Hi everyone, I’m working on a piece of code to update a custom field (“RSM_c”) in the OrderHed table when there’s an order entry, specifically when I input the customer ID. Here is the code snippet I’m using:
var ttOrderHedRow = (from ttOrderHed_Row in ttOrderHed
where ttOrderHed_Row.RowMod == "A" || ttOrderHed_Row.RowMod == "U"
select ttOrderHed_Row).FirstOrDefault();
if (ttOrderHedRow != null)
{
var originalOrderHed = Db.OrderHed.Where(o => o.OrderNum == ttOrderHedRow.OrderNum).FirstOrDefault();
if (originalOrderHed != null && originalOrderHed.CustNum != ttOrderHedRow.CustNum)
{
string vCustId = (from cust in Db.Customer
where cust.Company == Session.CompanyID && cust.CustNum == ttOrderHedRow.CustNum
select cust.Character08).FirstOrDefault();
if (!string.IsNullOrEmpty(vCustId))
{
ttOrderHedRow.SetUDField("RSM_c", vCustId);
}
}
}
The logic here is intended to check for an input of the customer ID and pull their information. It’s supposed to fetch a specific field (Character08) from the Customer table and update the custom field (“RSM_c”) in OrderHed. The label of the field in the User Defined tab is RSM.
When creating an order, you select the values from the dropdown, and in the User Defined fields in order entry, the values are also in a dropdown.
However, I’m running into an issue where the custom field (“RSM_c”) is not getting updated as expected. Could someone help me identify any potential issues with this code or suggest what might be going wrong?
Here are some screenshots of the BPM design
What type of BPM is it? Method or data directive? If method, which method is this and is it pre or post processing? If you are trying to pick up when the Cust ID is changed, the order isn’t saved yet. So you aren’t going to return anything in the originalOrderHed unless someone is changing the CustID of an existing saved order. I don’t think you need the custom code. I think you can do something like the below. I’m setting the value of a UD field on OrderHed to the value obtained from my customer record everytime the order changes customers… sounds like exactly what you want. Refer to below example.
(from c in Db.Customer
where c.Company == callContextClient.CurrentCompany
&& c.CustNum == dsOrderHedRow.CustNum
select c.Character08).FirstOrDefault()
It is a method directive, and the method code is salesorder->masterupdate. I created both pre-processing and post-processing directives, enabling one at a time. Below is a screenshot of it. I am supposed to populate the field with the information such that the value set during customer creation is not changed during new order entry. The issue I am trying to solve is ensuring that the value reflects that the customer already has a set value, preventing anyone from selecting new values and setting a different one.
Hmm. It sounds like you’re close to what you’re after.
A couple things about what you’ve got going on in your BPM that you showed above. Your condition widget is looking for rows where RSM_c is null. That should not be null on an order record… I would expect it to be an empty string or “”. Maybe try that. Also, you’re executing custom code asynchronously. I think this needs to be synchronously if you want the change picked up by that MasterUpdate method… but I could be wrong. I only use asynchronously for things like firing emails or updating other tables not in the current data set.
As a plan B, you might try the ChangeCustomer method but instead of always setting the field, put a condition widget in that checks for a value already there and then only set it if it’s empty.
Here is the flow with images to guide you. I create a customer and select the RSM field value from the dropdown, which is bound to the database as Customer.Character08.
In our case, we chose Pam Williams. During order entry, we create a new order, and below that, we have a place to input the customer ID to associate the order with
On pressing tab, the customer information is pulled. However, the RSM field is bound as OrderHed.RSM_c. I am supposed to pull the value from Customer.Character08 and populate it there.
I follow you exactly. When you select the customer from search or enter the ID and tab out of the field, you are firing the Customer.ChangeCustomer method. That’s why I suggested you set the RSM_c field on that method. Then you don’t have to wait for the user to hit Save to fire the Master Update method.
Post Processing on Customer.ChangeCustomer. Add a condition widget that checks if the RSM_c value is empty. If it is empty, set the value of RSM_c like I showed you above using the Set Field widget. If it’s not empty, do nothing. I think that’s how I understood you wanted the logic to work.
If you run a trace on the application, you will probably find that when you CHANGE or ENTER a new Customer, that a different Method is triggered (SalesOrder.ChangeCUstomer or something like that). If that is the case, this might be a better place to hang your BPM, because it would trigger as soon as you enter the customer rather than waiting till you save. You would need to do it “POST PROCESSING” because you want it to trigger after the customer has been retrieved.
Here is another trick, During customer creation, I will pick from these values:
NONE
Alex - 900 M
Alex - 900 N
Value - 901 M
Value - 901 N
Bob - 902 M
Bob - 902 N
Sam - 903 M
Sam - 903 N
Dan - 904 M
Dan - 904 N
However, during order entry, the values I am supposed to compare with are:
Alex
Value
Bob
Sam
Dan
Notice how “Alex - 900 M” and “Alex - 900 N” are simplified to “Alex,” meaning the code extension is not considered.
I do this post processing on Salesorder.ChangeSoldToID which fires on new and changes to customer.
If you put the code here you don’t need a condition since it is on change and if you are post processing the customer is valid.
I took my routine and adapted to what should be close to what you need. You don’t have a version listed, but given that you have tt and not ds I am assuming 10ish. I do not remember when the transaction scope got added, but it was probably not until 11, so you may not need it.
/* Copy cust profile to sales order */
var ttOrderHedRow = ttOrderHed.FirstOrDefault();
{
using (System.Transactions.TransactionScope txScope = IceDataContext.CreateDefaultTransactionScope())//start the transaction
{
var repCode = Db.Customer.Where(Customer_Row => ttOrderHedRow.CustNum == Customer_Row.CustNum && ttOrderHedRow.Company == Customer_Row.Company).Select(s=> s.Character10).FirstOrDefault();
{
var repCodeShort = repCode.Split('-')[0];
ttOrderHedRow.SetUDField<System.String>("RSM_c", repCodeShort);
}
txScope.Complete();//commit the transaction
}
}
Hey @dr_dan , @timshuwy
This solution works at the moment only when I save the order. Here’s why I guess it is not populating when I enter the customer ID to pull their information: there’s a difference between the names in the order entry RSM dropdown and the ones in the dropdown during customer creation. During customer creation, we have an extension of a code (- code) like the ones below:
NONE
Alex - 900 M
Alex - 900 N
Value - 901 M
Value - 901 N
Bob - 902 M
Bob - 902 N
Sam - 903 M
Sam - 903 N
Dan - 904 M
Dan - 904 N
However, during order entry, the values I am supposed to compare with are simplified to:
Alex
Value
Bob
Sam
Dan
Notice how “Alex - 900 M” and “Alex - 900 N” are simplified to “Alex,” meaning the code extension is not considered.So, am I supposed to execute a custom code to compare them and map those that match for the first two words, or which is the best approach?
I’ll be honest. I don’t understand the use case. To me, the first set of dropdowns is one thing and the second set of dropdowns is another thing. If they are supposed to be related, I guess I’d need to know that relationship to better be able to help. Why do they have to be simplified in Order Entry?
The dropdown during customer creation contains values for the RSM (Regional Sales Manager), which is linked to the customer and stored in the database as Customer.Character08. During order entry, the Character08 value is supposed to be mapped from the dropdown values.
For example, the dropdown values like:
Alex - 900 M
Alex - 900 N
are both considered as Alex without the code extension. This is to prevent the user from choosing an RSM value again, as it’s already stored in the database.
When we save the order, the truncated RSM value is saved in the database as OrderHed.RSM_c.
I still don’t follow.
Character08: is that referring to a user code that you’ve defined?
How is that drop-down populated to the user?
How/when does Character08 get filled in?
Is that on Customer Maintenance or does it happen from some other place?
What does that dropdown get populated with? is it a User Code that you’ve setup? Or is the list hard coded? Or is it pulling it from some other place…
What I’m ultimately driving toward is that you need some kind of way to link the full length RSM to a truncated version. The confusing part is it appears you want a many to one relationship, which is backwards of how things usually are. So that’s why I am struggling a bit to keep up.
The database field Customer.Character08 is an E9 (or earlier) User Defined field. Prior to the ability to create our OWN UD fields, most database tables had chunks of pre-existing fields that we could use for our own nefarious purposes.
Data in those fields was migrated automatically during upgrades, so anyone who had them still does. Empty fields were removed from the database during the upgrade process.