0
votes

I have a requirement to have a field on SalesOrder screen and the same field should appear on Shipment screen also for respective SalesOrder. And the user should be able to update these field on both the screen.

I created a bound field on Sales Order screen which user can save it. Then I created an unbound field on Shipment screen to show the text from Sales Order. For that I have written a SOShipment_RowSelected event and later for user to update it to the database, I have written SOShipment_RowUpdated. However, when I try to edit the field, it fires RowSelected event and it overwrites the editing and bring back in the same original value.

I have tried with SOShipment_ShipmentNbr_FieldUpdated & SOShipment_ShipmentNbr_FieldUpdating event but its not firing everytime.

Here is the code for Cache extension-

public class SOOrderExtension : PXCacheExtension<SOOrder>
{
	#region UsrNotesText
	[PXDBString(255)]
	[PXUIField(DisplayName = "Pick List Notes")]
	public virtual string UsrNotesText { get; set; }
	public abstract class usrNotesText : IBqlField { }
	#endregion
}
	
public class SOShipmentExtension : PXCacheExtension<SOShipment>
{
	#region UsrNotesText
	[PXString(255)]
	[PXUIField(DisplayName = "Pick List Notes")]
	public virtual string UsrNotesText { get; set; }
	public abstract class usrNotesText : IBqlField { }
	#endregion
}

SOShipmentExtension code-

public class SOShipmentEntryExtension : PXGraphExtension<SOShipmentEntry>
{
	PXSelect<SOOrder> soOrder;

	protected virtual void SOShipment_RowSelected(PXCache sender, PXRowSelectedEventArgs e)
	{
		if (e.Row != null)
		{
			SOOrder order = PXSelectJoin<SOOrder,
				LeftJoin<SOOrderShipment, On<SOOrder.orderNbr, Equal<SOOrderShipment.orderNbr>,
					And<SOOrder.orderType, Equal<SOOrderShipment.orderType>>>,
				LeftJoin<SOShipment, On<SOOrderShipment.shipmentNbr, Equal<SOShipment.shipmentNbr>>>>,
				Where<SOShipment.shipmentNbr, Equal<Current<SOShipment.shipmentNbr>>>>.Select(Base);

			if (order != null)
			{
				SOOrderExtension orderExt = PXCache<SOOrder>.GetExtension<SOOrderExtension>(order);

				SOShipment soShipment = Base.Document.Current;

				SOShipmentExtension ext = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(soShipment);
				ext.UsrNotesText = orderExt.UsrNotesText;
			}
		}
	}

	protected virtual void SOShipment_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
	{
		SOShipment oldRow = (SOShipment)e.OldRow;
		SOShipment newRow = (SOShipment)e.Row;

		if (oldRow != null || newRow != null)
		{
			SOShipmentExtension oldExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(oldRow);
			SOShipmentExtension newExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(newRow);


			if (oldExt.UsrNotesText != newExt.UsrNotesText)
			{
				{
					SOOrder order = PXSelectJoin<SOOrder,
					LeftJoin<SOOrderShipment, On<SOOrder.orderNbr, Equal<SOOrderShipment.orderNbr>,
						And<SOOrder.orderType, Equal<SOOrderShipment.orderType>>>,
					LeftJoin<SOShipment, On<SOOrderShipment.shipmentNbr, Equal<SOShipment.shipmentNbr>>>>,
					Where<SOShipment.shipmentNbr, Equal<Current<SOShipment.shipmentNbr>>>>.Select(Base);

					soOrder.Current = order;

					if (order != null)
					{
						SOOrderExtension orderExt = PXCache<SOOrder>.GetExtension<SOOrderExtension>(order);

						orderExt.UsrNotesText = newExt.UsrNotesText;
						soOrder.Update(order);
					}
				}
			}
		}
	}
}

Any suggestions?

1
RowSelected is not a good place for data updates. Should only be for UI stuff such as visible, enabled, etc. What about RowInserted? - Brendan
RowInserted doesn't work either. I thought that will fire only when inserting new row for primary DAC. I know RowSelected is not a good place for setting some default value, however no other event works for me for some reason. - Krunal
If all else fail, SOShipment_UsrNotesText_FieldSelecting shoud do it. - Hugues Beauséjour
The issue is no such event is triggering. I am using Acumatica version 17.203.0029, will there be any issue with that event. - Krunal
I've never had FieldSelecting not triggering. In fact it's often a last recourse solution to most eventing problems. Double check the syntax: public void SOShipment_UsrNotesText_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e) - Hugues Beauséjour

1 Answers

1
votes

The trick is to initialize UsrNotesText elsewhere.

You can use PXDefault attribute:

[PXDefault(typeof(Search<SOOrderExtension.usrNotesText, Where< [...] >>))]

Or FieldDefaulting event handler:

public void SOShipment_UsrNotesText_FieldDefaulting(PXCache sender, PXFieldDefaultingEventArgs e)
{
   e.NewValue = [...]
}

Sometimes you also want to re-initialize when user changes key fields that are not re-triggering the default.:

public void SOShipment_ShipmentNbr_FieldUpdated(PXCache sender, PXFieldDefaultingEventArgs e)
{
    SOShipment shipment = e.Row as SOShipment;

    if (shipment != null)
    {
        SOShipmentExtension shipmentExt = PXCache<SOShipment>.GetExtension<SOShipmentExtension>(shipment);

        if (shipmentExt != null)
        {
            shipmentExt.UsrNotesText = [...];
        }
    }
}

In such case manually re-triggering FieldDefaulting event with RaiseFieldDefaulting is often a better option.

However method you choose to initialize avoid setting the field value in RowSelected because that event is called at times when you don't want to initialize the custom field.