I’m attempting to write a Transaction API call into a tightly integrated client’s Epicor system that will receive POs utilizing our data from a PO receipt JSON our system generates upon confirmation.
The issue we’re running into is that the item_id field on the PO receipt screen is locked for inventory updates. Only the quantity field can be filled in (which is true on the standard PO Receiving screen also in the P21 UI.
If you feed it multiple “Rows”, they don’t seem to apply to different rows in the UI - as if you’d press the down arrow after you enter a quantity. E.g. There are 4 lines on the PO Item A,B,C,D with quantities 310, 103, 206, 403. The error coming back that we get at the end, after submitting the transaction set, is that the quantity entered is greater than the quantity for the item - I believe implying 403 > 310 - but there may be another reason for the error?
Hoping someone knows how to force the quantity to correspond to the correct item. I noticed in the transaction template definition there is a “ParentText”: “Items” - but I cannot find an example of how to utilize this in the transaction.
Code in C# (only relevant bits included… please ask if more context is needed):
DataElement lotQtyElement = new DataElement();
lotQtyElement.Name = "TABPAGE_LOT_BIN_XREF.tabpage_lot_bin_xref";
lotQtyElement.Type = DataElementType.Form;
lotQtyElement.Keys = new List<string> { "lot_cd", "item_id" };
DataElement itemQtyElement = new DataElement();
itemQtyElement.Name = "TABPAGE_17.tp_17_dw_17";
itemQtyElement.Type = DataElementType.Form;
itemQtyElement.Keys = new List<string> { "item_id"};
// "receipt" below refers to the JSON object from the third party warehousing system confirming a receipt.
// This pulls back the existing PO receipt inventory lines in the correct order so we can match up our fed in quantities in the right order
ServiceDefinition purchaseOrderReceiptServiceDef = transactionRestClient.GetServiceDefinition("PurchaseOrderReceipt");
TransactionStateRequest transactionStateRequest = new TransactionStateRequest();
transactionStateRequest.ServiceName = purchaseOrderReceiptServiceDef.Template.TransactionSet.Name;
transactionStateRequest.TransactionStates.Add(new TransactionState("TABPAGE_1.tp_1_dw_po", "po_no", receipt.AsnId));
TransactionSet retrievedTransactionSet = transactionRestClient.GetTransactionState(transactionStateRequest);
DataElement dataElement = retrievedTransactionSet.Transactions[0].DataElements
.Find(element => element.Name == "TABPAGE_17.tp_17_dw_17");
<< itemQtyElements are created to line up with the DataElement found above - cannot use the actual rows in the one above because nearly all the fields are locked >>
foreach (var line in sortedLines) //Lines are presorted to be in the same order as the existing PO in P21.
{
<< unitQuantity (received quantity) calculated from UOM conversion and receipt quantity here >>
var lotRowToAdd = new P21.Transactions.Model.V2.Row()
{
Edits = new List<Edit>
{
new Edit("item_id", line.ItemId),
new Edit("lot_cd", "lot" ),
new Edit("bin_cd", "bin"),
new Edit("unit_quantity", unitQuantity.ToString())
}
};
lotQtyElement.Rows.Add(lotRowToAdd);
var itemQtyToAdd = new P21.Transactions.Model.V2.Row()
{
Edits = new List<Edit>
{
new Edit("unit_quantity", unitQuantity.ToString()),
// new Edit("item_id", line.ItemId) This must be commented out because it returns an error on submission because the field is locked.
}
};
<< itemQtyToAdd is added to the list of Rows in itemQtyElement in the same order as the actual PO line in P21 here. >>
}
transactions = new TransactionSet
{
Name = "PurchaseOrderReceipt",
Transactions = new List<P21.Transactions.Model.V2.Transaction>
{
new P21.Transactions.Model.V2.Transaction
{
DataElements = new List<DataElement>
{
new DataElement
{
Name = "TABPAGE_1.tp_1_dw_po",
Type = DataElementType.Form,
Keys = new List<string>{"po_no"},
Rows = new List<P21.Transactions.Model.V2.Row>
{
new P21.Transactions.Model.V2.Row
{
Edits = new List<Edit>
{
new Edit("po_no", receipt.AsnId),
new Edit("location_id", receipt.location),
}
}
}
},
itemQtyElement,
lotQtyElement,
}
}
}
};
}
result = transactionRestClient.ProcessTransactionSet(transactions);