Skip to main content

How To Run an Event Handler Once per Screen Load


Forum|alt.badge.img+8
  • Captain II
  • 396 replies

Hello everyone,

 

I am sure we all have events we would want to run once per screen load, unfortunately, we do not have a ScreenLoaded event or anything of that sort.

 

To overcome this you can create a non-persisted bool.

#region TrueFalse
public abstract class trueFalse : BqlBool.Field<trueFalse> { }
[PXBool]
[PXUIField(Display Name ="True/False", Enabled = false, Visible = false)]
public virtual bool? TrueFalse { get; set; }
#endregion

Then you can control the value of this with a RowSelected event handler

protected virtual void _(Events.RowSelected<YourDAC> e)
{
  YourDAC row = e.Row;
  if(row == null) return;

  if(row.TrueFalse != true)
  {
    row.TrueFalse = true;
  } 

  else return;
}

This field value will hold until the screen is refreshed, however, when it is refreshed it will trigger the RowSelected handler again and set the value to true.

 

You could also update the field value within the handler that executes your logic, in this case my non-persisted bool is UsrCreditHold and use an if() to determine whether the logic is executed based on your field.

protected virtual void _(Events.RowPersisting<SOShipment> e, PXRowPersisting b)
{
    b?.Invoke(e.Cache, e.Args);
    SOShipment row = e.Row;
    if (row == null) return;

    SOShipmentCreditHold rowExt = row.GetExtension<SOShipmentCreditHold>();

    if (rowExt.UsrCreditHold != true)
    {
        ARBalances remBal = SelectFrom<ARBalances>.
         Where<ARBalances.customerID.IsEqual<P.AsInt>.
            And<ARBalances.customerLocationID.IsEqual<P.AsInt>>>.View.Select(Base, row.CustomerID, row.CustomerLocationID);

        if (remBal == null) return;

        Customer customer = SelectFrom<Customer>.
            Where<Customer.bAccountID.IsEqual<P.AsInt>>.View.Select(Base, row.CustomerID);
        if (customer == null) return;

        var creditLimit = customer.CreditLimit;
        var balance = creditLimit - ((remBal.CurrentBal ?? 0) + (remBal.TotalOpenOrders ?? 0) + (remBal.TotalShipped ?? 0) - (remBal.TotalPrepayments ?? 0));


    }


    var query = SelectFrom<SOShipment>
        .InnerJoin<Customer>
          .On<Customer.bAccountID.IsEqual<P.AsInt>>
        .InnerJoin<ARBalances>
          .On<ARBalances.customerID.IsEqual<P.AsInt>>
        .AggregateTo<GroupBy<SOShipment.customerID, Avg<Customer.creditLimit>>>.View.Select(Base, row.CustomerID, row.CustomerID);



    foreach (PXResult<SOShipment, Customer, ARBalances> result in query)
    {

        SOShipment shipment = result;
        Customer cust = result;
        ARBalances arBal = result;

        decimal? currentBalSum = arBal.CurrentBal ?? 0m;
        decimal? totalOpenOrdersSum = arBal.TotalOpenOrders ?? 0m;
        decimal? totalShippedSum = arBal.TotalShipped ?? 0m;
        decimal? totalPrepaymentsSum = arBal.TotalPrepayments ?? 0m;
        decimal? creditLimit = cust.CreditLimit ?? 0m;

        decimal? bal = creditLimit - ((currentBalSum + totalOpenOrdersSum + totalShippedSum) - totalPrepaymentsSum);

        if (balance < 0)
        {
            if(rowExt.UsrCreditHold != true)
            {
                e.Cache.SetValueExt<SOShipmentCreditHold.usrCreditHold>(rowExt.UsrCreditHold, true);



                SOShipmentCreditHold.MyEvents
                    .Select(events => events.CreditLimitViolated)
                    .FireOn(Base, row);
            }

        }
    }

}

This is particularly useful with event handlers that are called many times during a session but you may not want the logic executed every time.

 

I hope this helps someone!

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

0 replies

Be the first to reply!

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