Update Customer Shipment Through API

I’m running a (basically my first) function in an API call, where we receive certain parameters through JSON - example below - for a customer shipment and then need to update those fields in the Customer Shipment (and the Order itself, but I’m focusing on the shipment first), and my function is not exactly working the way I expected it to. My layout is below, but the intended logic is as such:

  • Pull in the ShipHead record and any ShipDtl records that match.
  • Update the changed fields within the function for the ShipHead and all ShipDtl rows, including setting the RowMod to “U”
  • Invoke the BO function to Update the records in the table.
  • Great success!

Can anybody shine a light on where I’m going wrong?

{
  "ShipmentID": "26625",
  "TrackingNo": "LD46",
  "CarrierName": "ABF Freight",
  "SchDeliveryDate": "2024-12-04T15:38:48.920Z",
  "ActDeliveryDate": "2024-12-04T15:38:48.920Z",
  "FreightCost": 125.00,
  "AccessorialCost": 0,
  "ShipmentStatus": "Delivered",
  "ProofOfDelivery": ""
}

Also, attaching the function file, since that screenshot is probably not super helpful.
TEST-TMS.efxb (960.7 KB)

Hi Seth.

I think you need to add some more information before anyone can jump in here. Are you getting an error? Did you do a trace of the manual process? Are you following it? Good on you for using a function!

3 Likes

Hey Mark!

I was getting errors at times, but now it went through… EXCEPT it deleted the pack ID I supplied and created a brand new one with the info I supplied. I was attempting to follow the process, yes. The only main items I am seeing are

  • Erp.CustShip.CheckPCBinOutLocation
  • Erp.CustShipUpdateMaster

I did try to use the Master function, but I can’t seem to get a tableset that will feed into the function. My standard CustShipTableset isn’t recognized.

Hi Seth,

You’re on a newer version than I am, so I couldn’t import your function library.

I use the API to update packs with information that is similar to what I think you are trying to accomplish.

In my case, though, I’m doing some of the work in Automation Studio and some with functions.

If you haven’t done so already, do a trace while you manually do all the operations you want to include in the function. This will help you identify all the BO operations you will need to include in your function.

Keep in mind that some fields on a Shipment can’t be changed if Ready to Invoice = true. You’ll have to set it to false before you can do some updates.

Based on your function parameters and your screenshot, I’d expect a flow that uses CustShip Get By ID, Another step to get the ShipViaCode based on the description that you have in the parameters, then Set the ShipViaCode, Tracking number, and ShipStatus in a single step using Fill by Query widget and then a CustShip Update BO.

I’d get that working then add in the updated values for the other data you want to change.

2 Likes

Hey @danvoss,

I did those, but now I am dealing with the pack slip getting deleted and recreated with the new info instead of updating the pack slip ID provided.

Can you select all the widgets in your function and then screenshot toe rows on the Action tab of the properties? This will help me get a better understanding of what you are doing.

Sure thing!

First, I am setting each of the incoming variables to typed variables in code.


Next, I am invoking the CustShip.GetByID BO to pull in the ShipHead values based on the incoming PackID I received.


Next, I am invoking the CustShip.CheckPCBinOutLocation, though I don’t think this is making any difference at the moment, but it was in the trace.


After that, I set a ShipmentStatusConv variable to change the ShipmentStatus I am going to insert, as the user will send a “Delivered” value which Epicor does not accept.


Following that, I update all rows in the tableset with their existing values, based on the query that pulls using the same shipment ID from ShipHead, except those I wish to change (ShipComment (adds “Delivered” text if the incoming status was “Delivered”), ReadyToInvoice (false in case that prevents changes), TrackingNo, ShipStatus, and SlipStatus. SysRowID does get ignored.



Immediately after, I run one more update, based on the ShipVia table, so that I can update the ShipViaCode based on the description that is sent from the API. I also update the RowMod to “U” in this step.



Finally, I invoke the CustShip.Update BO to push the new fields.


I did also add an invocation of CustShip.GetByID at the end, even though this uses no interface, just like the first one, but it returns the error that it can’t find the record due to it deleting the previous on and recreating it.

Check out the posts below. I knew this issue sounded familiar. It likely has to do with the BeforeImage.

1 Like

I’ve not encountered the issues that Chris referenced.

While you are going to use REST API to call the function, all of the operations within the function are calling BO methods – not REST API.

I suggest starting small and building from there. Something like -


GetbyID-
image
Set New Values - The query for this update is just all fields of dsCustShip ShipHead with no filter.

UpdateMaster - You may want to capture some of the output to variables for later use.

Test with a Pack that is marked shipped and see if this will successfully update the pack to make it not shipped.

Once successful with that, add other new values in the Set New Values step.

It’s possible that you might have to complete the “unship” step before you can update other fields. i.e. your function might need multiple Master Update steps.

3 Likes

That was the culprit, thank you so much, @spaceage !

So weird that it needs a copy of the row in order to update… Guess I can’t stick to widgets only for now.

2 Likes

I’m glad it helped @halcyon !

1 Like

Not really, that’s how it knows what changed.

One unmodified row, and one updated row is the idea.

1 Like

Ahhh, so it needs the original row AND the update row to compare. Understood!

1 Like