Calling Business Object Methods From Within An Epicor 10 BPM Using Custom Code

Typically you think of a BPM as being reactive to Business Object methods, since that is what we connect them to (at least in the case of Method Directives). But did you know you can trigger Business Object methods from within an Epicor 10 BPM with some custom code as well? Let us show you how!

To start with, you are going to need to go to ‘Using & References’ within the BPM designer and enter the following text within the ‘Usings’ section:

Screenshot of the Epicor 10 ERP BPM Workflow Designer where GingerHelp shows you how to call an Epicor 10 BPM using custom code

While still having that ‘Using & References’ dialog open, head over to the ‘References’ tab and select the business object(s) you wish to call - I am going to use part for the example here:

Screenshot of the Epicor ERP Directive Usings and References screen in a tutorial by Epicor ERP consultant, GingerHelp

Alright, now we are ready to write some code! Drag an ‘Execute Custom Code’ widget onto the canvas and enter some code similar to the following:

var part = ServiceRenderer.GetService<Erp.Contracts.PartSvcContract>(Db);
Erp.Tablesets.PartTableset partTs = new Erp.Tablesets.PartTableset();
part.GetNewPart(ref partTs);
partTs.Part[0].PartNum = "GH1234";
partTs.Part[0].PartDescription = "GH1234";
partTs.Part[0].UOMClassID = "LBSPERFOOT";
partTs.Part[0].IUM = "LF";
partTs.Part[0].PUM = "LB";
partTs.Part[0].SalesUM = "LF";
part.Update(ref partTs);

So breaking this down line by line here, the first line we are getting a reference to the Business Object. The format you see here is going to be common for all of your business objects so just swap out “Erp” and “Part” according to the business object you are calling.

Next we need to define a reference to a tableset if we intend to create or update any records. As with the service reference line, there is a consistent format across all of the business objects here so just swap out “Erp” and “Part” as appropriate.

From there I am actually calling a business object method the same as you might see within trace logs. Here I am calling GetNewPart (which gives me a new blank row in the tableset with several columns defaulted) and from there I populate the various columns I wish to specify. Lastly I call Update to save the new part record.

As with anywhere you may call the business objects, they will do all of the same validations as the standard user interface here. They will also trigger any BPMs tied to them so be careful to not create circular references here.

This makes for a very useful technique - I recently used it to automatically add service charges to sales order lines that met specific criteria and it allowed the end users to instantly see changes without doing any sort of refresh. I did that one as a pre-processing on SalesOrder.MasterUpdate with these lines doing the work (there were a lot more lines than this, but keeping it brief here). Note on this example I am still working with a tableset, but I am grabbing the one from the current transaction:

var so = ServiceRenderer.GetService<SalesOrderSvcContract>(Db);
var ts = (Erp.Tablesets.SalesOrderTableset)ds;
so.GetNewOrderMsc(ref ts, orderNum, orderLine);
ttOrderMsc.Last().MiscCode = "MYCODE";
so.ChangeMiscCode(ref ts, "OrderMsc");

Hope this is helpful!