I'm wondering if it possible to override DefaultEndpointImpl.cs or add my own API logic in another file?
I'm struggling with a few API calls which require the logic in this file to be overridden or added to. For example I am able to create a purchase receipt for a PO via the api successfully, however I'm not able to add a "Transfer Receipt" purchase receipt in the same way.
I've included various non-standard fields to the API endpoints that reference the original transfer, transfer order and shipment but have been unsuccessful. The API calls succeeds but no lines are added. I've been able to get lines to update their quantity once generated but can't add or delete current lines.
The problem looks to stem from this code, which seems to add functionality that correctly handles adding Purchase order lines logic of the graph but doesn't do anything special for other receipt types.
[FieldsProcessed(new[] { "POLineNbr", "POOrderType", "POOrderNbr" })]
protected void PurchaseReceiptDetail_Insert(PXGraph graph, EntityImpl entity, EntityImpl targetEntity) {
var receiptEntry = (POReceiptEntry)graph;
var lineNbr = targetEntity.Fields.SingleOrDefault(f => f.Name == "POLineNbr") as EntityValueField;
var orderType = targetEntity.Fields.SingleOrDefault(f => f.Name == "POOrderType") as EntityValueField;
var orderNbr = targetEntity.Fields.SingleOrDefault(f => f.Name == "POOrderNbr") as EntityValueField;
bool insertViaAddPO = lineNbr != null && orderNbr != null && orderType != null;
if (!insertViaAddPO && (lineNbr != null || orderType != null || orderNbr != null)) {
throw new PXException(PO.Messages.POTypeNbrLineNbrMustBeFilled);
}
var detailsCache = receiptEntry.transactions.Cache;
if (insertViaAddPO) {
receiptEntry.filter.Cache.Remove(receiptEntry.filter.Current);
receiptEntry.filter.Cache.Insert(new POReceiptEntry.POOrderFilter());
var filter = receiptEntry.filter.Current; var state = receiptEntry.filter.Cache.GetStateExt(filter, "OrderType") as PXStringState;
if (state != null && state.AllowedLabels.Contains(orderType.Value)) {
orderType.Value = state.ValueLabelDic.Single(p => p.Value == orderType.Value).Key;
}
receiptEntry.filter.Cache.SetValueExt(filter, "OrderType", orderType.Value);
receiptEntry.filter.Cache.SetValueExt(filter, "OrderNbr", orderNbr.Value);
receiptEntry.filter.Update(filter);
var orders = receiptEntry.poLinesSelection.Select().Select(r => r.GetItem<POReceiptEntry.POLineS>());
var order = orders.FirstOrDefault(o => o.LineNbr == int.Parse(lineNbr.Value));
if (order == null) {
throw new PXException(PO.Messages.PurchaseOrderLineNotFound);
}
order.Selected = true;
receiptEntry.poLinesSelection.Update(order);
receiptEntry.Actions["AddPOOrderLine2"].Press();
} else {
detailsCache.Current = detailsCache.Insert();
}
}
After a lot of trial and error I have managed to get everything working as I need. However I'm concerned that since this is not documented information that it may be subject to change in the near future.
The methods in the class DefaultEndpointImpl are called via reflection. To add custom functionality for my default endpoint I have extended the default class and added the necessary attributes to my class and functions.
My custom class adds the following:
The first one was pretty straight forward and I'm happy with the outcome. The second one took a lot of time and debugging to get right, is hacky and probably doesn't work with serial tracked items. The reason it's taken so long is because there are many unknowns and I've essentially been guessing based on the code in the base class. For example I'm not even sure at which stage this function fires. It looks the functions completely override some other default logic which is invisible.
So take it or leave it! Maybe I will reach out to Acumatica to see if I can get more information.