We have some custom code that is bombing out on a sales order BPM. Erp.BO.SalesOrder.Update. I did not write the code but I get the gist of it, the code looks to ensure that parts come out of the correct plant. Looks to be having issues with OrderRel.
This works in 10.2.700 but not in 2023.1.16. Any help would be appreciated as I don’t know C# all that well.
Erp.Tables.OrderRel OrderRel;
foreach (var ttOrderDtl_xRow in ds.OrderDtl)
{
var ttOrderDtlRow = ttOrderDtl_xRow;
using (System.Transactions.TransactionScope txScope = IceDataContext.CreateDefaultTransactionScope())//start the transaction
{
foreach (var OrderRel_iterator in (from OrderRel_Row in Db.OrderRel
where OrderRel_Row.OrderNum == ttOrderDtl_xRow.OrderNum && string.Compare(OrderRel_Row.Company, ttOrderDtl_xRow.Company, true) == 0 && OrderRel_Row.OrderLine == ttOrderDtl_xRow.OrderLine
select OrderRel_Row))
{
OrderRel = OrderRel_iterator;
if ((string.Compare(OrderRel.WarehouseCode, "PPARTS", true) == 0 || string.Compare(OrderRel.WarehouseCode, "PRIPLEY", true) == 0))
{
OrderRel.Plant = "PARTS";
txScope.Complete();//commit the transaction
}
}
//txScope.Complete();//commit the transaction
}
}
Didn’t get a screenshot of the the error. Upgrade week, I’ve been all over the place. Trying to reproduce now.
Basically our parts sales guys enter a counter sale and then the bpm is supposed to set the site to PARTS if the warehouse matches. Looks like the release tab goes away when counter sale is checked, so that may be the reason for this code.
It says the syntax is ok but something seems off, the action in the method designer has turned red but it validates. The bpm condition was changed by my predecessor who was also troubleshooting it today and he forgot to change it back to original state. I will post error if my users let me know.
Don’t worry about the widget turning red, I’ve seen it before and it’s never given me trouble… I’ve always assumed some weird UI quirk of the designer.
Your code is compiling; this is a runtime error.
The code is trying to update the database through the entity framework, which is a BIG red flag. It is akin to a SQL update because whatever the code is trying to do is not passing through Epicor’s business logic application layer. So, while I have no idea what is specifically going wrong for you, it is safe to say that when you let code like this run in your environment, all bets are off.
The proper way to do this is through the Business Objects. You can find lots of examples on this site, I might even have one for OrderRel Plant update if I can find it…
Interesting. I have seen code like this all over method directives in the system. I think my predecessor got a piece of code like this from a consultant at one point and copied and pasted where he needed something like this.
It’s unfortunately very common. I was guilty of it myself for a while. When Epicor 10 first came out EpiUsers wasn’t what it is today and there wasn’t much good developer/community content out there. So bad stuff like this spread easily.
Just a couple of points here. That code with _x came from the ABL to C# converter and in the beginning that was what was done. As @TomAlexander points out Epicor has made better tools and we need to adapt and use BO as much as possible or at least UpdateExt.
As to the linq lambda difference this thread shows that both statements will be compiled into the same.
var OrderDs = new SalesOrderTableset();
var soSvc = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.SalesOrderSvcContract>(this.Db);
using (soSvc)
{
OrderDs = soSvc.GetByID(orderNum);
int orderLine = OrderDs.OrderDtl.Count - 1;
OrderDs.OrderRel[orderLine].WarehouseCode = "NJS";
OrderDs.OrderRel[orderLine].RowMod = "U";
soSvc.ChangeORelWarehouse(ref OrderDs);
int custNum = OrderDs.OrderHed[0].CustNum;
bool blnOut;
string strResponseMsg;
string strAgeMsg;
string strCreditShipAction;
string strDisplayMsg;
string strCompliantMsg;
string strResponseMsgOrdRel;
soSvc.MasterUpdate(true, true, "OrderRel", custNum, orderNum, false, out blnOut, out strResponseMsg, out strCreditShipAction, out strDisplayMsg, out strCompliantMsg, out strResponseMsgOrdRel, out strAgeMsg, ref OrderDs);
}
Edit: oops this is for changing warehouse instead of plant. Should still be useful though. This code uses the ChangeORelWarehouse helper method, there is probably a different one for Plant. If you run a trace you can find out.
Been meaning to revisit this topic with an update. I couldn’t get a BPM to work but as a workaround we ended up setting the sales site in Product Group Maintenance to use the desired site. This works with minor process modification.