Epicor Functions > CustShip.UpdateMaster > doCheckShipDtl method error

Hello,

I am trying to set a CustShip’s “Shipped” status to true. While doing this, I assume the Line > “Shipped Complete” box is checked as well.

I am running into an error in one of my functions trying to automate it:

Message: "Record not found."
Type: "Ice.BLException"
Table: "ShipHead"
Program: "Erp.Services.BO.CustShip.dll"
Method: "checkShipDtlCore"

when using “UpdateMaster” from CustShip.
This is what I’m populating:
image

It succeeds when I set “doCheckShipDtl” to false, but I’ll need to update the ShipDtl records as well.
I checked to make sure that the CustShip DataSet (custShipDS) has ShipDtl records. They also have the same PackNum as the ShipHead entry. packNum and custNum are populated properly as well.

Any ideas/experience with this method?
Also, if anyone has any alternative methods to accomplish this, I’m all ears.

Thanks in advance!

The update methods are completely inconsistent as to what data is actually sent to the server (and by extension, available to you out of the box on the BPM). Sometimes it sends the whole record. Other times just the row being modified. Still others send not just the updated data, but rows corresponding to the old data.

So when you get the “record not found” it’s probably because that table in the dataset is empty. You usually have to run a LINQ query or GetByID to grab the object you’re trying to update and then populate the missing row before updating.

2 Likes

Thank you for your response!

Here’s my function overview:

I’m grabbing the custShipDS using GetById.

I also implemented this custom code:

var shipHeadEntry = BufferCopy.Copy<Erp.Tablesets.ShipHeadRow>(custShipDS.ShipHead[0]);
shipHeadEntry.RowMod = "";
custShipDS.ShipHead.Add(shipHeadEntry);

as per Logic works in BL Tester, but not BPM Code (Mass Shipment) - #12 by Jason_Woods
but without success.

Is this the type of “GetById” you were referring to?

Looking at the other thread, it looks like @Jason_Woods created the updated ShipHead row, and then added a copy of unmodified row (which is what your quoted snippet is doing). Is there an updated ShipHead row in your DS?

1 Like

I traced the methods used by Epicor when clicking the “Shipped” checkbox and added those methods to the function with the required parameters as best as I could. I assumed that using those methods would update the row, but I can imagine that it isn’t doing it.

As you asked if I had an updated row, I tried setting ShipHead.ReadyToInvoice (Shipped) to true before the implemented code, which I assumed would give the row an updated status, but I’m not sure about anything about Epicor.
Now I’m getting the same error, not for ShipDtl, but for ShipHead!

Also, for ShipDtl, would I have to do the same - since that is where it fails?

  • I figured I can get away with only setting ShipHead and using UpdateMaster (since setting a ShipHead to shipped automatically completes the lines too)

Whether or not the system considers a row updated is based on the RowMod field. Changing the ReadyToInvoice field in the dataset will not, by itself, change the RowMod to “U” (updated). The system will ignore any other changes if RowMod == “”. Well, it won’t write the changes. It still might barf if your DS row doesn’t match the DB.

2 Likes

Okay that is super helpful, thank you very much for the information. I was able to change my code to the following:

// Update ShipHead
var shipHeadEntry = BufferCopy.Copy<Erp.Tablesets.ShipHeadRow>(custShipDS.ShipHead[0]);
shipHeadEntry.ReadyToInvoice = true;
shipHeadEntry.RowMod = "U";
custShipDS.ShipHead.Add(shipHeadEntry);

int numShipDtlRecords = custShipDS.ShipDtl.Count;
for(int i = 0; i < numShipDtlRecords; i++)
{
  // Update ShipDtl records
  var shipDtlEntry = BufferCopy.Copy<Erp.Tablesets.ShipDtlRow>(custShipDS.ShipDtl[i]);
  shipDtlEntry.ShipCmpl = true;
  shipDtlEntry.RowMod = "U";
  custShipDS.ShipDtl.Add(shipDtlEntry);
}

Now I’m just getting the error:

"Message": "Row has been modified by another user and couldn't be updated.",
"Table": "ShipDtl",
"Field": "SysRevID",
"Program": "Epicor.Ice.dll",
"Method": "Validate",

which is progress, but confuses me quite a bit lol
This is the type of error I usually get when someone modifies a record while I look at it in Epicor. Now I’m getting it here… Can’t I update both ShipHead and ShipDtl in one go?

Edit:
I don’t need to. Removing the for loop part will do the trick!

What happens when you only update the ShipHead record?

1 Like

This solved the last error.
I am able to push only ShipHead and it seems to automatically do the rest (I am never setting the ShipDtl booleans, Epicor is doing that by itself).

I awarded the solution to the above comment, because that is what solved the main issue for me.

I really appreciate your help!

Posting the final solution, because I know it’s a bit of a process to find all the right answers to get UpdateMaster working:

Problem: I am trying to programmatically activate the “Shipped” checkbox in Customer Shipment Entry using Epicor Functions.

Here is my function (I think you might only need GetById, custom code, and UpdateMaster):

Required Methods:
Get Custship → Erp.CustShip.GetByID
Code:

var shipHeadEntry = BufferCopy.Copy<Erp.Tablesets.ShipHeadRow>(custShipDS.ShipHead[0]);
shipHeadEntry.ReadyToInvoice = true;
shipHeadEntry.RowMod = "U";
custShipDS.ShipHead.Add(shipHeadEntry);

UpdateMaster only works when you set the RowMod field of the row you want to update to “U”.

Hi!, BufferCopy.Copy works perfect to me, any explanation of why do we have to add a copy to the ds? it doesn’t make sense to me :stuck_out_tongue:
jajaja thanks in advance

1 Like

It’s how Epicor determines if there are changes to the row or not.

One row is the unmodified row, and one has changes.
They determine which is which by looking at the RowMod.

It’s also how BPMs check for field changes, like field changed from something.

3 Likes