Use Rest API to modify ECOMtl QtyPer value - Erp.Bo.EngWorkBenchSvc

My goal is to update the “QtyPer” value of the ECOMtl object for a part. I can successfully Check Out the part revision via API request…
https://epicor01.server.com/Pilot/api/v1/Erp.Bo.EngWorkBenchSvc/CheckOut

{
  "ipGroupID": "BOMINTEGRATION",
  "ipPartNum": "PART123",
  "ipRevisionNum": "INITIAL",
  "ipAsOfDate": "2025-07-30T00:00:00",
  "ipAltMethod": "",
  "ipProcessMfgID": "",
  "ipCompleteTree": false,
  "ipValidPassword": true,
  "ipReturn": false,
  "ipGetDatasetForTree": true,
  "ipUseMethodForParts": false
}

Once checked out I can then add a new ECOMtl with the following request…
https://epicor01.server.com/Pilot/api/v1/Erp.Bo.EngWorkBenchSvc/Update

{
  "ds": {
    "ECOMtl": [
      {
        "Company": "200",
        "PartNum": "PART123",
        "RevisionNum": "INITIAL",
        "MtlSeq": 10,
        "MtlPartNum": "COMPONENT123",
        "UOMCode": "LBS",
        "QtyPer": 1.23,
        "GroupID": "BOMINTEGRATION",
        "RowMod": "A"
      }
    ]
  }
}

But when I make the following request…
https://epicor01.server.com/Pilot/api/v1/Erp.Bo.EngWorkBenchSvc/Update

{
  "ds": {
    "ECOMtl": [      
      {
        "Company": "200",
        "PartNum": "PART123",
        "RevisionNum": "INITIAL",
        "MtlSeq": 10,
        "MtlPartNum": "COMPONENT123",
        "QtyPer": 2.23,
        <A BUNCH OF OTHER TAGS>
        "RowMod": "U"
      }
    ]
  }
}

I get the following response…

{
    "HttpStatus": 400,
    "ReasonPhrase": "REST API Exception",
    "ErrorMessage": "Row has been modified by another user and couldn't be updated.",
    "ErrorType": "Ice.BLException",
    "ErrorDetails": [
        {
            "Message": "Row has been modified by another user and couldn't be updated.",
            "Type": "Error",
            "Table": "ECOMtl",
            "Field": "SysRevID",
            "Program": "Epicor.Ice.dll",
            "Method": "Validate",
            "ColumnNumber": 9,
            "LineNumber": 124,
            "RowID": "140c0d9d-5a3e-45dc-a11e-2e86cb3df2e0"
        }
    ],
    "CorrelationId": "e0a70cd2-24fc-4b7b-9e78-4f3d8994e57b"
}

What am I missing?
I’m using the same authorization/user in each request.

You need to get the sysrev ID and a before image. Since you aren’t passing in the current sysrevID it assumes that it changed. You’ll need to copy the original and pass it in with the new row.

{
  "ds": {
    "ECOMtl": [      
      {
        "Company": "200",
        "PartNum": "PART123",
        "RevisionNum": "INITIAL",
        "MtlSeq": 10,
        "MtlPartNum": "COMPONENT123",
        "QtyPer": 2.23,
        <A BUNCH OF OTHER TAGS>
        
        "RowMod": "U"
      }
      {
        "Company": "200",
        "PartNum": "PART123",
        "RevisionNum": "INITIAL",
        "MtlSeq": 10,
        "MtlPartNum": "COMPONENT123",
        "QtyPer": 1.23,
        <A BUNCH OF OTHER TAGS>
        "SysRevID":"Guid of the sysrow that you looked up",
        "RowMod": ""
      }
    ]
  }
}

So something sort of like this. One row is your updated row, and the other row is the original row. You should be able to get that from the response of the previous call.

This is used to check whether you have the most up to date copy, (collision detection) and to do things in BPM’s like conditions “Field x changed from y to z” the before image is how it knows if it changed or not.

Adding the material doesn’t need a before image, because there isn’t one for a new row.

Thanks for the quick reply Brandon. I’ll give this a try and let you know how it goes.

What request do you recommend I use to get the SysRevID and a “before image”?

If I use https://epicor01.server.com/Pilot/api/v1/Erp.Bo.EngWorkBenchSvc/ChangeECOMtlQtyPer
I get a SysRevID and SysRowID. Then when I copy that into the Update request it returns the following…

{
    "HttpStatus": 404,
    "ReasonPhrase": "REST API Exception",
    "ErrorMessage": "Record for update was not found by its SysRowID value [95011eca-95f0-487d-adb6-0093fd02819b].",
    "ErrorType": "Ice.Common.RecordNotFoundException",
    "ErrorDetails": [
        {
            "Message": "Record for update was not found by its SysRowID value [95011eca-95f0-487d-adb6-0093fd02819b].",
            "Type": "Error",
            "Program": "Epicor.Ice.dll",
            "Method": "UpdateRow",
            "ColumnNumber": 21,
            "LineNumber": 1207
        }
    ],
    "CorrelationId": "64515c6c-b4cb-4ed1-a03b-83303ce53044"
}

The SysRowID it references is the one I copied in from the ChangeECOMtlQtyPer request.

Brandon I’m still banging my head against the wall on this. So far the only way I’ve been able to get a SysRevID and SysRowID is by using the client and parsing through results in Developer Tools. And when I use those values I get a response that says another user modified the data or that the “Revision is currently being used by .”

Any more guidance/direction on this?

Assuming we’re in a state of the part/revision checked out to an ECO Group called “BOMINTEGRATION”:

To get the “Before” row, you want to do an EngWorkBenchSvc/GetByID to pull the contents of the ECO Group,
EngWorkBenchTableSet ewbts = EngWorkBenchSvc.GetByID("BOMINTEGRATION");
now, your original row will be in
var originalrow = ewbts.ECOMtl.FirstOrDefault(x => x.Company == "200" && x.PartNum == "PART123" && x.MtlSeq == 10)
To update it, make a copy of the row, update whatever columns you need, then set RowMod = U on that row copy.
So now you have 2 identical copies of the row, aside from whatever fields you changed, and RowMod = U instead of RowMod = “”
Add the row to the tableset you pulled with GetByID:
ewbts.ECOMtl.Add(newrow);
then send it back to the update BO:
ewbSvc.Update(ewbts);

Also, a note, if you use UpdateExt instead of Update, you don’t have to do this rather complicated step!
UpdateExt doesn’t need RowMod at all, it will look up the row by matching primary keys - if it exists, it updates, if not, it adds. rowmod is only needed for deletes in updateext. Much simpler :slight_smile:

Thanks for the input Gabe. I’m finally getting back to this. I’d very much like to use UpdateExt, but I’m getting the following response…

request URL: https://epicor01.server.com/Pilot/api/v1/Erp.Bo.EngWorkBenchSvc/UpdateExt

"returnObj": {
        "BOUpdError": [
            {
                "TableName": "ECOGroup",
                "ErrorLevel": "Error",
                "ErrorType": "Exception",
                "ErrorText": "Row has been modified by another user and couldn't be updated.",
                "ErrorSysRowID": "f3b7b35e-8f16-420a-8da0-fed2aabef75a",
                "SysRowID": "da3baf3f-6e49-48ad-93b5-e70d8052bc08",
                "RowMod": ""
            }
        ],
        "ExtensionTables": []

“row has been modified by another user” is a conflict with SysRevID, (record in database has a different value than you are inputting) try UpdateExt without that or SysRowID in the payload.

Success! Now I just have to figure out what fields in the request aren’t needed.

Thanks for your help Gabe.