Экран обработки зданий для местоположений клиентов - PullRequest
1 голос
/ 07 июня 2019

Мне нужно создать экран обработки для местоположений клиентов, который определяет, а затем обновляет флаг местожительства на местах.

Этот код правильно обрабатывает каждую выбранную запись и, по-видимому, обновляет соответствующие поля.Но проблема, с которой я сталкиваюсь, заключается в том, что мои изменения в Location не сохраняются обратно в базу данных.

График "Местоположения клиентов" требует, чтобы бизнес-аккаунт был указан, прежде чем вы сможете ввести идентификатор местоположения, и я подозреваю, что из-за этого я не могу просто обновить представление Местоположений на графике.Но я не могу найти никакой документации или примеров кода, указывающих, какой подход я должен использовать здесь.

Вот код на моем графике экрана обработки:

public class ProcessCustomerLocations : PXGraph<ProcessCustomerLocations>
{
    public PXCancel<Location> Cancel;
    public PXProcessing<Location, Where<Location.isActive, Equal<True>>> Locations;

    public static void Process(List<Location> locations)
    {
        var graph = PXGraph.CreateInstance<CustomerLocationMaint>();
        CustomerLocationMaint_Extension graphExt = graph.GetExtension<CustomerLocationMaint_Extension>();

        foreach (var location in locations)
        {
            graphExt.UpdateLocation(location, true);
        }
    }

    public ProcessCustomerLocations()
    {
        Locations.SetProcessDelegate(Process);
    }

}

А вот мой код на графике CustomerLocationMaint_Extension:

public class CustomerLocationMaint_Extension : PXGraphExtension<CustomerLocationMaint>
{
  public void UpdateLocation(Location location, bool isMassProcess = false)
    {
        bool isRes = false;

        Base.Location.Current = Base.Location.Search<Location.locationID>(location.LocationID, location.BAccountID);
        LocationExt locationExt = location.GetExtension<LocationExt>();

        // INSERT CODE TO DETERMINE VALUE OF isRes
        locationExt.UsrResidentialValidated = true;
        location.CResedential = isRes;

        Base.Location.Update(location);
        Base.Actions.PressSave();
    }
}

Одно из полей, которые яОбновление в Location - это настраиваемое поле с именем UsrResidentialValidated.Вот код для этого поля.

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

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

Обновление

Благодаря некоторой помощи @Samvel я изменил код UpdateLocation следующим образом.Следующий код сохраняет изменения в базе данных (как в настраиваемом, так и в нестандартном поле), и это здорово.Однако для этого мне пришлось создать новый объект Location «myLocation», и я больше не использую объект «location», который граф PXProcessing передал UpdateLocation.Это означает, что после обработки, когда на экране обработки отображаются обработанные записи с измененными данными (после завершения обработки и до обновления экрана), на нем не отображаются обновленные значения.Есть ли способ, чтобы на экране обработки отображались обновленные значения и сохранялись изменения в базе данных?

    public void UpdateLocation(PX.Objects.CR.Location location, bool isMassProcess = false)
    {
        bool isRes = true;

        Location myLocation = PXSelect<Location,
              Where<Location.bAccountID, Equal<Required<Location.bAccountID>>, And<Location.locationID, Equal<Required<Location.locationID>>>>>
              .Select(this.Base, location.BAccountID, location.LocationID);

        this.Base.Location.Current = myLocation;

        LocationExt locationExt = myLocation.GetExtension<LocationExt>();
        locationExt.UsrResidentialValidated = true;

        myLocation.CResedential = isRes;
        Base.Location.Current = Base.Location.Update(myLocation);

        this.Base.Save.Press();
    }

1 Ответ

1 голос
/ 08 июня 2019

ОБНОВЛЕНО

Я обновил код, чтобы он соответствовал вашему случаю.После обработки всех записей записи в сетке обновляются и показывают измененные записи.Вы можете скачать пакет настройки для этого кода по этой ссылке

Чтобы создать страницу обработки для обновления местоположения, вы должны выполнить следующие шаги:

  1. Добавьте поле «Выбранные» в расположение DAC

    public sealed class LocationExt: PXCacheExtension<Location>
    {
        #region Selected
        public abstract class selected : IBqlField
        { }
        [PXBool()]
        [PXDefault(true,PersistingCheck = PXPersistingCheck.Nothing)]
        [PXUIField(DisplayName = "Selected")]
        public bool? Selected { get; set; }
        #endregion
        #region UsrResidentialValidated
        [PXDBBool]
        [PXUIField(DisplayName = "Residential Validated")]
        public bool? UsrResidentialValidated { get; set; }
        public abstract class usrResidentialValidated : IBqlField { }
        #endregion
    }
    

    Этот шаг необходим, поскольку в противном случае ваш делегат для SetProcessDelegate никогда не будет вызван. Acumatica проверяет наличие хотя бы одной выбранной записи перед вызовом Process Delegate.

  2. Создайте график обработки, как показано ниже:

    using PX.Data;
    using PX.Objects.CR;
    using System.Collections.Generic;
    
    namespace CustomerLocationUpdate
    {
        public class ProcessCustomerLocations : PXGraph<ProcessCustomerLocations>
        {
            public PXCancel<Location> Cancel;
            public PXProcessingJoin<Location,InnerJoin<BAccountR,On<Location.bAccountID,Equal<BAccountR.bAccountID>>>, 
        Where<Location.isActive, Equal<True>,And<Location.locType, Equal<PX.Objects.CR.LocTypeList.customerLoc>>>> Locations;
    
            public static void Process(List<Location> locations)
            {
                var graph = PXGraph.CreateInstance<PX.Objects.AR.CustomerLocationMaint>();
                CustomerLocationMaint_Extension graphExt = graph.GetExtension<CustomerLocationMaint_Extension>();
    
                foreach (var location in locations)
                {
                    graphExt.UpdateLocation(location, true);
                    graph.Clear();
                }
            }
    
            public ProcessCustomerLocations()
            {
                Locations.SetProcessDelegate(Process);
            }
        }
    }   
    

    Как видите, я неявно указал PX.Objects.AR и PX.Objects.CR, по какой-то причине программа работала только так на моем экземпляре.

  3. Создайте метод UpdateLocation в GraphExtension:

    using PX.Data;
    
    namespace CustomerLocationUpdate
    {
        public class CustomerLocationMaint_Extension : PXGraphExtension<PX.Objects.AR.CustomerLocationMaint>
        {
            public void UpdateLocation(PX.Objects.CR.Location location, bool isMassProcess = false)
            {
                bool isRes = false;
                this.Base.Location.Current = PXSelect<PX.Objects.CR.Location,Where<PX.Objects.CR.Location.bAccountID,Equal<Required<PX.Objects.CR.Location.bAccountID>>,And<PX.Objects.CR.Location.locationID,Equal<Required<PX.Objects.CR.Location.locationID>>>>>.Select(this.Base,location.BAccountID,location.LocationID);
                this.Base.Location.Current.CResedential = isRes;
                LocationExt locationExt = PXCache<PX.Objects.CR.Location>.GetExtension<LocationExt>(this.Base.Location.Current);
                locationExt.UsrResidentialValidated = false;
                this.Base.Location.Current = this.Base.Location.Update(this.Base.Location.Current);
                this.Base.Save.Press();
            }
        }
    }
    

    Как видите, я устанавливаю Location.Current с помощью PXSelect, а не Location.Current.Search.По какой-то причине Location.Current.Search всегда возвращает ноль.Может быть, это вызвано приложенным к нему атрибутом PXProjectionAttribute, я не уверен, какова точная причина.

...