0
votes

I have a custom field on an Acumatica Production Detail Operation (UsrEligibleForRoboticFulfillment) that I have created an Action to set based on criteria on the component items in the Materials tab. (code below)

I would like to call this Action to set the field as soon as the Production Order is created, but the split nature of the Production Order is such that there are no events on the Production Detail raised that I can attach to and call the Action. I've tried Row Inserted as well as Persist delegate on the Production Detail graph.

I CAN attach to either the AMProdItem Row Inserted or Persist Delegate on the Production Maint graph, but at this point in time the Operations and Materials have not yet been created.

What's the best way to update this field when a new Production Order is created?

Action code:

    public PXAction<AMProdItem> UpdateEligibleForRoboticFulfillment;
    [PXButton(CommitChanges = true)]
    [PXUIField(DisplayName = "Update Robotic Eligibility", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
    protected void updateEligibleForRoboticFulfillment()
    {
        AMProdItem prodDetail = Base.ProdItemRecords.Current;
        AMProdOper prodOper = Base.ProdOperRecords.Current;
        InventoryItem finishedProduct = PXSelect<InventoryItem,
               Where<InventoryItem.inventoryID, Equal<Current<AMProdItem.inventoryID>>>>.Select(Base).FirstOrDefault();

        //Only production orders are eligible for robotic fulfillment, not disassemblies
        if (prodDetail.OrderType == "MO")
        {
            bool wasRoboticsEligible = (prodOper.GetExtension<AMProdOperExt>().UsrEligibleForRoboticFulfillment ?? false);

            //Get the current branchID
            int branchID = (int)Base.Accessinfo.BranchID;

            //Get the default site/warehouse for this branch.
            INSite site = INTranHelper.GetDefaultSiteForItemBranch(branchID);

            //Get the flag indicating whether this site is active for robotics
            bool activeRobotics = site.GetExtension<INSiteExt>().UsrActiveRobotics ?? false;
            //Get the flags for manual process and component robotics compatible

            bool requiresManualProcess = finishedProduct.GetExtension<InventoryItemExt>().UsrManualFinishRequired ?? false;
            //Gotta be prepared for the possibility that more than one component is used
            //Check for any components that are NOT robotics eligible that have qty required and haven't already been fully allocated
            PXResultset<AMProdMatl> components = PXSelectJoin<AMProdMatl,
            InnerJoin<InventoryItem, On<InventoryItem.inventoryID, Equal<AMProdMatl.inventoryID>,
            And<InventoryItemExt.usrRoboticsCompatible, Equal<False>,
            And<AMProdMatl.orderType, Equal<Current<AMProdOper.orderType>>,
            And<AMProdMatl.prodOrdID, Equal<Current<AMProdOper.prodOrdID>>,
            And<AMProdMatl.operationID, Equal<Current<AMProdOper.operationID>>,
            And<AMProdMatl.qtyActual, Less<AMProdMatl.totalQtyRequired>,
            And<AMProdMatl.qtyReq, Greater<decimal0>>>>>>>>>>
            .Select(Base);

            bool roboticsEligible = !requiresManualProcess && activeRobotics;
            //If any component is not eligible, the whole operation is not eligible
            if (components.Count > 0)
            {                    
                       roboticsEligible = false;
            }

            //If the robotics eligible flag should have changed, change it
            if (wasRoboticsEligible != roboticsEligible)
            {
                prodOper.GetExtension<AMProdOperExt>().UsrEligibleForRoboticFulfillment = roboticsEligible;
                Base.ProdOperRecords.Update(prodOper);
            }
        }
    }
1

1 Answers

0
votes

Had to open a ticket with Acumatica; got a working solution! I had to enclose the persist delegate method in a transaction scope.

Override Persist() method of graph Call base method first so that Operations and Materials on the Production Order Detail gets created Enclosed in transaction scope Something like this:

  public delegate void PersistDelegate();
      [PXOverride]
      public void Persist(PersistDelegate baseMethod)
    {
        if (/**/)
        {              
            using (var ts = new PXTransactionScope())
            {


            //Call base method to persist 

            baseMethod();

            /*Custom Logic here*/

            ts.Complete();

        }
    }
    else
        baseMethod();
}