0
votes

I've been having many problems inserting a Purchase Order using the API because it often responds with errors which are vague or don't identify the cause correctly. We have quite a few customizations for the site involved, so to narrow down the issue, I created a new clean Acumatica ERP installation (v17.210.0034) to work with, with no endpoint extensions, and installed the SalesDemo data in both.

Even with clean installation sites like this, I'm still getting vague errors when trying to insert a PO. For example, I followed the steps below, using Postman to call the API:

  1. Login: POST to url = "http://localhost/Acu172100034/entity/auth/login, with JSON credentials in the body. Response = success.
  2. GET a PO: url = http://localhost/Acu172100034/entity/Default/17.200.001/PurchaseOrder/RO/PO000696?$expand=Details,ShippingInstructions. Response = JSON data for the PO
  3. I copied the JSON in the GET response above and pasted it into a new PUT request body. I removed all "id", "rowNumber", "custom" and "files" fields. I removed the "OrderNbr" field in the header and detail rows since it is an auto-number field for a PO.
  4. I attempt to insert a new PO using the modified JSON with a PUT: url = http://localhost/Acu172100034/entity/Default/17.200.001/PurchaseOrder,

The error response includes: "PX.Data.PXException: Error: 'Branch' cannot be empty.\r\nError: 'Ship To' cannot be empty.\r\nError: 'Location' cannot be found in the system.\r\n ---> PX.Data.PXOuterException: Error: Inserting 'Purchase Order' record raised at least one error. Please review the errors."

There is a BranchID specified on the PO Line, there is a Location specified on the PO header, and there is a ShipTo specified on the ShippingInstructions. The Location does exist. This error is obviously vague and misleading. Only by trial and error did I determine that I needed to change Hold from true to false to get past this error. I assume this is because there's some validation or rule which disallows an insert or update while on hold? After changing Hold to false and attempting an insert with a PUT again, I then get an error: "PX.Data.PXException: Error: An error occurred during processing of the field InventoryID: Object reference not set to an instance of an object.. ---> System.NullReferenceException: Object reference not set to an instance of an object." and the call stack includes POOrderEntry.POLine_ExpenseAcctID_FieldDefaulting and POOrderEntry.POLine_LineType_FieldUpdated event handlers.

There is an InventoryID on the PO Line, and the inventory item exists, so it looks like these event handlers are throwing errors for some reason when LineType is being set, but I'm guessing. Any ideas how to get this simple API insert to work?

Update (2/23/19): I modified the JSON for insert a bit more by changing the detail item Completed to "false", and the PO header Hold to "true", and the Status to "On Hold". The error mentioned above now changes to "Error: 'UOM' cannot be empty.\r\nError: 'Account' cannot be empty.\r\nError: 'Sub.' cannot be empty.". The UOM is not empty, Account is empty, and SubAccount is empty; but Account and SubAccount are not required fields for a PO Line.

1
I ran through your example and see the same issues. I looked through the code and find it is due to field defaulting, erroring out on some setup fields, namely getting the carrier. I removed the detail and received errors on other fields. I was able to get it to be inserted on hold, and then do a quick put with the OrderNbr that was returned and Hold set to false, and it went through. Give that workaround a try, but I am not sure if anyone else has any input on to why these are not setting?KRichardson
KRichardson, if you specify the same OrderNbr, then it behaves like an update instead of an insert. I also can get an update to work.Tony Lanzer
The workaround would be to insert as on hold, then take the OrderNbr returned and then perform a second call that would be an update. This was able to get my PO created and ready to be approved off hold due to the second call/update.KRichardson
KRichardson, if you mean just supply required fields and Hold=true for an insert, then perform an update, yes, that would probably work.Tony Lanzer

1 Answers

0
votes

After more trial and error, I was able to insert a PO by additionally changing the JSON being inserted by removing the two fields "QtyOnReceipts" and "ReceivedAmount". Can you see why the errors I'm receiving in the response in no way helps to find the cause of the error? I still don't even know why removing these fields resolved the error. The most reliable way to perform an API insert is probably -- as KRichardson suggested -- always insert first with only the minimum required fields, then perform an update with the rest. Or, perform a LOT of testing with trial and error to determine what fields and values allow for a successful insert. If I were to change or add field values in the JSON, or use JSON from a different record, I have no real confidence that the changes I made to get it to work will always work.