BPM Sales Order Entry

I’m trying to create a BPM using the SalesOrder.Update method that upon saving will check the customer ship to address to see if it’s domestic or international, and then change the Group field (OrderDtl.ProdCode) for all items to match. We have product groups that are different for domestic (i.e., “Install”) and international (i.e., “Install INTL”), so these entries need to align with the ship to address.

The reason for this is if someone enters in a new sales order, then adds a bunch of line items, and then changes the ship to address from domestic to international, or vice-versa, the BPM will check each line item and change them accordingly.

I’ve got the BPM to where it checks the ship to address in ttOrderHed.ShipToAddressList and assigns the OrderNum to a variable. Can’t figure out how to check each line item and update the ProdCode field. I tried using the “Set by Query” feature but can’t get it to work. Does this sound like an impossible task? Any help is appreciated. Thank you for your time!

Shawn,

You’ve really got two issues here.

First, what I would suspect would occur most times, is the Sales Order Header gets set (so the ship-to address is set) prior to any lines being added. In this case, I’d probably put a BPM not on the update, but rather on the POST-PROCESSING when the part number is changed (ChangePartNumMaster) - which is the point where it’s setting the product code on the line - and have it change the product code then. So, as the user adds lines, it is setting the correct product group as they go. This has the added benefit of allowing the system to DEFAULT to a product code - and the user would still be able to change it after the fact if there are exceptions to your rules.

Second, it could be possible that the user gets all the lines added, and after the lines are added, they change the ship-to address to/from domestic/international. This is a different issue, I would likely put together some advanced BPM code (C# for E10) that goes through the order and changes each line. Of course, there’s the added issue that the “ship-to” is on the order, line and release - so you may have to take into consideration if your company ships orders to multiple ship-to addresses. It is possible one line would be domestic, another line international.

Not sure if you can do the first BPM with all canned actions, but the second will definitely need custom code.

Let me know if you have any further questions.

Kevin Simon
SimsTrak Consulting, LLC

1 Like

Hey Kevin,

Thank you for the response. I’ve only been working with Epicor for a month or so and have gone through a lot of the embedded and online courses, but even that material doesn’t cover everything. I’ve been working on this off and on for the past few days. The first part of your reply is not an issue, but the second part has me stumped. For my company, we will never ship to multiple locations that would mix domestic and international. That being said, I’ve setup a BPM on the SalesOrder Update method, under Pre-processing where I have a condition that checks if the OrderHed ShipToAddressList field contains “US”. If it does then the OrderNum is set to a variable, and the flow passes to a Custom Code action (see code below). In this action it should go through each record with the OrderNum saved in the variable then change the ProdCode field, which in this case is just TESTING until I can get it to work.

foreach (var ttOrderDtl_iterator in (from ttOrderDtl_Row in ttOrderDtl
where ttOrderDtl_Row.OrderNum == this.orderNum
select ttOrderDtl_Row))
{
var ttOrderDtl_xRow = ttOrderDtl_iterator;
ttOrderDtl_xRow[“ProdCode”] = “TESTING”;
}

I even put a Show Message action to say the process was complete. I get the message, but when I refresh the order and check the ProdCode field, nothing has changed. At a loss at this point. Thank you for your time and any help you can provide!

Did you try putting the message in the foreach loop? The order details you are looking for might not be in the dataset

1 Like

Epicor doesn’t like the MessageBox.Show. I tried using System.Windows.Forms, but it didn’t like that either. I will search for other ways to display messages. Thanks!

Instructions for bpm c# message boxes

http://erp.ittoolbox.com/groups/technical-functional/epicor-l/epicor-10-bpm-messagebox-or-alternative-for-debugging-5820800

1 Like

Use a BPM In-Transaction Data Directive on the OrderHed table Condition on the value of the OrderHed.IntrntlShip field (True or False) and execute the following Custom Code:

/* ProdCode */
Erp.Tables.OrderDtl OrderDtl;
foreach (var ttOrderHedRow in ttOrderHed)
{
    foreach (var OrderDtl_iterator in (from OrderDtl_Row in Db.OrderDtl
                                       where OrderDtl_Row.Company == ttOrderHedRow.Company && OrderDtl_Row.OrderNum == ttOrderHedRow.OrderNum
                                       select OrderDtl_Row))
    {
        OrderDtl = OrderDtl_iterator;
        OrderDtl.ProdCode = "TESTING";
	}
}

2 Likes

Thank you Brian! I had to tweak the code some to get the results we were looking for, but this helped me get where I needed to be. Thanks to all of you who replied trying to help. I hope someday I’ll have enough knowledge that I’ll be able to help people too.

I was wondering - when using the Epicor ABL -> C# converter, it uses the string compare function on testing character fields, versus the ==. So, where you listed:
where OrderDtl_Row.Company == ttOrderHedRow.Company
the converter tool would generate:
where string.Compare(OrderDtl_Row.Company, ttOrderHedRow.Company, true) == 0

I know both of these work. Does anyone know if one is inherently better than the other? I guess I’m primarily looking at response - if they’re the same I’d use the “==” as it’s cleaner.

Thanks.
Kevin

1 Like

Hey everyone! I thought I had this solved, but in working through scenarios we found we needed something a little different. I had the BPM set to look for “US” in the ttOrderHed.ShipToAdressList of the updated row on the SalesOrder.Update method, but then we found that if someone added another line item and saved it didn’t check the list.

Basically what I’m needing is this: A user creates a new sales order, places line items on it and saves the record. On the SalesOrder.Update method I need to lookup the ship-to country and then check the product group of each line item to be sure it’s entered correctly (i.e., “Install” for domestic, “Install INTL” for international), and change it accordingly if it’s not. I’ve got the code that looks at each line item and changes the product group as needed (see code below), but I can’t figure out how to lookup the ship-to country.

Erp.Tables.OrderDtl OrderDtl;
foreach (var ttOrderHedRow in ttOrderHed)
{
foreach (var OrderDtl_iterator in (from OrderDtl_Row in Db.OrderDtl
where OrderDtl_Row.Company == ttOrderHedRow.Company
&& OrderDtl_Row.OrderNum == ttOrderHedRow.OrderNum
select OrderDtl_Row))
{
OrderDtl = OrderDtl_iterator;

  		if (OrderDtl.ProdCode.EndsWith("IN"))
    {
        OrderDtl.ProdCode = OrderDtl.ProdCode.Remove(OrderDtl.ProdCode.Length - 2, 2);
    }
}

}

1 Like

Thanks Brian! I think I was over thinking it and trying to come up with custom code to get the ship-to country. Unfortunately, this only returns the default country in the customer table, and not the ship-to country of the sales order. I also did try the same process with the ShipTo table, but didn’t get the desired results either.

I finally got it, I think! I ended up using a Condition that checked the ShipToAdressList custom field of “all rows”, and then moved to the custom code. Everything seems to be working. Thank you all for your time & help!

I see an issue if an international customer contains “US” anywhere in their name, city, state or address.

1 Like

Consider the following:

Check if the OrderHed.ShipToNum = “”

if true check if the Customer.Country = “US”

if false check if the ShipTo.Country = “US”

Run custom code to change ProdCode based on either International or Domestic shipping

1 Like

I set it up as you showed, with simple messages to say YES if it’s USA and NO if it’s not…

When I change the ship-to address to Germany and save the record, it still gives me the message of YES…

Thanks for the suggestion though!

Based on the logic I presented, count(ShipTo.Country = “USA”) < 1 would be true and result in Yes as you have shown. Unless you used Count(ShipTo.Country = “USA”) !< 1 in the query statement

I have it setup as you showed, with the Count(ShipTo.Country = “USA”) < 1. When I change the ship to address between domestic and international and save it gives me the correct response. Perfect!

But, when I change something on a line item, say the product group, and then save it fails…

Are you setting up multiple BPMs, one checking for change in the ShipTo and one looking for change in the OrderDtl? If so, verify the logic for determining the country is consistent.