Solved

Custom field not being saved to database unless I change something else on the screen

  • 11 May 2023
  • 2 replies
  • 418 views

Userlevel 6
Badge +3

I added a custom field to the Equipment screen FS205000.

I am looking up the AMProdID and storing it in the custom field.

The rowselected handler is getting the value and it shows on the screen.  I set the cache to IsDirty = true so that the user will need to click save when the rowselected does not find a Production Nbr in the custom field.

If I don’t set cache.IsDirty = true, then it does not show that the record needs to be saved.

When you click the Save button, it does not save the value in the FSEquipment table.

This is the screen and it shows the value I am adding to the screen:

 

IF I change the Description and click Save, it DOES save the custom field.

Here is the graph extension:

	public class SMEquipmentMaint_Extension : PXGraphExtension<SMEquipmentMaint>
{
public static bool IsActive() => true;

#region Event Handlers
protected void FSEquipment_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var row = (FSEquipment)e.Row;

FSEquipmentExt itemExt = PXCache<FSEquipment>.GetExtension<FSEquipmentExt>(row);
if (itemExt == null) return;

//if already has a value, exit method
if (itemExt.UsrAMProdOrdID != null) return;

AMProdItem aMProdItem = SelectFrom<AMProdItem>
.InnerJoin<SOLineMfgOnly>.On<SOLineMfgOnly.aMProdOrdID.IsEqual<AMProdItem.prodOrdID>>
.InnerJoin<ARTran>.On<ARTran.sOOrderNbr.IsEqual<SOLineMfgOnly.orderNbr>.And<ARTran.sOOrderLineNbr.IsEqual<SOLineMfgOnly.lineNbr>>>
.InnerJoin<FSEquipment>.On<FSEquipment.sourceRefNbr.IsEqual<ARTran.refNbr>.And<FSEquipment.arTranLineNbr.IsEqual<ARTran.lineNbr>>>
.Where<FSEquipment.SMequipmentID.IsEqual<FSEquipment.SMequipmentID.FromCurrent>.And<FSEquipment.sourceRefNbr.IsEqual<FSEquipment.sourceRefNbr.FromCurrent>>>
.AggregateTo<GroupBy<AMProdItem.prodOrdID>>.View.Select(Base);

if (aMProdItem != null)
{
itemExt.UsrAMProdOrdID = aMProdItem.ProdOrdID;
cache.IsDirty = true;
}
}
#endregion
}

This is the DAC extension.  I used a selector so that you can drill into the Production Nbr field and open the Production Order Maintenance screen (which works great as is).

        [PXDBString(15, IsUnicode = true, InputMask = "")]
        [PXUIField(DisplayName = "Production Nbr.", Enabled = false)]
  [PXSelector(typeof(SearchFor<AMProdItem.prodOrdID>.Where<AMProdItem.prodOrdID.IsEqual<FSEquipmentExt.usrAMProdOrdID.FromCurrent>>))]
        public string UsrAMProdOrdID { get; set; }
        public abstract class usrAMProdOrdID : PX.Data.BQL.BqlString.Field<usrAMProdOrdID> { }
 

Do I need to do something else to let the screen know the extension field has been updated?

I think this is the spot where I might need to change something:

            if (aMProdItem != null)
            {
                itemExt.UsrAMProdOrdID = aMProdItem.ProdOrdID;
                cache.IsDirty = true;
            }
 

 

icon

Best answer by Vignesh Ponnusamy 11 May 2023, 21:43

View original

2 replies

Userlevel 7
Badge +4

Hi @Joe Schmucker,

I would suggest you override the Persist method and set the value for the custom field before invoking the baseMethod. In the below example, I am just setting the value for the field and updating the cache(Base.EquipmentSelected.Cache.Update) before invoking the base. 

 

       public delegate void PersistDelegate();
        [PXOverride]
        public void Persist(PersistDelegate baseMethod)
        {
                FSEquipment equipment = Base.EquipmentSelected.Current;
                FSEquipmentExt itemExt = PXCache<FSEquipment>.GetExtension<FSEquipmentExt>(equipment);
                if (itemExt.UsrAMProdOrdID == "AM000002")
                {
                    itemExt.UsrAMProdOrdID = "AM000001"; //You can set value from the BQL
                }
                else
                {
                    itemExt.UsrAMProdOrdID = "AM000002"; //You can set value from the BQL
                }
            Base.EquipmentSelected.Cache.Update(equipment);
            baseMethod();
        } 

 

Note: I have added the condition just for my testing, to check if the value is update each time I save.

Please feel free to post if you have any questions.! Good Luck,

Userlevel 6
Badge +3

@Vignesh Ponnusamy Thank you!  That works! 

I did a combination of rowselected and the code you provided.

In the Rowselected, I get the value and set it for the screen.  I also set the isdirty = true so that the user will be prompted to save.  If I just use the PersistDelegate, there is no prompt to save the record unless they make a change to it.

VERY strange that the persist delegate is needed.  You will see in the code below, I don't actually set the value of the item in the Persist delegate.  It is done in the rowselected.  But without your delegate, it doesn’t update the DB.

Thank you for your help!!!

This is what I ended up with:

        public delegate void PersistDelegate();
        [PXOverride]
        public void Persist(PersistDelegate baseMethod)
        {
            FSEquipment equipment = Base.EquipmentSelected.Current;
            FSEquipmentExt itemExt = PXCache<FSEquipment>.GetExtension<FSEquipmentExt>(equipment);

            Base.EquipmentSelected.Cache.Update(equipment);
            baseMethod();
        }

        #region Event Handlers
        protected void FSEquipment_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
        {
            var row = (FSEquipment)e.Row;

            FSEquipment equipment = Base.EquipmentSelected.Current;

            FSEquipmentExt itemExt = PXCache<FSEquipment>.GetExtension<FSEquipmentExt>(equipment);
            if (itemExt == null) return;

            //if already has a value, exit method
            if (itemExt.UsrAMProdOrdID != null) return;

            AMProdItem aMProdItem = SelectFrom<AMProdItem>
                .InnerJoin<SOLineMfgOnly>.On<SOLineMfgOnly.aMProdOrdID.IsEqual<AMProdItem.prodOrdID>>
                .InnerJoin<ARTran>.On<ARTran.sOOrderNbr.IsEqual<SOLineMfgOnly.orderNbr>.And<ARTran.sOOrderLineNbr.IsEqual<SOLineMfgOnly.lineNbr>>>
                .InnerJoin<FSEquipment>.On<FSEquipment.sourceRefNbr.IsEqual<ARTran.refNbr>.And<FSEquipment.arTranLineNbr.IsEqual<ARTran.lineNbr>>>
                .Where<FSEquipment.SMequipmentID.IsEqual<FSEquipment.SMequipmentID.FromCurrent>.And<FSEquipment.sourceRefNbr.IsEqual<FSEquipment.sourceRefNbr.FromCurrent>>>
                .AggregateTo<GroupBy<AMProdItem.prodOrdID>>.View.Select(Base);

            if (aMProdItem != null)
            {
                itemExt.UsrAMProdOrdID = aMProdItem.ProdOrdID;
                cache.IsDirty = true;
            }
        }
        #endregion

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved