TheNewbie
TheNewbie

Reputation: 33

Acumatica Warning Message To Only Affect Shipment Screen SO302000

I'm trying to display a warning every time the ShippedQty field is changed to a value < OrigOrderQty on the "Shipment - SO302000" screen, but I only want the code to be active for that specific screen/form.

I added the code below to extend the SOShipmentEntry graph, which accomplishes my original goal, but the issue is that now the code I added is also being used by the "Create Shipment" action in "Sales Orders - SO301000" screen/form.

Create Shipment Action Discussed

namespace PX.Objects.SO
{
  public class SOShipmentEntry_Extension : PXGraphExtension<SOShipmentEntry>
{
  #region Event Handlers

  protected void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)
{


         var myrow = (SOShipLine)e.Row;
            if (myrow == null) return;


                if (myrow.ShippedQty >= myrow.OrigOrderQty)
                {

                }
            else
            {
                throw new PXSetPropertyException("The difference between the shipped-qty and the ordered-qty will be placed on a back-order", PXErrorLevel.Warning);
            }  

}


  #endregion
 }
}

While the warning allows the user to save changes to a shipment on the Shipment Screen/form SO302000 (Because the exception is set up as a warning and not an error), I get the following error when I create a shipment using the "Create Shipment" button on the "Sales Orders - SO301000" screen.

Warning works fine for form-mode

Warning becomes error when processed in background by action button

Any ideas to accomplish this? It is my understanding that if I want to make global changes to a field I must make them in the DAC, but if I want to make changes that only affect screens/forms where a graph is used, then I have to make those changes in the graph code itself. I'm guessing the "Create Shipment" action button in the Sales Orders screen is creating an instance of the graph where I added the code, so I'm wondering what are my options here.

Best regards,

-An Acumatica newbie

Upvotes: 1

Views: 1008

Answers (1)

Hugues Beaus&#233;jour
Hugues Beaus&#233;jour

Reputation: 8278

If you want your event logic to execute only when CreateShipment is invoked from the Shipment screen you can override the other calls to CreateShipment to dynamically remove your event handler.

The event that invokes CreateShipment action from the SalesOrderEntry graph is Action:

public PXAction<SOOrder> action;
[PXUIField(DisplayName = "Actions", MapEnableRights = PXCacheRights.Select)]
[PXButton]
protected virtual IEnumerable Action(PXAdapter adapter,
    [PXInt]
    [PXIntList(new int[] { 1, 2, 3, 4, 5 }, new string[] { "Create Shipment", "Apply Assignment Rules", "Create Invoice", "Post Invoice to IN", "Create Purchase Order" })]
    int? actionID,
    [PXDate]
    DateTime? shipDate,
    [PXSelector(typeof(INSite.siteCD))]
    string siteCD,
    [SOOperation.List]
    string operation,
    [PXString()]
    string ActionName
    )

In that method it creates a SOShipmentEntry graph to create the shipment. You can override Action and remove your handler from that graph instance:

SOShipmentEntry docgraph = PXGraph.CreateInstance<SOShipmentEntry>();

// >> Remove event handler
SOShipmentEntry_Extension docgraphExt = docgraph.GetExtension<SOShipmentEntry_Extension>();
docgraph.FieldUpdated.RemoveHandler<SOShipLine.shippedQuantity>(docgrapExt.SOShipLine_ShippedQty_FieldUpdated);
// << Remove event handler

docgraph.CreateShipment(order, SiteID, filter.ShipDate, adapter.MassProcess, operation, created);

Note that in order to reference SOShipLine_ShippedQty_FieldUpdated method from another graph you'll have to make it public:

public void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)

I have described how to do this in that answer too: Updating custom field is ending into infinite loop


If you want your event logic to execute only when it is modified in the UI or by web service.

You can use the ExternalCall Boolean property of the PXFieldUpdatedEventArgs parameter. This property value will be true only when the sender field is modified in the UI or by web service.

Usage example:

protected void SOShipLine_ShippedQty_FieldUpdated(PXCache cache,PXFieldUpdatedEventArgs e)
{
   // If ShippedQty was updated in the UI or by a web service call
   if (e.ExternalCall)
   {
      // The logic here won't be executed when CreateShipment is invoked
   }
}

ExternalCall Property (PXFieldUpdatedEventArgs)

Gets the value specifying whether the new value of the current DAC field has been changed in the UI or through the Web Service API.

Upvotes: 1

Related Questions