Krunal
Krunal

Reputation: 1188

Populating unbound field from another bound custom field

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?

Upvotes: 0

Views: 1068

Answers (1)

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

Reputation: 8278

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.

Upvotes: 1

Related Questions