Monday, November 17, 2025

BUSINESS EVENTS

  

DEVELOPING  Custom BUSINESS EVENTS 

Scenario – In this example, I am going to show you how we can develop a new custom business event from scratch. In my scenario, business event in D365 FO should be triggered when a user confirmed purchased order in Microsoft dynamics 365 for finance and operations. 

There a 2 standard and base classes which i will use to develop custom business events – 

  1. BusinessEventsContract ( Use for developing/defining payload message) 

  2. BusinessEventsBase ( Use for triggering custom business event) 

  

  

  1. Create contract class (Class1PAAPurchInvoiceJournalPostBusinessEventContract) 

[DataContract 

class Class1PAAPurchInvoiceJournalPostBusinessEventContract extends BusinessEventsContract 

{ 

  // private InvoiceAcc vendAccount; 

   private PurchId purchId; 

   private InvoiceId invoiceId; 

  

   public static Class1PAAPurchInvoiceJournalPostBusinessEventContract newFromPurchTable(PurchTable _PurchTable) 

   { 

       var contract = new Class1PAAPurchInvoiceJournalPostBusinessEventContract(); 

       contract.initialize(_PurchTable); 

       return contract; 

   } 

  

   private void initialize(PurchTable _PurchTable) 

   { 

       //vendAccount = _PurchParmTable.OrderAccount; 

       purchId   = _PurchTable.PurchId; 

       invoiceId = _PurchTable.InvoiceAccount; 

   } 

  

   private void new() 

   { 

   } 

  

   //[DataMember('VendAccount') ,BusinessEventsDataMember ('VendAccount')] 

   //public VendAccount parmVendAccount(VendAccount _vendAccount = vendAccount) 

   //{ 

   //    vendAccount = _vendAccount; 

   //    return vendAccount; 

   //} 

  

   [DataMember('PurchId') , BusinessEventsDataMember('PurchId')] 

   public PurchId parmPurchId(PurchId _PurchId = purchId) 

   { 

       purchId = _PurchId; 

       return purchId; 

   } 

  

   [DataMember('InvoiceId') , BusinessEventsDataMember('InvoiceId')] 

   public InvoiceId parmInvoiceId(InvoiceId _InvoiceId = invoiceId) 

   { 

       invoiceId = _InvoiceId; 

       return invoiceId; 

   } 

  

} 

  

  

  1. Create Base Class (PAAPurchInvoiceJournalPostBusinessEvent) 

[BusinessEvents(classStr(Class1PAAPurchInvoiceJournalPostBusinessEventContract) , 

"Custom Vendor Invoice Post Business Event" ,  

   "this business event is triggering during the time purchase invoice posting" , 

   ModuleAxapta::PurchaseOrder)] 

public final class PAAPurchInvoiceJournalPostBusinessEvent extends BusinessEventsBase 

{ 

  // private PurchFormLetter_Confirmation purchFormLetter_Confirmation; 

   private PurchTable purchTable; 

   public static PAAPurchInvoiceJournalPostBusinessEvent newFrompurchFormLetter_Confirmaton(PurchTable purchTable) 

   { 

       PAAPurchInvoiceJournalPostBusinessEvent businessEvent = new PAAPurchInvoiceJournalPostBusinessEvent(); 

  

       businessEvent.parmPurchTable(PurchTable); 

       return businessEvent; 

   } 

  

   private PurchTable parmPurchTable(PurchTable _PurchTable = PurchTable) 

   { 

       PurchTable = _PurchTable; 

       return PurchTable; 

   } 

  

   private void new() 

   { 

   } 

  

   [Wrappable(true), Replaceable(true)] 

   public BusinessEventsContract buildContract() 

   { 

       return Class1PAAPurchInvoiceJournalPostBusinessEventContract::newFromPurchTable(purchTable); 

   } 

  

} 

  1. you must add below block of code in purchase order confirming class. Also business must be activated or enabled in that company. Business event will trigger when purchase order confirming will take place. 

  

[ExtensionOf(classStr(PurchFormLetter))] 

final class PurchFormLetter_Extension 

{ 

   

   protected static PurchFormLetter constructAndInitialize(container _cachedArgs, 

                                                  Common    _record, 

                                                  Object    _callerForm, 

                                                  container _dataSourceRecordsPacked) 

   { 

       PurchTable purchTable ; 

       PurchFormLetter purchFormLetter; 

       next constructAndInitialize( _cachedArgs, _record , _callerForm  , _dataSourceRecordsPacked); 

       purchTable  = _record; 

       PAAPurchInvoiceJournalPostBusinessEvent::newFrompurchFormLetter_Confirmaton(purchtable).send(); 

       PurchFormLetter::MailToVendor(purchTable); 

       return PurchFormLetter; 

   } 

  

   public static void MailToVendor(Purchtable purchtableloc) 

  // public void method() 

   { 

       #define.SalesIdToken('salesid') 

       #define.CustNameToken('customername') 

       #define.DeliveryAddress('deliveryaddress') 

       #define.CustomerAddress('customeraddress') 

       #define.ShipDate('shipdate') 

       #define.ModeOfDelivery('modeofdelivery') 

       #define.Charges('charges') 

       #define.Discount('discount') 

       #define.Tax('tax') 

       #define.Total('total') 

       #define.LineProductName('lineproductname') 

       #define.LineProductDesc('lineproductdescription') 

       #define.LinePrice('lineprice') 

       #define.LineQuantity('linequantity') 

       #define.LineNetAmount('linenetamount') 

       //SalesTable salesTable; 

  

       //SalesLine salesLine; 

       //CustTable custTable; 

       //ContactPerson contactPerson; 

       //SalesTotals salesTotals; 

      // PurchTable purchTable; 

       PurchLine purchLine; 

       VendTable vendTable; 

       ContactPerson contactPerson; 

       PurchTotals purchTotals; 

       str emailId; 

       Map templateTokens; 

       str emailSenderName; 

       str emailSenderAddr; 

       str emailSubject; 

       str emailBody; 

       str emailToAddress; 

       PurchTable purchTable ; 

       //next main(args); 

      // FormDataObject fdo = any2Object(this ); 

      // FormDataSource fds = fdo.datasource(); 

       PurchTable = purchtableloc; 

       //purchTable = PurchTable::find('000028'); 

       //PurchTable purchTable = PurchTable_ds.cursor(); 

       purchLine = PurchLine::find(purchTable.PurchId); 

       vendTable = VendTable::find(vendTable.AccountNum); 

       //contactPerson = ContactPerson::find(salesTable.SixCustContactPersonId); 

  

       purchTotals = PurchTotals::newPurchTable(purchTable); 

       emailToAddress = 'priyanka.ratakonda97@outlook.com'; 

       emailId = 'priyanka.ratakonda97@outlook.com'; 

       templateTokens = new Map(Types::String, Types::String); 

       templateTokens.insert(#SalesIdToken, purchTable.PurchId); 

       templateTokens.insert(#CustNameToken, vendTable.name()); 

       templateTokens.insert(#DeliveryAddress, purchTable.deliveryAddress().Address); 

       templateTokens.insert(#CustomerAddress, vendTable.InventLocation); 

       templateTokens.insert(#ShipDate, strFmt("%1", purchTable.ShippingDateRequested)); 

       templateTokens.insert(#ModeOfDelivery, strFmt("%1", purchTable.DlvMode)); 

       templateTokens.insert(#Charges, strFmt("", '10.00')); 

       templateTokens.insert(#Discount, strFmt("", '10.00')); 

       templateTokens.insert(#Tax, strFmt("", '10.00')); 

       templateTokens.insert(#Total, strFmt("", '10.00')); 

       templateTokens.insert(#LineProductName, purchLine.itemName()); 

       templateTokens.insert(#LineProductDesc, purchLine.itemLineDisc()); 

       templateTokens.insert(#LinePrice, strFmt("%1", purchLine.PurchPrice)); 

  

       templateTokens.insert(#LineQuantity, strFmt("%1", purchLine.PurchQty)); 

  

       templateTokens.insert(#LineNetAmount, strFmt("%1", purchLine.LineAmount)); 

       if (emailId) 

       { 

           [emailSubjectemailBodyemailSenderAddremailSenderName] = PurchFormLetter::getEmailTemplate('cnfmOrder', 'en-us'); 

       } 

       var messageBuilder = new SysMailerMessageBuilder(); 

       messageBuilder.addTo(emailToAddress)    .setSubject(emailSubject)    .setBody(SysEmailMessage::stringExpand(      emailBodySysEmailTable::htmlEncodeParameters(templateTokens))); 

  

       if (emailSenderAddr) 

       { 

           messageBuilder.setFrom(emailSenderAddremailSenderName); 

           SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage()); 

       } 

   } 

  

   protected static container getEmailTemplate(str _emailIdLanguageId languageId) 

   { 

  

  

       var messageTable = SysEmailMessageTable::find(_emailIdlanguageId); 

       var emailTable = SysEmailTable::find(_emailId); 

       if (!messageTable && emailTable) 

       { 

           // Try to find the email message using the default language from the email parameters 

           messageTable = SysEmailMessageTable::find(_emailIdemailTable.DefaultLanguage); 

       } 

       if (messageTable) 

       { 

           return [messageTable.SubjectmessageTable.MailemailTable.SenderAddremailTable.SenderName]; 

       } 

       else 

       { 

           warning("@SYS135886"); // Let the user know we didn't find a template 

  

           return ['', '', emailTable.SenderAddremailTable.SenderName]; 

       } 

   } 

  

  1.  Activate The Custom Business Event 

Go to System administration > Setup > Business events > Business events catalog 

On the form, click on Manage > Rebuild business event catalog. This will cause the system to see your newly created custom business event and add it to the grid shown on this form. 

               

  

SetUp Path : 

Step 1: SMTP Settings in sysadmin 
 
SMTP (Go to System Admin --> Setup  -->  Email --> Email Paramenters  -->Email providers and 
  SMTP Settings) 

  

Step2: 

  

Go to System Administartor - > Email Tempaltes - >  System Email Templates  

Here we can create Email Template  

                               

  

  

Create Purchase order : 00000126 

 I will confirm this order  , Automatically mail send to vendor 

DEVELOPING  Custom BUSINESS EVENTS 

Scenario – In this example, I am going to show you how we can develop a new custom business event from scratch. In my scenario, business event in D365 FO should be triggered when a user confirmed purchased order in Microsoft dynamics 365 for finance and operations. 

There a 2 standard and base classes which i will use to develop custom business events – 

  1. BusinessEventsContract ( Use for developing/defining payload message) 

  2. BusinessEventsBase ( Use for triggering custom business event) 

  

  

  1. Create contract class (Class1PAAPurchInvoiceJournalPostBusinessEventContract) 

[DataContract 

class Class1PAAPurchInvoiceJournalPostBusinessEventContract extends BusinessEventsContract 

{ 

  // private InvoiceAcc vendAccount; 

   private PurchId purchId; 

   private InvoiceId invoiceId; 

  

   public static Class1PAAPurchInvoiceJournalPostBusinessEventContract newFromPurchTable(PurchTable _PurchTable) 

   { 

       var contract = new Class1PAAPurchInvoiceJournalPostBusinessEventContract(); 

       contract.initialize(_PurchTable); 

       return contract; 

   } 

  

   private void initialize(PurchTable _PurchTable) 

   { 

       //vendAccount = _PurchParmTable.OrderAccount; 

       purchId   = _PurchTable.PurchId; 

       invoiceId = _PurchTable.InvoiceAccount; 

   } 

  

   private void new() 

   { 

   } 

  

   //[DataMember('VendAccount') ,BusinessEventsDataMember ('VendAccount')] 

   //public VendAccount parmVendAccount(VendAccount _vendAccount = vendAccount) 

   //{ 

   //    vendAccount = _vendAccount; 

   //    return vendAccount; 

   //} 

  

   [DataMember('PurchId') , BusinessEventsDataMember('PurchId')] 

   public PurchId parmPurchId(PurchId _PurchId = purchId) 

   { 

       purchId = _PurchId; 

       return purchId; 

   } 

  

   [DataMember('InvoiceId') , BusinessEventsDataMember('InvoiceId')] 

   public InvoiceId parmInvoiceId(InvoiceId _InvoiceId = invoiceId) 

   { 

       invoiceId = _InvoiceId; 

       return invoiceId; 

   } 

  

} 

  

  

  1. Create Base Class (PAAPurchInvoiceJournalPostBusinessEvent) 

[BusinessEvents(classStr(Class1PAAPurchInvoiceJournalPostBusinessEventContract) , 

"Custom Vendor Invoice Post Business Event" ,  

   "this business event is triggering during the time purchase invoice posting" , 

   ModuleAxapta::PurchaseOrder)] 

public final class PAAPurchInvoiceJournalPostBusinessEvent extends BusinessEventsBase 

{ 

  // private PurchFormLetter_Confirmation purchFormLetter_Confirmation; 

   private PurchTable purchTable; 

   public static PAAPurchInvoiceJournalPostBusinessEvent newFrompurchFormLetter_Confirmaton(PurchTable purchTable) 

   { 

       PAAPurchInvoiceJournalPostBusinessEvent businessEvent = new PAAPurchInvoiceJournalPostBusinessEvent(); 

  

       businessEvent.parmPurchTable(PurchTable); 

       return businessEvent; 

   } 

  

   private PurchTable parmPurchTable(PurchTable _PurchTable = PurchTable) 

   { 

       PurchTable = _PurchTable; 

       return PurchTable; 

   } 

  

   private void new() 

   { 

   } 

  

   [Wrappable(true), Replaceable(true)] 

   public BusinessEventsContract buildContract() 

   { 

       return Class1PAAPurchInvoiceJournalPostBusinessEventContract::newFromPurchTable(purchTable); 

   } 

  

} 

  1. you must add below block of code in purchase order confirming class. Also business must be activated or enabled in that company. Business event will trigger when purchase order confirming will take place. 

  

[ExtensionOf(classStr(PurchFormLetter))] 

final class PurchFormLetter_Extension 

{ 

   

   protected static PurchFormLetter constructAndInitialize(container _cachedArgs, 

                                                  Common    _record, 

                                                  Object    _callerForm, 

                                                  container _dataSourceRecordsPacked) 

   { 

       PurchTable purchTable ; 

       PurchFormLetter purchFormLetter; 

       next constructAndInitialize( _cachedArgs, _record , _callerForm  , _dataSourceRecordsPacked); 

       purchTable  = _record; 

       PAAPurchInvoiceJournalPostBusinessEvent::newFrompurchFormLetter_Confirmaton(purchtable).send(); 

       PurchFormLetter::MailToVendor(purchTable); 

       return PurchFormLetter; 

   } 

  

   public static void MailToVendor(Purchtable purchtableloc) 

  // public void method() 

   { 

       #define.SalesIdToken('salesid') 

       #define.CustNameToken('customername') 

       #define.DeliveryAddress('deliveryaddress') 

       #define.CustomerAddress('customeraddress') 

       #define.ShipDate('shipdate') 

       #define.ModeOfDelivery('modeofdelivery') 

       #define.Charges('charges') 

       #define.Discount('discount') 

       #define.Tax('tax') 

       #define.Total('total') 

       #define.LineProductName('lineproductname') 

       #define.LineProductDesc('lineproductdescription') 

       #define.LinePrice('lineprice') 

       #define.LineQuantity('linequantity') 

       #define.LineNetAmount('linenetamount') 

       //SalesTable salesTable; 

  

       //SalesLine salesLine; 

       //CustTable custTable; 

       //ContactPerson contactPerson; 

       //SalesTotals salesTotals; 

      // PurchTable purchTable; 

       PurchLine purchLine; 

       VendTable vendTable; 

       ContactPerson contactPerson; 

       PurchTotals purchTotals; 

       str emailId; 

       Map templateTokens; 

       str emailSenderName; 

       str emailSenderAddr; 

       str emailSubject; 

       str emailBody; 

       str emailToAddress; 

       PurchTable purchTable ; 

       //next main(args); 

      // FormDataObject fdo = any2Object(this ); 

      // FormDataSource fds = fdo.datasource(); 

       PurchTable = purchtableloc; 

       //purchTable = PurchTable::find('000028'); 

       //PurchTable purchTable = PurchTable_ds.cursor(); 

       purchLine = PurchLine::find(purchTable.PurchId); 

       vendTable = VendTable::find(vendTable.AccountNum); 

       //contactPerson = ContactPerson::find(salesTable.SixCustContactPersonId); 

  

       purchTotals = PurchTotals::newPurchTable(purchTable); 

       emailToAddress = 'priyanka.ratakonda97@outlook.com'; 

       emailId = 'priyanka.ratakonda97@outlook.com'; 

       templateTokens = new Map(Types::String, Types::String); 

       templateTokens.insert(#SalesIdToken, purchTable.PurchId); 

       templateTokens.insert(#CustNameToken, vendTable.name()); 

       templateTokens.insert(#DeliveryAddress, purchTable.deliveryAddress().Address); 

       templateTokens.insert(#CustomerAddress, vendTable.InventLocation); 

       templateTokens.insert(#ShipDate, strFmt("%1", purchTable.ShippingDateRequested)); 

       templateTokens.insert(#ModeOfDelivery, strFmt("%1", purchTable.DlvMode)); 

       templateTokens.insert(#Charges, strFmt("", '10.00')); 

       templateTokens.insert(#Discount, strFmt("", '10.00')); 

       templateTokens.insert(#Tax, strFmt("", '10.00')); 

       templateTokens.insert(#Total, strFmt("", '10.00')); 

       templateTokens.insert(#LineProductName, purchLine.itemName()); 

       templateTokens.insert(#LineProductDesc, purchLine.itemLineDisc()); 

       templateTokens.insert(#LinePrice, strFmt("%1", purchLine.PurchPrice)); 

  

       templateTokens.insert(#LineQuantity, strFmt("%1", purchLine.PurchQty)); 

  

       templateTokens.insert(#LineNetAmount, strFmt("%1", purchLine.LineAmount)); 

       if (emailId) 

       { 

           [emailSubject, emailBody, emailSenderAddr, emailSenderName] = PurchFormLetter::getEmailTemplate('cnfmOrder', 'en-us'); 

       } 

       var messageBuilder = new SysMailerMessageBuilder(); 

       messageBuilder.addTo(emailToAddress)    .setSubject(emailSubject)    .setBody(SysEmailMessage::stringExpand(      emailBody, SysEmailTable::htmlEncodeParameters(templateTokens))); 

  

       if (emailSenderAddr) 

       { 

           messageBuilder.setFrom(emailSenderAddr, emailSenderName); 

           SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(messageBuilder.getMessage()); 

       } 

   } 

  

   protected static container getEmailTemplate(str _emailId, LanguageId languageId) 

   { 

  

  

       var messageTable = SysEmailMessageTable::find(_emailId, languageId); 

       var emailTable = SysEmailTable::find(_emailId); 

       if (!messageTable && emailTable) 

       { 

           // Try to find the email message using the default language from the email parameters 

           messageTable = SysEmailMessageTable::find(_emailId, emailTable.DefaultLanguage); 

       } 

       if (messageTable) 

       { 

           return [messageTable.Subject, messageTable.Mail, emailTable.SenderAddr, emailTable.SenderName]; 

       } 

       else 

       { 

           warning("@SYS135886"); // Let the user know we didn't find a template 

  

           return ['', '', emailTable.SenderAddr, emailTable.SenderName]; 

       } 

   } 

  

  1.  Activate The Custom Business Event 

Go to System administration > Setup > Business events > Business events catalog 

On the form, click on Manage > Rebuild business event catalog. This will cause the system to see your newly created custom business event and add it to the grid shown on this form. 

               

  

SetUp Path : 

Step 1: SMTP Settings in sysadmin 
 
SMTP (Go to System Admin --> Setup  -->  Email --> Email Paramenters  -->Email providers and 
  SMTP Settings) 

  

Step2: 

  

Go to System Administartor - > Email Tempaltes - >  System Email Templates  

Here we can create Email Template  

                               

  

  

Create Purchase order : 00000126 

 I will confirm this order  , Automatically mail send to vendor 

 

No comments:

Post a Comment