#acumatica
#acumatica
Вопрос:
У меня есть пользовательский график с несколькими сетками на разных вкладках. В каждой таблице есть столбец для номеров заказов на продажу, которые перенаправляют действия на график SOOrderEntry. Одна из сеток использует действие с этим кодом для поиска и вставки заказа на продажу в перенаправленный график, и это работает нормально:
SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();
graph.Document.Current = graph.Document.Search<SOOrder.orderNbr>(row.OrderNbr);
Однако использование того же кода в действии для другой сетки не работает. Пошаговое выполнение отладчика показывает, что
graph.Document.Search<SOOrder.orderNbr>(row.OrderNbr);
возвращает пустой результат.
Для каждого действия в источнике данных pages установлено значение DependOnGrid=true, для каждой сетки установлено значение SyncPosition=true. Даже при жестком кодировании порядкового номера строки в параметр поиска он возвращает пустой результат.
Обходной путь, который я нашел для работы, заключается в использовании
PXSelect<SOOrder>.Search<SOOrder.orderNbr, SOOrder.orderType>(graph, row.OrderNbr, row.OrderType);
в действиях, которые не работают.
Кто-нибудь сталкивался с этим или, может быть, имеет некоторое представление о том, что здесь происходит? Мне странно, что очень похожие действия перенаправления в одном и том же графике требуют другого кода для правильной работы.
Редактировать: добавление определений представления
Это представление, которое использует действие с поиском для поиска нужного документа.
public PXSelectReadonly2<
SOOrder,
InnerJoin<BAccount,
On<SOOrder.customerID, Equal<BAccount.bAccountID>>,
LeftJoin<STSalesTerritory,
On<BAccountExt.usrTerritoryID, Equal<STSalesTerritory.territoryID>>>>,
Where2<
Where<SOOrder.orderType, Equal<SOOrderTypeConstants.salesOrder>,
And<SOOrder.status, NotEqual<SOOrderStatus.completed>,
And<SOOrder.status, NotEqual<SOOrderStatus.invoiced>,
And<SOOrder.status, NotEqual<SOOrderStatus.cancelled>>>>>,
And<
Where2<
Where<Current<STSalesTerritoryInqFilter.ownerID>, IsNotNull,
And<Current<STSalesTerritoryInqFilter.territoryID>, IsNull,
And<Current<STSalesTerritoryInqFilter.repID>, IsNull,
And<BAccountExt.usrTerritoryID, IsNull,
And<SOOrder.ownerID, Equal<Current<STSalesTerritoryInqFilter.ownerID>>>>>>>,
Or<
Where2<
Where<Current<STSalesTerritoryInqFilter.ownerID>, IsNotNull,
Or<Current<STSalesTerritoryInqFilter.territoryID>, IsNotNull,
Or<Current<STSalesTerritoryInqFilter.repID>, IsNotNull>>>,
And<
Where2<
Where<Current<STSalesTerritoryInqFilter.ownerID>, IsNull,
Or<STSalesTerritory.ownerID, Equal<Current<STSalesTerritoryInqFilter.ownerID>>>>,
And<
Where2<
Where<Current<STSalesTerritoryInqFilter.territoryID>, IsNull,
Or<STSalesTerritory.territoryID, Equal<Current<STSalesTerritoryInqFilter.territoryID>>>>,
And<Where<Current<STSalesTerritoryInqFilter.repID>, IsNull,
Or<STSalesTerritory.repID, Equal<Current<STSalesTerritoryInqFilter.repID>>>>>>>>>>>>>>>
OpenSOOrders;
И это представление с действием, в котором поиск не работает, и для поиска нужного документа требуется PXSelect
public PXSelectJoinGroupBy<
Customer,
InnerJoin<Address,
On<Customer.defAddressID, Equal<Address.addressID>>,
InnerJoin<SOOrder,
On<Customer.bAccountID, Equal<SOOrder.customerID>>,
InnerJoin<BAccount,
On<Customer.bAccountID, Equal<BAccount.bAccountID>>,
InnerJoin<STSalesTerritory,
On<BAccountExt.usrTerritoryID, Equal<STSalesTerritory.territoryID>>>
>>>,
Where2<
Where<SOOrder.orderDate, GreaterEqual<Current<STSalesTerritoryInqDateFilter.startDate>>,
And<SOOrder.orderDate, LessEqual<Current<STSalesTerritoryInqDateFilter.endDate>>>>,
And<
Where2<
Where<SOOrder.orderType, Equal<SOOrderTypeConstants.salesOrder>,
Or<SOOrder.orderType, Equal<SOOrderTypeConstantsExt.websiteOrder>>>,
And<
Where2<
Where<SOOrder.status, NotEqual<SOOrderStatus.hold>,
And<SOOrder.status, NotEqual<SOOrderStatus.cancelled>,
And<SOOrder.status, NotEqual<SOOrderStatus.voided>,
And<Customer.customerClassID, NotEqual<marketplaceCustomerClassID>
>>>>,
And<
Where2<
Where<Current<STSalesTerritoryInqFilter.territoryID>, IsNull,
Or<BAccountExt.usrTerritoryID, Equal<Current<STSalesTerritoryInqFilter.territoryID>>>>,
And<Where<Current<STSalesTerritoryInqFilter.ownerID>, IsNull,
Or<STSalesTerritory.ownerID, Equal<Current<STSalesTerritoryInqFilter.ownerID>>>>>>>>>>>>,
Aggregate<
GroupBy<Customer.acctCD>>,
OrderBy<SOOrder.orderDate.Desc>>
NewCustomers;
Комментарии:
1. Можете ли вы показать, как определяются ваши представления?
2. @BrianStevens Я добавил определения представлений
Ответ №1:
Я не уверен, что достаточно понимаю, что вы делаете, чтобы иметь возможность помочь, но я постараюсь.
Первичным ключом SOOrder является CompanyID, OrderType, OrderNbr — это означает, что вы должны искать SOOrder по OrderType и OrderNbr. Вы сделали это в «обходном пути», но не с первой попытки.
Если ваши сетки возвращают значения, и вам просто нужно сделать поле Order Nbr доступной для просмотра ссылкой на экран SOOrderEntry, добавьте поле в представление (в редакторе экрана) в разделе «Уровни» сетки, а затем отметьте поле ordern br как AllowEdit = true, чтобы сделать его доступным для просмотра. Предполагая, что вы показываете ORDERBR в таблице из таблицы SOOrder, SOOrder DAC определяет основной график SOOrder как SOOrderEntry и будет знать, как перенаправить его для вас.
Если вам действительно нужно извлечь текущий SOOrder из представления OpenSOOrders, чтобы вручную перенаправить на заказ, вы получаете доступ к «Текущему SOOrder» из представления (что стало возможным благодаря настройке сетки «SyncPosition = true») через OpenSOOrders.Current . Например, вы можете найти текущий SOOrder, создать экземпляр графика SOOrderEntry и задать текущий SOOrder (документ) следующим образом:
SOOrder order = OpenSOOrders.Current;
SOOrderEntry graph = PXGraph.CreateInstance<SOOrderEntry>();
graph.Document.Current = order;
Это должно сработать, потому что order — это точная запись в базе данных. Для поиска только по типу и номеру заказа вы бы использовали:
graph.Document.Current = graph.Document.Search<SOOrder.orderType, SOOrder.orderNbr>
(order.OrderType, order.OrderNbr);
Для полноты картины, если SOOrder обновлялся в переопределяемом вами методе, вы бы использовали Locate вместо Search . Поиск найдет запись в базе данных, но Locate найдет ее в кэше. Это означает, что если метод обновил значения, вы получите эти обновления, а не удалите их с помощью новой копии записи, которую извлек бы поиск. Locate использует ключевые поля указанной записи для поиска записи в кэше, как показано ниже.
graph.Document.Current = graph.Document.Locate(order);
Что касается представления, которое не находит для вас текущую запись, кажется, вы агрегируете по клиенту. Я не часто использую aggregate, но я полагаю, что это означает, что результаты будут возвращены в обобщенном виде клиентом. Если имеется более 1 значения OrderNbr, оно не может быть показано в совокупности. Поскольку второе представление агрегируется по клиенту, вам нужно будет разрешить пользователю выбирать заказы клиента и использовать текущие из ЭТОГО представления.
Если вы хотите, чтобы ваш агрегат был в 1 сетке и отображал просмотр заказов выбранного клиента, вы должны добавить новое представление (и дополнительную сетку) для заказа следующим образом:
public PXSelect<SOOrder,
Where<SOOrder.customerID, Equals<Current<Customer.bAccountID>>>> CustomerOrders;
Просто чтобы вставить плагин для FBQL, вы могли бы написать это как:
public SelectFrom<SOOrder>
.Where<SOOrder.customerID.IsEqual<Customer.bAccountID.FromCurrent>>
.View CustomerOrders;
Синхронизация для новых клиентов должна приводить к обновлению CustomerOrders при изменении строк новых клиентов. Опять же, в этом представлении я бы сделал поле OrderNbr SOOrder доступной для просмотра ссылкой, используя AllowEdit = true .
Ответ №2:
Я сталкивался со сценариями на страницах с 2 первичными ключами, где поиск <> вызывается следующим образом:
graph.Document.Search<SOOrder.orderNbr>(row.OrderNbr, row.OrderType);
В исходном коде Acumatica есть несколько ссылок. Хороший пример можно найти в SOInvoiceEntry graph >> Метод RecallUnbilledTax():
soOrderEntry.Document.Current = soOrderEntry.Document.Search<SOOrder.orderNbr>(order.SOOrderNbr, order.SOOrderType);
Ответ №3:
Ваше второе представление содержит агрегированный выбор, сгруппированный по клиенту.AcctCD. Для одного и того же клиента у вас может быть несколько заказов: какой из них следует отобразить и открыть? По умолчанию Acumatica генерирует SQL с максимальным значением для неопределенных столбцов. Я бы попытался удалить агрегацию из представления и посмотреть, работает ли она.