Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

customization - Updating custom field on Location via event handler on Customer breaks after Acuamtica upgrade

I have a custom field on the Location DAC which gets updated via event handlers on the Customer screen. Similarly this custom field can also be updated by events on the Business Account screen. My code is working in Acumatica version 2019 R1. However in version 2020 R2, the code breaks and I cannot figure out how to adjust it accordingly.

The scenario is that we have a boolean on Location called usrResidentialValidated which indicates whether or not the location address has been validated with FedEx (and then we have code to validate with FedEx as needed). If the location information is changed on the Customer or Business Account screen, we need to set usrResidentialValided on the corresponding location to False so that it can be queued for subsequent validation.

As I mentioned, our code is functional in Acumatica 2019 R1 but broken in 2020 R2, and I cannot see how to make it work in 2020 R2. There are a few things which may be factors: 1.Page 44 of the 2020 R2 Developer Release Notes indicates that in the upgrade LocationExtAddress view on the Customer graph has been moved into DefLocationExt. However, DefLocationExt is not an ordinary view, and it is not clear to me how to use this new view for my situation. 2. Also, the CustomerMaint graph now is using PX.Objects.CR.Standalone.Location, but my custom field extends PX.Objects.CR.Location. I wonder if that is another source of trouble. If so, I don't know how to best handle that either. The custom field is currently in use on our live version of Acuamtica, and I need to preserve that data.

Here's is my code:

Custom Field to extend PX.Objects.CR.Location

using PX.Objects.SO;
using PX.Objects.TX;
using PX.Objects;
using System.Collections.Generic;
using System;

namespace PX.Objects.CR
{
  public class LocationExt : PXCacheExtension<PX.Objects.CR.Location>
  {
          
    #region UsrResidentialValidated
    [PXDBBool]
    [PXUIField(DisplayName="Residential Validated")]
    [PXDefault(false, PersistingCheck = PXPersistingCheck.Nothing)]

    public virtual bool? UsrResidentialValidated { get; set; }
    public abstract class usrResidentialValidated : IBqlField { }
    #endregion

  }
}

Here is my code on the Customer graph extension where I have the event handler (see the comments within the code for the code that's working in 2019 R1 and what I have tried to no avail in 2020 R2):

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using PX.Common;
using PX.Data;
using PX.Objects.CA;
using PX.Objects.CM;
using PX.Objects.CR;
using PX.Objects.CR.Extensions;
using PX.Objects.CS;
using PX.Objects.SO;
using PX.SM;
using PX.Objects.AR.CCPaymentProcessing;
using PX.Objects.Common;
using CashAccountAttribute = PX.Objects.GL.CashAccountAttribute;
using PX.Objects;
using PX.Objects.AR;
using LaSalle;
using LaSalleJO;
using CRLocation = PX.Objects.CR.Standalone.Location;

namespace PX.Objects.AR
{
  
  public class CustomerMaint_Extension:PXGraphExtension<CustomerMaint>
  {
        //  If any fields of the location change, mark location as needing FedEx validation again.
             
        /* ------------ THIS CODE WORKS IN 2019R1 BUT BREAKS IN 2020R2 ----------------- */
        protected virtual void LocationExtAddress_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
        {

            if (e.Row == null) return;
            LocationExtAddress row = (LocationExtAddress)e.Row;
            Location location = PXSelect<Location, Where<Location.locationID, Equal < Required < Location.locationID >>>>.Select(Base, row.LocationID);

            if (location != null)
            {
                LocationExt locationExt = location.GetExtension<LocationExt>();
                
                if (locationExt != null)
                {
                    locationExt.UsrResidentialValidated = false;
                    PXCache cache = Base.Caches[typeof(Location)];
                    cache.Update(location);
                }
            }
        }
        
         /* ------------ MY ATTEMPT TO GET THE CODE TO WORK IN 2020R2 ----------------- */
         /* This is my attempt to get the LocationExtAddress_RowUpdated event handler to work in 2020R2
            Currently this is partially working. 
                - The event handler is successfully triggered when a Location field changes (e.g. when the Ship Via field on the Shipping tab of Customers is edited)
                - The code does successfully update the cache if I view it in Debug mode
                - The change is saved to the DB with the Persist but that understandably generates an "another process has updated ..." error when you save the Customer record 
                 (without Persist the field is not updated)
                - I wonder if the problem has to do with the fact that my custom field extends PX.Objects.CR.Location not PX.Objects.CR.Standalone.Location
         */
        protected void Location_RowUpdated(PXCache cache, PXRowUpdatedEventArgs e)
        {
            if (e.Row == null) return;
            var row = (CRLocation)e.Row;

            Location location = PXSelect<Location, Where<Location.locationID, Equal<Required<Location.locationID>>>>.Select(Base, row.LocationID);

            if (location != null)
            {
                LocationExt locationExt = location.GetExtension<LocationExt>();

                if (locationExt != null)
                {    
                    locationExt.UsrResidentialValidated = false;
                    PXCache locCache = Base.Caches[typeof(Location)];
                    locCache.Update(location); 
                    locCache.Persist(location, PXDBOperation.Update); // With this line, it correctly updates the location in the db but then I get an error on the Customer saying my changes will be lost

                    /* -------------------- SOME OTHER ATTEMPTS --------------------- */
                    //defLocationExt.DefLocation.Cache.Update(location); - no error but doesn't save to the db

                    // Doesn't save to the DB
                    //Base.Caches[typeof(Location)].SetValueExt<LocationExt.usrResidentialValidated>(location, false);
                    //Base.Caches[typeof(Location)].Update(locationExt);

                    // Base.Caches[typeof(Location)].MarkUpdated(location); -- doesn't work

                    // This works too but also has the problem of not saving to the DB either
                    //Base.BaseLocations.Cache.RaiseFieldUpdated<LocationExt.usrResidentialValidated>(locationExt, true);
                    //Base.BaseLocations.Cache.Update(location);
                }
            }

        }

        // If address changes, check to see if there's a linked location. If there is, kick off location updated event handler (LocationExtAddress_RowUpdated),
        // which will mark that FedEx needs validation again 
        
         /* ------------ THIS CODE WORKS IN 2019R1 BUT BREAKS IN 2020R2 ----------------- */
        protected virtual void Address_RowUpdated(PXCache sender, PXRowUpdatedEventArgs e)
         {
             if (e.Row == null) return;
             Address row = (Address)e.Row;

             foreach (LocationExtAddress location in Base.Locations.Select())
             {
                 if (location.DefAddressID == row.AddressID)
                 {
                     Base.Locations.Cache.Update(location); // trigger location updating (for the sake of checking FedEx)
                 }
             }
         }  
  }
}

And here is my code that extends the BAccount graph.

using PX.Objects.CR.MassProcess;
using PX.TM;
using PX.Objects.EP;


using System;
using System.Collections;
using Avalara.AvaTax.Adapter.AvaCert2Service;
using PX.Common;
using PX.Data;
using PX.Data.EP;
using PX.Objects.AR;
using PX.Objects.AP;
using PX.Objects.CM;
using PX.Objects.CS;
using PX.Objects.CT;
using PX.Objects.SO;
using PX.SM;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using PX.Objects;
using PX.Objects.CR;
using LaSalleAB;
using LaSalleJO;
using CRLocation = PX.Objects.CR.Standalone.Location;

namespace LaSalle
{
  
  public class BusinessAccountMaint_Extension:PXGraphExtension<BusinessAccountMaint>
  {
        // If Address changes and the address is being used by a location (Same as Main is checked on the location or the location is linked to the Delivery Settings address), mark that the location needs FedEx validation again
        // This works for both the main address and the delivery settings address
        
        
         /* ------------ THIS CODE WORKS IN 2019R1 BUT BREAKS IN 2020R2 ----------------- */
          public virtual void Address_RowUpdating(PXCache sender, PXRowUpdatingEventArgs e)
        {
            if (e.Row == null) return;
            Address row = (Address)e.Row;

            foreach (Location loc in Base.Locations.Select())
            {
                if (loc.DefAddressID == row.AddressID)
                {
                    Location location = PXSelect<Location, Where<Location.locationID, Equal<Required<Location.locationID>>>>.Select(Base, loc.LocationID);

                    PX.Objects.CR.LocationExt locationExt = location.GetExtension<PX.Objects.CR.LocationExt>();
                    locationExt.UsrResidentialValidated = false;
                    Base.Caches[typeof(Location)].MarkUpdated(location);
                }
            }

        }*/
        
        
        // If the delivery settings carrier changes, mark FedEx as needing validation again on the associated location (only necessary if the carrier changed to FEDH or FEB)

        /* ------------ THIS CODE WORKS IN 2019R1 BUT BREAKS IN 2020R2 ----------------- */
        public virtual void Location_CCarrierID_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
        {
            if (e.Row == null) return;
            Location location = (Location)e.Row;

            String carrier = e.NewValue as String;
            if (carrier == "FEDB" || carrier == "FEDH") {

                PX.Objects.CR.LocationExt locationExt = location.GetExtension<PX.Objects.CR.LocationExt>();

                if (locationExt != null && Base.Locations.Current != null)
                {
                    locationExt.UsrResidentialValidated = false;
                    Base.Caches[typeof(Location)].MarkUpdated(location);

                }
            }
        }
              
              
        // If residential flag changes, mark FedEx has needing validation again on the associated location
        
         /* ------------ THIS CODE WORKS IN 2019R1 BUT BREAKS IN 2020R2 ----------------- */
        public virtual void Location_CResedential_FieldUpdating(PXCache sender, PXFieldUpdatingEventArgs e)
        {

            if (e.Row == null) return;
            Location location = (Location)e.Row;

            PX.Objects.CR.LocationExt locationExt = location.GetExtension<PX.Objects.CR.LocationExt>();

            if (locationExt != null &&a

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...