Skip to main content
Solved

How to Detect Updates to the Shipped Quantity Field on a Blanket Sales Order After POReceipt Release


Forum|alt.badge.img+1

I’m first creating a blanket sales order. Then, I create some child orders by splitting the quantity of the blanket order. After selecting one child sales order, I continue the process. During this process, after releasing the relevant POReceipt for that sales order, the 'Shipped Quantity' field of the parent blanket order gets updated. I want to capture this update.I tried using a SOLine_ShippedQty_FieldUpdated event handler in the SOOrderEntry graph, but it is not being triggered. Please check the below screen shot. Please let me know how I can detect when the 'Shipped Quantity' field is being updated.

Qty.On Shipments(ShippedQty)
protected void SOLine_ShippedQty_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
    PXTrace.WriteInformation("SOLine_ShippedQty_FieldUpdated triggered");
}

 

Best answer by Zoltan Febert

I would create a function or action on the Sales Order screen (or the PO Receipt screen) and call this function after releasing the receipt. Assuming you have the related blanket sales order number for the receipt, you can use it as a parameter to retrieve the necessary data for your API call.

View original
Did this topic help you find an answer to your question?

7 replies

Zoltan Febert
Jr Varsity I
Forum|alt.badge.img+3
  • Jr Varsity I
  • 175 replies
  • August 22, 2024

Hi @malinthawarnakulasooriya08,

The FieldUpdate event will only be triggered if the update occurs directly on the Sales Order screen. If the field is updated through another graph, the FieldUpdate event will not be triggered in this context.

What do you want to do after the field is updated?


Forum|alt.badge.img+1

Thank you so much @Zoltan Febert  for your valuable reply.We have integrated these blanket orders with an external CRM. Along with updating the 'Shipped Quantity' field, we want to pass this updated value to the external CRM via an outbound API call.


Zoltan Febert
Jr Varsity I
Forum|alt.badge.img+3
  • Jr Varsity I
  • 175 replies
  • Answer
  • August 22, 2024

I would create a function or action on the Sales Order screen (or the PO Receipt screen) and call this function after releasing the receipt. Assuming you have the related blanket sales order number for the receipt, you can use it as a parameter to retrieve the necessary data for your API call.


Forum|alt.badge.img+1

I’ll try this based on your suggestion and will let you know the updates. Thank you, @Zoltan Febert , for your valuable guidance.


Forum|alt.badge.img+1

Hi @Zoltan Febert , Can you please provide any suggestion regarding the below issue.

I declared a method in the SOOrderEntry graph as follows.

public void UpdateSalesOrder(PXCache cache, PXFieldUpdatedEventArgs e, string blanketOrderNumber = null)
{
    PXTrace.WriteError("Field_updated");

    // Tenant selection
    if (PX.Data.Update.PXInstanceHelper.CurrentCompany == 3)
    {
        // Determine the appropriate SOOrder row
        SOOrder row = null;

        if (!string.IsNullOrEmpty(blanketOrderNumber))
        {
            // Fetch the specific SOOrder record matching the blanketOrderNumber
            row = PXSelect<SOOrder,
                           Where<SOOrder.orderType, Equal<Required<SOOrder.orderType>>,
                                 And<SOOrder.orderNbr, Equal<Required<SOOrder.orderNbr>>>>>
                           .Select(cache.Graph, "BL", blanketOrderNumber);

            if (row == null)
            {
                PXTrace.WriteError($"No SOOrder found with OrderNbr: {blanketOrderNumber} and OrderType: BL.");
                return;
            }
            else
           {
                PXTrace.WriteInformation(row.OrderNbr);

                SOLine line = SOLines.SelectSingle(row.OrderNbr);  
                 if (line == null)
                {
                    PXTrace.WriteError("SOLine is null.");
                }
                else
                {
                    PXTrace.WriteInformation($"SOLine is not null. Open Qty: {line.OpenQty}, Shipped Qty: {line.ShippedQty}");
                }                                                          
            }                                                              
        }
        else
        {
            // If no blanket order number is provided, use the row from the event args
            row = (SOOrder)e.Row;
            if (row == null)
            {
                PXTrace.WriteError("SOOrder row is null.");
                return;
            }

            // Ensure we're working with a blanket order
            if (row.OrderType != "BL")
            {
                PXTrace.WriteError("OrderType is not 'BL'. Exiting method.");
                return;
            }
        }

     }

 } 

Then, I attempted to call this method from the POReceiptEntry graph as shown below, when the POReceipt's status changed to 'Released'.

 protected void POReceipt_Status_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
    PXTrace.WriteInformation("Entering POReceipt_Status_FieldUpdated");

    try
    {
        var row = (POReceipt)e.Row;
        if (row == null)
        {
            PXTrace.WriteError("POReceipt row is null.");
            return;
        }

        PXTrace.WriteInformation($"POReceipt.Status: {row.Status}");
        if (row.Status != "R")
        {
            PXTrace.WriteInformation("POReceipt.Status is not 'R'. Exiting method.");
            return;
        }

        // Log key variable values
        PXTrace.WriteInformation($"Fetching POReceiptLine for ReceiptNbr: {row.ReceiptNbr}");
        POReceiptLine poReceiptLine = POReceiptLineView.SelectSingle("RT", row.ReceiptNbr);
        if (poReceiptLine == null)
        {
            PXTrace.WriteError("No matching POReceiptLine found.");
        }
        else
        {
            PXTrace.WriteInformation($"Found POReceiptLine: ReceiptType={poReceiptLine.ReceiptType}, LineNbr={poReceiptLine.LineNbr}");
        }

        PXTrace.WriteInformation($"Fetching POOrder for POType: {poReceiptLine?.POType}, PONbr: {poReceiptLine?.PONbr}");
        POOrder poOrder = POOrder.PK.Find(Base, poReceiptLine?.POType, poReceiptLine?.PONbr);
        if (poOrder == null)
        {
            PXTrace.WriteError("No matching POOrder found.");
        }
        else
        {
            PXTrace.WriteInformation($"Found POOrder: OrderType={poOrder.OrderType}, OrderNbr={poOrder.OrderNbr}");
        }

        PXTrace.WriteInformation($"Fetching SOLine for SOOrderNbr: {poOrder?.SOOrderNbr}");
        SOLine soLine = SOLineView.SelectSingle("SO", poOrder?.SOOrderNbr);
        if (soLine != null && !string.IsNullOrEmpty(soLine.BlanketNbr))
        {
            PXTrace.WriteInformation($"Found SOLine with BlanketNbr: {soLine.BlanketNbr}");

            // Log the transition to the next method
            PXTrace.WriteInformation("Calling UpdateSalesOrder");
            var soOrderEntryGraph = PXGraph.CreateInstance<SOOrderEntry>();
            var soOrderEntryExt = soOrderEntryGraph.GetExtension<SOOrderEntry_Extension>();
            soOrderEntryExt.UpdateSalesOrder(Base.Caches[typeof(SOOrder)], null, soLine?.BlanketNbr);
            PXTrace.WriteInformation("UpdateSalesOrder completed");
        }
        else
        {
            PXTrace.WriteError("No SOLine found or no BlanketNbr present to update.");
        }
    }
    catch (Exception ex)
    {
        PXTrace.WriteError($"Error in POReceipt_Status_FieldUpdated: {ex.Message}");
        PXTrace.WriteError($"StackTrace: {ex.StackTrace}");
        throw; // Re-throw the exception after logging
    }
    finally
    {
        PXTrace.WriteInformation("Exiting POReceipt_Status_FieldUpdated");
    }
}

However, after inserting this custom logic, the POReceipt is not getting released and is showing the following error.”A data corruption state has been detected. You cannot save the changes. Copy the data you have entered and reload the page. Date and Time: 2024-09-02T08:59:44; IncidentID: 7b75179c-407e-4b5c-8987-4356b86ef67e; Name: Aggregate Validation: PX.Objects.SO.SOOrder+openLineCntr. You can view detailed information about the issue on the System Events tab of the System Monitor (SM201530) form.”

Please check the below screenshot of the trace also.

The Trace after clicking the Release button in the POReceipt screen

 


Zoltan Febert
Jr Varsity I
Forum|alt.badge.img+3
  • Jr Varsity I
  • 175 replies
  • September 3, 2024

@malinthawarnakulasooriya08, It looks like you try to share PXCache object between graphs, and I think this cause the issue.

soOrderEntryExt.UpdateSalesOrder(Base.Caches[typeof(SOOrder)], null, soLine?.BlanketNbr);

Base here is POReceiptEntry, you need to use soOrderEntryGraph instead.

soOrderEntryExt.UpdateSalesOrder(soOrderEntryGraph.Caches[typeof(SOOrder)], null, soLine?.BlanketNbr);

 


Forum|alt.badge.img+1

Hi @Zoltan Febert , Thank you so much for your valuable feedback, it directly resolved the issue.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings