Solved

Custom field on Cases screen is not updating when I set a value to it

  • 14 June 2023
  • 7 replies
  • 92 views

Userlevel 6
Badge +3

I have added custom fields to the cases screen.  

When you select a record type, the Service Type field should be cleared so the user has to select a new value.  The Service Type selector is filled with data based on the selected Record Type.

When you select a new value in the Record Type field, the Service Type should be set to null.

Strangely, it works, but ONLY if it is the FIRST time you update the Record Type after bringing up the case.

Any changes in that field other than the first one, the Service type is not being cleared.

I used the RowSelected handler for CRCase to try to null the field.  

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

            CRCaseExt itemExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);

            if (itemExt == null) return;

            if (itemExt.UsrServiceTypeID != null)
            {
                SSGCRServTypeRecTypeLinks link = SelectFrom<SSGCRServTypeRecTypeLinks>.Where<SSGCRServTypeRecTypeLinks.serviceTypeID.IsEqual<@P.AsInt>
.And<SSGCRServTypeRecTypeLinks.recordTypeID.IsEqual<@P.AsInt>>>.View.Select(Base, itemExt.UsrServiceTypeID, itemExt.UsrRecordTypeID);

                if (link == null) itemExt.UsrServiceTypeID = null;
            }
        }

If the “link” is null, then the value in the Service Type is not linked to the Record Type and the Service Type field should be nulled.

In debug, I verified that the last time the rowselected fires, the value in itemExt.UsrServiceTypeID is set to null.  However, on the screen, I get this:

Fortunately you cannot save the record, but it looks ugly to the user.

The custom code “works” but I’d like to make it not look buggy.

Note, I tried nulling the Service Type field in the FieldUpdated handler for the RecordType field, but it did not do anything.

        protected void CRCase_UsrRecordTypeID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
        {
            CRCase row = (CRCase)e.Row;
            if (row == null) return;

            CRCaseExt itemExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);

            if (itemExt == null) return;

            itemExt.UsrServiceTypeID = null;
        }

Any thoughts?

 

icon

Best answer by Naveen Boga 14 June 2023, 20:07

View original

7 replies

Badge +11

I believe your FieldUpdated event would need to include

itemExt.UsrServiceTypeID = null; //already existing code
cache.Update(row);

 

Userlevel 7
Badge +17

Hi @Joe Schmucker   We should avoid including the Cache.Update(row) statement. With this statement, the system will continuously trigger of the FieldUpdated event in the same view and leads to the overflow exceptions.

 

I don’t see any issues with the above code, but can you try like below and confirm?

 

protected void CRCase_UsrRecordTypeID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
CRCase row = (CRCase)e.Row;
if (row == null) return;

CRCaseExt itemExt = row.GetExtension<CRCaseExt>();

if (itemExt == null) return;

itemExt.UsrServiceTypeID = null;
}

 

Badge +11

We should avoid including the Cache.Update(row) statement. With this statement, the system will continuously trigger of the FieldUpdated event in the same view and leads to the overflow exceptions.

Ah, he’s right. My bad, don’t do that.

Userlevel 6
Badge +3

@Naveen Boga  I did try that and a cache.Update on the FieldUpdated handler did crash the site. 

I changed to using the FieldUpdating handler and I found that cache.Update(row) caused an exception.

Using cache.Update(itemExt) works (sort of).  I will explain below.

My next step was to check for a default value from the maintenance table.  If there is a default = true, it updates the Service Type field.  YAY.

However, if I try to set it to null, it does not clear the field.  I was just told moments ago that every Record Type will be required to have a default value.  So, this code works and solves my issue:

 

        protected void CRCase_UsrRecordTypeID_FieldUpdating(PXCache cache, PXFieldUpdatingEventArgs e)
        {
            CRCase row = (CRCase)e.Row;
            if (row == null) return;

            CRCaseExt itemExt = PXCache<CRCase>.GetExtension<CRCaseExt>(row);

            if (itemExt == null) return;

            SSGCRRecordType sSGCRRecordType = SelectFrom<SSGCRRecordType>.Where<SSGCRRecordType.recordTypeCD.IsEqual<@P.AsString>>.View.Select(Base, e.NewValue);

            foreach (SSGCRServTypeRecTypeLinks link in SelectFrom<SSGCRServTypeRecTypeLinks>.
                InnerJoin<SSGCRRecordType>.On<SSGCRRecordType.recordTypeID.IsEqual<SSGCRServTypeRecTypeLinks.recordTypeID>>
                .Where<SSGCRServTypeRecTypeLinks.recordTypeID.IsEqual<@P.AsInt>>.View.Select(Base, sSGCRRecordType.RecordTypeID))
            {
                if (link.IsDefault == true)
                {
                    itemExt.UsrServiceTypeID = link.ServiceTypeID;
                }
            }
            cache.Update(itemExt);
            //cache.Update(row);
        }

Since there will always be a default in the maint table, this will always populate a value in the service type field.  I am putting code on the maintenance screen to require a default service type for each record type.

 

Userlevel 7
Badge +17

@Joe Schmucker   This code → cache.Update(itemExt); NOT required at all.

 

Can you please check with below code ?

 protected void CRCase_UsrRecordTypeID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
CRCase row = (CRCase)e.Row;
if (row != null)
{
CRCaseExt itemExt = row.GetExtension<CRCaseExt>();

SSGCRRecordType sSGCRRecordType = SelectFrom<SSGCRRecordType>.Where<SSGCRRecordType.recordTypeCD.IsEqual<@P.AsString>>.View.Select(Base, itemExt.UsrRecordTypeID);

foreach (SSGCRServTypeRecTypeLinks link in SelectFrom<SSGCRServTypeRecTypeLinks>.
InnerJoin<SSGCRRecordType>.On<SSGCRRecordType.recordTypeID.IsEqual<SSGCRServTypeRecTypeLinks.recordTypeID>>
.Where<SSGCRServTypeRecTypeLinks.recordTypeID.IsEqual<@P.AsInt>>.View.Select(Base, sSGCRRecordType?.RecordTypeID))
{
if (link.IsDefault == true)
{
cache.SetValue<CRCaseExt.usrServiceTypeID>(row, link.ServiceTypeID);
}
}
}
}

 

Userlevel 6
Badge +3

@Naveen Boga 

Hi @Joe Schmucker   We should avoid including the Cache.Update(row) statement. With this statement, the system will continuously trigger of the FieldUpdated event in the same view and leads to the overflow exceptions.

 

I don’t see any issues with the above code, but can you try like below and confirm?

 

protected void CRCase_UsrRecordTypeID_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
CRCase row = (CRCase)e.Row;
if (row == null) return;

CRCaseExt itemExt = row.GetExtension<CRCaseExt>();

if (itemExt == null) return;

itemExt.UsrServiceTypeID = null;
}

 

I tried that too.  Many iterations ago.  :-)  I just tried that code again and it works (but only once).

Here is the really strange thing.  If you load the record onto the Cases screen, it WORKS ONE TIME.  It will clear the service type field the first time you change the record type field.  If you don’t save and change the RecordType field again, it doesn’t null the service type field.  So, it kind of works, but only the first time.

However, since I am now populating the field with a default value in the FieldUpdating, I don’t need to null the field.  It is strange that that doesn’t work.  

Userlevel 6
Badge +3

@Naveen Boga  

I found that if I don’t do that in the FieldUpdating handler, it doesn’t update the field.

I tried your last blob of code and made a tweak to it and it works great! 

				//SSGCRRecordType sSGCRRecordType = SelectFrom<SSGCRRecordType>.Where<SSGCRRecordType.recordTypeID.IsEqual<@P.AsInt>>.View.Select(Base, itemExt.UsrRecordTypeID);

foreach (SSGCRServTypeRecTypeLinks link in SelectFrom<SSGCRServTypeRecTypeLinks>.
InnerJoin<SSGCRRecordType>.On<SSGCRRecordType.recordTypeID.IsEqual<SSGCRServTypeRecTypeLinks.recordTypeID>>
.Where<SSGCRServTypeRecTypeLinks.recordTypeID.IsEqual<@P.AsInt>>.View.Select(Base, itemExt.UsrRecordTypeID))

Since I am using Updated rather than Updating, I don’t need to get the ID with a BQL select.  In the updating handler, the NewValue is the CD, not the ID.  

Thanks guys.  This works great and is more efficient as well.  

I will keep this line in my keepers folder!

cache.SetValue<CRCaseExt.usrServiceTypeID>(row, link.ServiceTypeID);

I always forget that command!

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