Acumatica - В другой процесс добавлена ​​/ обновлена ​​запись - Создание элементов инвентаризации с помощью DAC и расширений графиков - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь создать ежедневный процесс, который будет импортировать записи из другой базы данных как элементы инвентаризации.Для этого мне нужно создать расширение графа InventoryItemMaint (чтобы дать мне свое настраиваемое действие), а также расширение DAC InventoryItem (чтобы дать мне настраиваемое поле).Я пытался следовать инструкциям, изложенным специально в руководстве T-300, чтобы сделать это.

Вот код моего расширения InventoryItemMaint:

    namespace PX.Objects.IN
{

  public class InventoryItemMaint_Extension:PXGraphExtension<InventoryItemMaint>
  {

    public PXAction<PX.Objects.IN.InventoryItem> DailyOnixImport;

        [PXButton(CommitChanges = true)]
        [PXUIField(DisplayName = "Daily Onix Import")]
        protected void dailyOnixImport()
        {           
            var invItemMaintExtInstance = Base.GetExtension<InventoryItemMaint_Extension>();

            string todaysDate = DateTime.Today.ToString("MM/dd/yyyy");                        

            foreach (STOnixItem currentOnixItem in PXSelect<STOnixItem,
                        Where<STOnixItem.addedDate, Equal<Required<STOnixItem.addedDate>>>>
                        .Select(this.Base, todaysDate))
            {                                
                InventoryItem currentInventoryItem = invItemMaintExtInstance.Base.Item.Current;

                PXCache inventoryItemCache = invItemMaintExtInstance.Base.Item.Cache;
                InventoryItemExt inventoryItemExtension = inventoryItemCache.GetExtension<InventoryItemExt>(currentInventoryItem);

                inventoryItemCache.Clear();

                currentInventoryItem.InventoryCD = currentOnixItem.ISBN13;                

                currentInventoryItem.Descr = currentOnixItem.Title;
                currentInventoryItem.ItemClassID = currentOnixItem.ItemClass;
                currentInventoryItem.RecPrice = decimal.Parse(currentOnixItem.MSRP);
                currentInventoryItem.BasePrice = decimal.Parse(currentOnixItem.DefaultPrice);
                currentInventoryItem.BaseItemWeight = decimal.Parse(currentOnixItem.Weight);
                currentInventoryItem.WeightUOM = "POUND";
                currentInventoryItem.ImageUrl = currentOnixItem.ImageLink;

                //Assigning to the custom DAC Extension
                inventoryItemExtension.UsrFromOnixFile = currentOnixItem.FromFile;

                inventoryItemCache.Update(currentInventoryItem);
                Base.Actions.PressSave();

            }
        }
  }
}

В настоящее время я получаю ошибкучто гласит:

Ошибка: другой процесс обновил запись «InventoryItem».Ваши изменения будут потеряны.

А вот текст трассировки ошибок:

9/20/2018 15:26:05 PM Ошибка: ошибка: другой процесс имеетдобавили запись «InventoryItem».Ваши изменения будут потеряны.

в PX.Data.PXCache 1.PersistInserted(Object row) at PX.Data.PXCache 1.Persist (операция PXDBOperation) в PX.Data.PXGraph.Persist (Тип cacheType, операция PXDBOperation)
в PX.Data.PXGraph.Persist ()в PX.Objects.IN.InventoryItemMaint.Persist () в PX.Data.PXSave 1.d__2.MoveNext() at PX.Data.PXAction 1.d__31.MoveNext () в PX.Data.PXAction 1.d__31.MoveNext() at PX.Data.PXActionCollection.PressSave(PXAction caller) at PX.Objects.IN.InventoryItemMaint_Extension.dailyOnixImport() at PX.Data.PXAction 1. <> c__DisplayClass3_0. <. ctor> b__0 (PXAdapterадаптер) в PX.Data.PXAction 1.a(PXAdapter A_0) at PX.Data.PXAction 1.d__31.MoveNext () в PX.Data.PXAction`1.d__31.MoveNext () в PX.Web.UI.PXBaseDataSource.tryExecutePendingCommand (String viewName, String [] sortcolumns, Boolean [] по убыванию, поиск Object [], параметры Object [], фильтры PXFilterRow [], аргументы DataSourceSelectArguments, Boolean & closeWindowRequired, Int32 & adapterStartRow, Int32 & adapterTotalRows) в PX.Web.UI.PXBaseDataSource.ExecuteSelectguingsPXDSSelectArguments pxarguments)

Я много раз искал в StackOverflow и в других местах, но не нашел ответов, которые могли бы решить мою проблему. именно так.Сделанные мной твики привели к другим ошибкам, таким как различия в том, что я получаю сейчас (добавлен другой процесс против обновленного другого процесса) и ошибки MoveNext.

Если кто-нибудь сможет мне помочь, я будуочень признателен

1 Ответ

0 голосов
/ 21 сентября 2018

Кажется, в коде есть логический недостаток.Вы обновляете тот же текущий объект в цикле.Это не имеет смысла, поскольку оно всегда будет перезаписываться последним элементом, возвращаемым циклом.Вызов действия Save в цикле также может привести к ошибкам, если вы не будете осторожны.

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

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

Есть другие изменения, которые я бы порекомендовал.

Код:

// Consider replacing the default namespace to avoid conflicts
namespace MyNamespace
{
  public class InventoryItemMaint_Extension:PXGraphExtension<InventoryItemMaint>
  {
    public PXAction<PX.Objects.IN.InventoryItem> DailyOnixImport;

    // '(CommitChanges = true)' is not necessary
    [PXButton]
    [PXUIField(DisplayName = "Daily Onix Import")]
    protected void dailyOnixImport()
    {           
      InventoryItemMaint_Extension invItemMaintExtInstance = Base.GetExtension<InventoryItemMaint_Extension>();

      string todaysDate = DateTime.Today.ToString("MM/dd/yyyy");                        

      // You need to rethink that 'foreach' logic
      STOnixItem currentOnixItem in PXSelect<STOnixItem,
                                    Where<STOnixItem.addedDate, Equal<Required<STOnixItem.addedDate>>>>.Select(Base, todaysDate);    

      // You can access Base directly, no need to fetch it from the extension
      InventoryItem currentInventoryItem = Base.Item.Current;

      // Consider using more null check
      if (currentOnixItem != null && currentInventoryItem != null)
      {
        // Consider using similar names for similar variables
        InventoryItemExt currentInventoryItemExt = currentInventoryItem.GetExtension<InventoryItemExt>();

        // Avoid setting key related fields like InventoryCD when updating
        currentInventoryItem.Descr = currentOnixItem.Title;
        currentInventoryItem.ItemClassID = currentOnixItem.ItemClass;
        currentInventoryItem.RecPrice = decimal.Parse(currentOnixItem.MSRP);
        currentInventoryItem.BasePrice = decimal.Parse(currentOnixItem.DefaultPrice);
        currentInventoryItem.BaseItemWeight = decimal.Parse(currentOnixItem.Weight);
        currentInventoryItem.WeightUOM = "POUND";
        currentInventoryItem.ImageUrl = currentOnixItem.ImageLink;

        currentInventoryItemExt.UsrFromOnixFile = currentOnixItem.FromFile;

        // You fetched the item from the DataView 
        // you can update it in the DataView too.
        Base.Item.Update(currentInventoryItem);

        // Is it really needed to save here?
        // This coupled with cache clearing and the loop updating 
        // the same record triggers the error in your question.
        Base.Actions.PressSave();
      }
    }
  }
}
...