08.11.2019, 03:36 | #1 |
Участник
|
D365FO salesTable.PackedExtensions для MCRSalesTable
D365FO 10.0.4 PU28. Call Center.
Проблема в том, что у клиента после неполной разноске накладной (когда остаются товары для следующей доставки), накладная стопается и кнопка "Complete" снова становится активной. Полностью аналогичный случай на моей ВМ работает как надо и кнопка Complete не появляется. Оказалось, что после создания накладной и добавления платежей при выполнении submit для накладной при очередном Salestable.update() происходит создание записи в MCRSalesTable c обновлением поля OutOfBalanceReleased - на моей ВМ. У клиента MCRSalesTable не создается. Дальнейшее вскрытие показало что в ВМ клиента в SysExtensionSerializerMap.postUpdate() не создается запись в MCRSalesTable потому что this.PackedExtensions == conNull() - см. рисунок внизу. Компиляция AppSuite модуля и DBsync не помогли. Что делать дальше - пока не знаю. Буду рада любым предположениям. |
|
08.11.2019, 10:01 | #2 |
Участник
|
Я бы попытался понять соответствует ли текущий код идеям framework-а (может где-то что-то нарушили):
краткая инструкция как должно быть https://daxonline.org/9-table-extension-framework.html Обратил внимание на packExtensionTable и подобные вещи. Последний раз редактировалось axm2017; 08.11.2019 в 10:05. |
|
08.11.2019, 16:58 | #3 |
Участник
|
Дык все таблицы стандартные. Pack идет в salestable.mcrPackMCRSalesTable() (по крайней мере дебаггер туда заходит)
|
|
08.11.2019, 20:01 | #4 |
Участник
|
|
|
11.11.2019, 19:38 | #5 |
Участник
|
на ВМ где все работает как надо, запись в MCRSalesTable создается когда пользователь нажимает кнопку Submit (это MCRSalesOrderRecap.SubmitOrder()). Call stack с ВМ где запись создается - на скриншоте внизу.
MCRSalesTable.Insert() делается на Salestable.update(): X++: public class SysExtensionSerializerMap extends common { /* .................... */ /// <summary> /// Updates / inserts the packed extension table record after the base table record is updated. /// </summary> /// <remarks> /// This method should be called immediately after super() of base table's <C>update</C> method. /// </remarks> public void postUpdate() { SysExtensionSerializerExtensionMap currentExtensionTable; SysExtensionSerializerExtensionMap extensionTableToUpdate; SysExtensionSerializerExtensionMap extensionTableInUse; int i; boolean checkForLinkedExtensionTables; container newPackedExtensions; boolean updated; Array extensionTableArray = new Array(Types::Record); container extensionTableTableIdList; TableId currentExtensionTableTableId; container hasLinkedExtensionTableCon; boolean hasLinkedExtensionTable; if (this.RecId && this.PackedExtensions != conNull()) { for (i = 1; i <= conLen(this.PackedExtensions); i++) { currentExtensionTable = con2Buf(conPeek(this.PackedExtensions, i)); extensionTableArray.value(i, currentExtensionTable); currentExtensionTableTableId = currentExtensionTable.TableId; // if buffer is not form DS there is no need to check for extension table on client checkForLinkedExtensionTables = checkForLinkedExtensionTables || FormDataUtil::isFormDataSource(this); extensionTableTableIdList += [currentExtensionTableTableId]; } if (checkForLinkedExtensionTables) { hasLinkedExtensionTableCon = SysExtensionSerializerFormRunHelper::hasExtensionTable(this, extensionTableTableIdList); } ttsbegin; for (i = 1; i <= extensionTableArray.lastIndex(); i++) { updated = false; currentExtensionTable = extensionTableArray.value(i); /* ............................ */ // If it is not an existed record, insert it. if (updated == false) { currentExtensionTable.BaseRecId = this.RecId; currentExtensionTable.insert(); //<<----------------------------- } newPackedExtensions += [buf2Con(currentExtensionTable, true)]; } ttscommit; this.PackedExtensions = newPackedExtensions; } } |
|
11.11.2019, 20:41 | #6 |
Участник
|
Проблема же не в добавлении записи, а в том что PackedExtensions пустой. Заполняется это поле имхо не на update.
|
|
11.11.2019, 23:05 | #7 |
Участник
|
насколько я вижу, заполняется поле тут (в дебаггере вижу что таки заполняется):
X++: class MCRPaymentReview { /*...................................*/ public static boolean outOfBalance(MCRCustPaymTotals _mcrCustPaymTotals, AmountCur _overUnderPaymAmount = 0, AmountCur _totalSalesAmount = 0) { /*.....................................*/ else { // Update back status gets called from so many places that a new // enum value was added so that only end order can put a // sales order on out of balance "hold". // So once end order validates that this is not out of balance // make sure that it doesn't happen again unless the order // is modified. mcrSalesTable.OutOfBalanceReleased = MCROutOfBalanceReleaseType::Verified; } ttsBegin; if (salesTable.validateWrite()) { salesTable.mcrPackMCRSalesTable(mcrSalesTable); //<<---------------------------- salesTable.update(); } else { throw error("@SYS104318"); } ttsCommit; return isValid; X++: public class SalesTable extends common { /*....................................*/ /// <summary> /// Packs the retail sales table extension table into <c>MCRSalesTable</c> field. /// </summary> /// <param name="_mcrSalesTable"> /// Extension table to be packed. /// </param> public void mcrPackMCRSalesTable(MCRSalesTable _mcrSalesTable) { _mcrSalesTable.SalesTable = this.RecId; this.SysExtensionSerializerMap::packExtensionTable(_mcrSalesTable); } |
|
12.11.2019, 12:44 | #8 |
Участник
|
Судя по коду которые есть у меня выполнение этого кода привязано к вот такой проверке
X++: public boolean mcrIsCallCenter() { if (MCROrderParameters::isCallCenterEnabledAndInUse()) { return RetailMCRChannelTable::findRecId(RetailSalesTable::findSalesTable(this).RetailChannel).RecId != 0; } else { return false; } } Возможно вы их выполняете а вот клиент хз |
|
Теги |
mcrsalestable, packedextensions, sysextensionserializermap |
|
|