Invoke the same BO Method within a Post-Processing BPM Directive on the BO Method

I have a post-processing directive on ERP.BO.Customer.Update that sets a field in the ds.Customer Table. I know the BPM is firing because a table query I place in a message at the end of the BPM displays the value I’m expecting in the ds.Customer field. However, it appears that this value is not actually saving to the ERP.Customer table. I haven’t found documentation confirming this yet, but this leads me to believe that setting fields in a post-processing directive doesn’t automatically save them to the database. To overcome this, I tried invoking the ERP.Customer.Update.BO within the directive (there are conditions within the directive to prevent it from getting stuck in an infinite loop). I know the parameters are correct as well because a table query on the response tableset displays the value I’m expecting for the field. However, it does not appear that the invoked method is running as the value does not save to the database. Is it possible to invoke the same BO method within a BPM tied to it? If not, how should I commit my the value in my field to the database?

Correct. Post-processing means the update already occurred. Why Post and not Pre where the update would indeed get saved?

What is the business problem you’re trying to solve?

See Data Flow of the System Admin Guide for a high level look at data flow in this case as well

1 Like

Because the field I’m changing is dependent on another field being saved to the database. My sales reps want a field on quotes and orders that lists “Installation Customer.” This is just a reference field and is different than an Alternate Ship To Customer or a Alternate Billing Customer. To make the application easier to use, I want to include a “Default Installation Customer” on the customer record. Because the primary key for customers is the auto-assigned customer number integer type field and the Customer ID is subject to change, the field I actually want to store in the database is the Default Installation Customer Number while I have a data view column for the Default Installation Customer ID, similar to how the quote application shows the customer ID but is actually storing customer number in the ERP.QuoteHed table. So when a user creates a new customer and enters a “Default Installation Customer ID,” I want the BPM to handle storing “Default Installation Customer Number.” The reason I can’t do this in a pre-processing directive is because most of the time, the default installation customer is the same as the actual customer on the record. If I were to try and set the “Default Installation Customer Number” in a pre-processing directive, I would run into an issue when I was adding a new customer to the system whose default installation customer was itself because prior to running the update process, the customer number is not assigned. So I was trying to do in a post-processing directive when when the customer number had already been assigned.

That description was very helpful. I have worked at a company where our product was installed by an integrator, so the installation customer was different than the sold-to and ship-to.

A possible option is moving the default setting to a Data Directive on Customer. If Default Installation is zero (unassigned) then use the CustID. I believe the number should be set by then but you may want to code around the possibility that it isn’t just in case.

Just thinking out loud. It is Friday, so safe harbor, don’t drink and drive, etc.


Thanks for the help. I will try placing in a data directive and let you know how it goes.

1 Like


I was struggling with the data directive but I think I may be able to do this entirely in a pre-processing directive if I can figure out where Epicor stores the next value for customer number. Do you know where Epicor stores the next values for IDs such as sales order number, purchase order number, etc.?

There is a method to grab the next one:

Erp.Internal.Lib.CompanySequence.GetNextCompanySeq(company, sequencename)

You can search the list for examples. However, if you call it to get the next and it’s not yet assigned, then Epicor will grab the next-next and they may not match.

There is an Ice table: Ice.SysSequence where they are actually stored. May have to watch out for race conditions between the time you call it and another process getting the next number.

What problem did you have with the Data Directive?

I could be missing something, but a standard directive doesn’t have a “Set field” setter. Plus, I think I would run into the same issue as the post-processing directive because the save to the DB would have already occurred. And if I try use an in-transaction directive, the customer number hasn’t been set yet on a new customer record, so if the default CPU customer ID matches the actual customer ID, the ID won’t set properly. To figure out why I couldn’t invoke the ERP.BO.Customer.Update service method, I tried creating a post-processing directive that triggered on ERP.BO.Quote.Update and called the ERP.BO.ShipVia.Update method to see if I could get a change to a field to save to the DB. The directive appears to work all the way through. I set the widget calling the update method to terminate on error and the display message I have at the end of the directive appears with the data that I would expect. And yet, when I query the field I tried to change in the other table, the new value does not appear.

Here is my thinking:

You have an In-Transaction Data Directive on Customer on an Update event. (pseudo code)

If CustNum <> 0 {  // The CustNum is set
  if DefInstallCust_c == 0 {   // Need to set the Default Installation Customer
    DefInstallCust_c = CustNum

That’s it. It relies on the fact that one cannot enter a customer without multiple saves, i.e. updates. After the first update, where you may not have the CustId yet, you will have the CustNum on every subsequent call. If it has not been set, it will default to CustNum. Once set though, it is never set again.


Thanks for the clarification! I think that will work.