0
votes

I have a modification that facilitates an internal business process utilizing PO and SO. The screen provides the ability to purchase an MRO spare part outside of the normal replenishment process. The item may or may not be maintained in inventory, so it may be ordered for replenishment or as an SO to be processed as Mark for PO.

In creating the SO, I am able to store the SO reference information to the DAC for my customization. When creating the PO directly, I also am able to capture the PO reference information. However, when creating the PO from the SO using the standard Acumatica menu action for Create Purchase Order, I have been unable to capture the right event to enable storing the PO reference being assigned in SOLineSplit3 to my custom DAC. (Worth noting that I also need to be able to override the default curyunitcost value on the PO line using the value stored on my custom DAC as these purchases do not carry a fixed price per buy. This is done by tracing the SOLineSplit back to my custom DAC and overriding POLine_CuryUnitCost_FieldDefaulting.)

The action invoked on the Sales Order Entry screen (Action - Create Purchase Order) calls the method CreatePOOrders in POCreate.cs which in turn creates an instance of the POOrderEntry graph to create the actual purchase order.

Eventually, the following code is reached, which appears to attach the PO reference information to SOLineSplit3 as soline:

soline.POType = line.OrderType;
soline.PONbr = line.OrderNbr;
soline.POLineNbr = line.LineNbr;
soline.RefNoteID = docgraph.Document.Current.NoteID;

docgraph.UpdateSOLine(soline, docgraph.Document.Current.VendorID, true);

docgraph.FixedDemand.Cache.SetStatus(soline, PXEntryStatus.Updated);

I am not yet familiar with Cache.SetStatus, but the pop-up description seems to indicate that this is using the FixedDemand select in POOrderEntry to find and set (or insert) the SOLineSplit3 record. The call to UpdateSOLine above it is a new internal method that was not in my previous version of POCrete.cs, as this entire method seems to have had some significant rework recently. In trying to capture events on SOLineSplit3 in both POCreate and POOrderEntry, it appears that Cache.SetStatus does not raise any events that I can capture... or I am just completely lost on what event to capture/override.

Immediately following this section, the following appears to update a Replenishment record and save the entire POOrderEntry graph.

if (docgraph.Transactions.Cache.IsInsertedUpdatedDeleted)
{
    using (PXTransactionScope scope = new PXTransactionScope())
    {
        docgraph.Save.Press();

        if (demand.PlanType == INPlanConstants.Plan90)
        {
            docgraph.Replenihment.Current = docgraph.Replenihment.Search<INReplenishmentOrder.noteID>(demand.RefNoteID);
            if (docgraph.Replenihment.Current != null)
            {
                INReplenishmentLine rLine =
                    PXCache<INReplenishmentLine>.CreateCopy(docgraph.ReplenishmentLines.Insert(new INReplenishmentLine()));

                rLine.InventoryID = line.InventoryID;
                ...
                rLine.PlanID = demand.PlanID;
                docgraph.ReplenishmentLines.Update(rLine);
                docgraph.Caches[typeof(INItemPlan)].Delete(demand);
                docgraph.Save.Press();
            }
        }
        scope.Complete();
    }
...
}

Basically, I need to insert my code right between the assignment of the PO information to "soline" and the docgraph.Save.Press(); without copying dozens of lines of code to modify this method. I have managed cloning the base method and inserting my code successfully, but I'd prefer to use an event handler and eliminate modifying the standard code. But the question... What event in which graph will let me grab the PO information and follow the breadcumbs back through SOLineSplit to my custom DAC?

Acumatica Build 18.212.0033

1
Can you identify which specific event you need to override? DAC + Event Type, for example POLine_RowInserted? That is the hard part to understand for me, I don't know which event to target from your business rules. Besides that, the solution is to intercept the POOrderEntry graph (with InstanceCreated) created by action Create Purchase Order and hook events on the intercepted graph.Hugues Beauséjour
I have been trying to override SOLineSplit3_RowUpdated as I need to grab the SO information from the SOLineSplit and attach the PO references to my custom DAC. I have also tried other variations on field level events and even trying to hit RowPersisting and RowPersisted, but the DAC I need accessible to my update is SOLineSplit3.Brian Stevens
Working on an example, my computer is very slow but I should have something soon.Hugues Beauséjour

1 Answers

0
votes

Extend POCreate graph because it is the one instanciating the POOrderEntry you are interested in.

Setup a hook on any POOrderEntry graph created by POCreate and subscribe your events on the intercepted graph. I tested this solution, with a Sales Order that has allocations lines in allocation window it will catch the SOLineSplit3 events:

public class POCreate_Extension : PXGraphExtension<POCreate>
{
    public override void Initialize()
    {
        PXGraph.InstanceCreated.AddHandler<POOrderEntry>((graph) =>
        {
            graph.RowInserting.AddHandler<POOrder>((sender, e) =>
            {
                PXTrace.WriteInformation("POOrderEntry_POOrder_RowInserting");
            });

            graph.RowInserting.AddHandler<POOrderEntry.SOLineSplit3>((sender, e) =>
            {
                PXTrace.WriteInformation("POOrderEntry_SOLineSplit3_RowInserting");
            });

            graph.RowUpdating.AddHandler<POOrderEntry.SOLineSplit3>((sender, e) =>
            {
                PXTrace.WriteInformation("POOrderEntry_SOLineSplit3_RowUpdating");
            });

            graph.RowPersisting.AddHandler<POOrderEntry.SOLineSplit3>((sender, e) =>
            {
                PXTrace.WriteInformation("POOrderEntry_SOLineSplit3_RowPersisting");
            });
        });
    }
}