CustShip BO Changing PackNum on Update

This is really strange and I’m hoping someone can help. I’m using the CustShip BO through an external DLL that is called by an updatable dashboard to create shipments from imported UD records. This BO has been a pain because it seems it doesn’t act like other BO’s in that multiple tables are updated in one method call and following the traced methods doesn’t give you all you need to get it to work. Having said that, I got it to work, sort of…
The latest issue I’ve had is that when the lines are created and I want to mark the shipment as shipped, when the update method or updatemaster is called, the BO changes the packnum of the header records to the next available pack number creating orphaned records in the ShipDtl table. Has anyone ever seen this?
As a work around, I disposed the dataset and BO and reinitialized and called GetById before the update thinking I could get a fresh dataset in memory and then set it to shipped but then I get an error that I can’t troubleshoot. See below. Any help would be appreciated.

See screenshot of packnum being changed.

 csTS = null;
                csBO.Dispose();
                csBO = null;

                csTS = new Erp.Tablesets.CustShipTableset(); // TableSet
                csBO = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.CustShipSvcContract>(Db);

                csTS = csBO.GetByID(returnVal);
                sHead = csTS.ShipHead.FirstOrDefault();

                System.Collections.IList pCodes = new List<string>();
                csBO.GetPkgCodeQtyList(returnVal, out pCodes);
                sHead.ReadyToInvoice = true;
                sHead.RowMod = "U";
                csBO.Update(ref csTS);

Error:
" at Epicor.Data.BufferCopy.GetRowCopier(Object fromItem, Object toItem, Boolean fullRowCopy)\r\n at Epicor.Data.BufferCopy.Copy(Object fromItem, Object toItem, Boolean includeSysRowID)\r\n at Epicor.Data.BufferCopy.Copy[TTypeTo](Object fromItem, TTypeTo& toItem)\r\n at Erp.Services.BO.CustShipSvc.UpdateMaster(CustShipTableset& ds, Boolean doValidateCreditHold, Boolean doCheckShipDtl, Boolean doLotValidation, Boolean doCheckOrderComplete, Boolean doPostUpdate, Boolean doCheckCompliance, Boolean ipShippedFlagChanged, Int32 ipPackNum, Int32 ipBTCustNum, String& opReleaseMessage, String& opCompleteMessage, String& opShippingMessage, String& opLotMessage, String& opInventoryMessage, String& opLockQtyMessage, String& opAllocationMessage, String& opPartListNeedsAttr, String& opLotListNeedsAttr, String& shipCreditMsg, Boolean& cError, Boolean& compError, String& msg, String& opPostUpdMessage, Boolean& updateComplete, Boolean& checkComplianceError, Boolean& changeStatusError, Boolean& checkShipDtlAgain) in C:\_Releases\ERP\UD10.2.400.9\Source\Server\Services\BO\CustShip\CustShip.cs:line 34235\r\n at Erp.Services.BO.CustShipSvcFacade.UpdateMaster(CustShipTableset& ds, Boolean doValidateCreditHold, Boolean doCheckShipDtl, Boolean doLotValidation, Boolean doCheckOrderComplete, Boolean doPostUpdate, Boolean doCheckCompliance, Boolean ipShippedFlagChanged, Int32 ipPackNum, Int32 ipBTCustNum, String& opReleaseMessage, String& opCompleteMessage, String& opShippingMessage, String& opLotMessage, String& opInventoryMessage, String& opLockQtyMessage, String& opAllocationMessage, String& opPartListNeedsAttr, String& opLotListNeedsAttr, String& shipCreditMsg, Boolean& cError, Boolean& compError, String& msg, String& opPostUpdMessage, Boolean& updateComplete, Boolean& checkComplianceError, Boolean& changeStatusError, Boolean& checkShipDtlAgain) in C:\_Releases\ERP\UD10.2.400.9\Source\Server\Services\BO\CustShip\CustShipSvcFacade.cs:line 4692\r\n at ProcessExecutionLoads.CSExecution.CreateCustomerShipment(ErpContext Db, UD109Row udHead, IEnumerable`1& udDtls, String Plant) in E:\Epicor\Externals\Source\E10.2.400\ProcessExecutionLoads\CSExecution.cs:line 200"

Ok it seems I found the issue. I needed to create a duplicate header record in the dataset of the current header data row and then change one of the records RowMod to U and ReadyToInvoice to true. This is usually done in the backend by the BO, but in this case it wasn’t. I just used BufferCopy and below is the code in case anyone has to deal with this mess.

Also, I noticed that UpdateMaster works differently based on the flags that are set to true, while this is normal behavior seemingly, if you don’t get the right combination of the flags set to true, it wont do the task you want. For example, I had to set all the flags to false in order to get the method to run without error. If I had the two flags (that are shown in the trace) set to true, it wouldn’t do anything. On some instances in other places I was using it, it would throw an error, usually a null reference to a ttRow, which didn’t make sense because those rows existed in the TS. So play with the combos.

Also, check the updatecomplete flag on the masterupdate. If that is false, but you got no error, most likely you got a warning. This would usually be a popup in the UI asking the user if they want to continue. To accept the warning, call the UpdateMaster again with all the flags set to false. It should save.

Also after adding all the lines, I had to reload the TS because of what I had to do to add the lines. It seems after the first line added before you call GetNewOrderShipDtl, you need to modify the first row’s RowMod to equal U (and only the first row no matter how many you add) and get the order info then before you update, remove the RowMod value to be a blank so it doesn’t update into the db.

I don’t normally post code, but this BO is messy and hopefully this helps someone down the road.

sHead = csTS.ShipHead.FirstOrDefault();
Erp.Tablesets.ShipHeadRow copyRow = new Erp.Tablesets.ShipHeadRow();
                BufferCopy.Copy(sHead, copyRow);
                csTS.ShipHead.Add(copyRow);
                sHead.ReadyToInvoice = true;
                sHead.RowMod = "U";
                
                csBO.UpdateMaster(ref csTS, false, false, false, false, false, false, false, sHead.PackNum, sHead.BTCustNum, out opRelMes, out opCompMes, out opShipMes,
                                 out opLotMes, out opInvMes, out opLockQtyMes, out opAllocMes, out opPLMes, out opLLMes, out opCredMes, out cErr, out compErr,
                                 out oMes, out opPostMes, out updateComplete, out chkCompError, out chgStatError, out chkDtlAgain);
2 Likes