|
![]() |
#1 |
Участник
|
Raven, а расскажите плз, как именно вы исправляли эту ошибку. Передачей true при втором вызове метода interCompanyParmLineQty?
И, если будет время, было бы здорово привести сценарий, с помощью которого можно воспроизвести это поведение в стандартном функционале. Спасибо Последний раз редактировалось kashperuk; 21.08.2009 в 13:07. |
|
|
За это сообщение автора поблагодарили: Raven Melancholic (4). |
![]() |
#2 |
Участник
|
Лично я исправлял как Вы сказали:
Цитата:
Передачей true при втором вызове метода interCompanyParmLineQty
создать цепочку заказов (внутрихолд заказ продажи - внутрихолд заказ покупки - исходный заказ) типа прямая поставка. И разнести ее. |
|
|
За это сообщение автора поблагодарили: Raven Melancholic (2). |
![]() |
#3 |
Участник
|
Тогда уже исправили. Спасибо
|
|
|
За это сообщение автора поблагодарили: mazzy (2). |
![]() |
#4 |
Участник
|
Ну тогда, позвольте я еще про одну ошибку изложу. Скажу сразу, что толком не помню как ее воспроизвести (давненько это было). Кроется она в классе IntercompanyTransferInventDim метод transfer:
X++: ... while (qr.next()) { fromInventTrans = qr.get(tablenum(InventTrans)); fromInventDim = qr.get(tablenum(InventDim)); ... fromQty = -fromInventTrans.Qty; if (inventDimParm.InventLocationIdFlag && fromInventDim.InventLocationId) { convInventLocation = new TradeInterCompanyConv(); salesInventLocationId = fromInventDim.InventLocationId; convInventLocation.axInventLocationId(fromValueMap, fromInventDim.InventLocationId); } ... changecompany(_toDataAreaId) { toInventTrans = null; select forceplaceholders sum(Qty) from toInventTrans where toInventTrans.InventTransId == _toInventTransId && (toInventTrans.StatusReceipt <= StatusReceipt::Registered || toInventTrans.InterCompanyInventDimTransferred == true) && toInventTrans.StatusIssue == StatusIssue::None #inventDimJoin(toInventTrans.InventDimId,toInventDim,fromInventDim,inventDimParm); fromQty -= toInventTrans.Qty; .... P.S.: надеюсь понятно пояснил, как-то сумбурно получилось, млин |
|
![]() |
#5 |
Участник
|
Забыл добавить: DAX 4.0 SP2
|
|
![]() |
#6 |
Участник
|
Ошибка проявляется в именно так, как описал JeS.
Ой, насчет: Цитата:
Кроется она в классе IntercompanyTransferInventDim метод transfer
Он неправильно отрабатывает в случаях, когда были кредит-ноты по строке, лечилось добавлением в выборки (те, которые зависят от того, какие аналитики включены) условий (то, что выделено комментариями): Код: select forceplaceholders sum(Qty) from fromInventTrans where fromInventTrans.InventTransId == _fromInventTransId && fromInventTrans.StatusIssue <= _statusIssue && fromInventTrans.StatusReceipt == StatusReceipt::None // ААК: МФД40_09_01_0013_001 11.07.2009 [Сторнирование и копирование документов] --> && fromInventTrans.InvoiceReturned == NoYes::No && fromInventTrans.PackingSlipReturned == NoYes::No // ААК: МФД40_09_01_0013_001 11.07.2009 [Сторнирование и копирование документов] <-- join InventLocationId, InventBatchId, InventSerialId, InventGtdId_RU from fromInventDim group by InventLocationId, InventBatchId, InventSerialId, InventGtdId_RU where fromInventDim.InventDimId == fromInventTrans.InventDimId; X++: select forupdate toInventTrans index hint TransIdIdx where toInventTrans.InventTransId == _toInventTransId && toInventTrans.StatusReceipt == StatusReceipt::Ordered && toInventTrans.StatusIssue == StatusIssue::None && toInventTrans.InterCompanyInventDimTransferred == false; Для воспроизведения этой ошибки нужно чтобы проводки по лоту были расщеплены как со стороны заказа на продажу, так и со стороны заказа на покупку. Причем, иногда везет и комплектуются те записи, по которым установили флаг, но везение не всегда случается. Эту проблему решили, но грубо (стояли отгрузки, поэтому было не до изящности): вместо X++: inventTransUpd.InterCompanyInventDimTransferred = true; X++: //lex 24.04.2009 при регистрации могла выбраться еще необработанная проводка и на пересечении...--> if (!_registerReceipt) { inventTransUpd.InterCompanyInventDimTransferred = true; } //lex 24.04.2009 при регистрации могла выбраться еще необработанная проводка и на пересечении...<-- X++: //lex 24.04.2009 при регистрации могла выбраться еще необработанная проводка и на пересечении...--> update_recordset refInventTrans setting InterCompanyInventDimTransferred = true where refInventTrans.InventTransId == inventTransUpd.InventTransId && refInventTrans.StatusReceipt == StatusReceipt::Registered && !refInventTrans.InterCompanyInventDimTransferred; //lex 24.04.2009 при регистрации могла выбраться еще необработанная проводка и на пересечении...<-- |
|
|
За это сообщение автора поблагодарили: JeS (1). |
![]() |
#7 |
Участник
|
Еще один недостаток этого метода. Бывает, что в компании, в которой производится продажа конечному клиенту, требуются данные не только номера партии, а и то, что есть в таблице партий (например, дата производства, если существует контроль и предоставление клиенту информации о сроках годности), тоже может требоваться по серийным номерам и, естественно, нужна страна по ГТД. Однако, в методе создаются записи только с номером:
X++: if (!InventBatch::exist(toInventTrans.ItemId,inventDimUpd.InventBatchId))
{
inventBatch.clear();
inventBatch.ItemId = toInventTrans.ItemId;
inventBatch.InventBatchId = inventDimUpd.InventBatchId;
inventBatch.insert();
} X++: while (fromInventTrans) { // ААК: МФД40_08_01_0003 19.03.2009 [Планирование сделок] --> inventBatchFrom = null; if (fromInventDim.inventBatchId) { inventBatchFrom = InventBatch::find(fromInventDim.inventBatchId, itemIdFrom); } ... X++: if (!InventBatch::exist(toInventTrans.ItemId,inventDimUpd.InventBatchId)) { inventBatch.clear(); inventBatch.ItemId = toInventTrans.ItemId; inventBatch.InventBatchId = inventDimUpd.InventBatchId; // ААК: МФД40_08_01_0003 19.03.2009 [Планирование сделок] --> inventBatch.initFromInventBatch_OVK(inventBatchFrom); // ААК: МФД40_08_01_0003 19.03.2009 [Планирование сделок] <-- inventBatch.insert(); } |
|
![]() |
#8 |
Участник
|
Цитата:
Поэтому лучше получить данные методом interCompanyParmLineQty для единиц закупки/продажи и приводить к складским уже в компании-покупателе. |
|
![]() |
#9 |
Участник
|
В предыдущем сообщении, где приводил пример кода, я допустил ошибку. Исправляюсь. Код в базовой функциональности должен выглядеть так:
X++: while (fromInventTrans) { ... fromQty = -fromInventTrans.Qty; if (inventDimParm.InventLocationIdFlag && fromInventDim.InventLocationId) { convInventLocation = new TradeInterCompanyConv(); salesInventLocationId = fromInventDim.InventLocationId; convInventLocation.axInventLocationId(fromValueMap, fromInventDim.InventLocationId); } ... changecompany(_toDataAreaId) { toInventTrans = null; select forceplaceholders sum(Qty) from toInventTrans where toInventTrans.InventTransId == _toInventTransId && (toInventTrans.StatusReceipt <= StatusReceipt::Registered || toInventTrans.InterCompanyInventDimTransferred == true) && toInventTrans.StatusIssue == StatusIssue::None #inventDimJoin(toInventTrans.InventDimId,toInventDim,fromInventDim,inventDimParm); fromQty -= toInventTrans.Qty; .... Кстати непонятно зачем нужно было писать такую "этажерку" в этом методе до вышеописанного цикла: X++: if (inventDimParm.InventLocationIdFlag && inventDimParm.InventBatchIdFlag && inventDimParm.InventSerialIdFlag) { select forceplaceholders sum(Qty) from fromInventTrans where fromInventTrans.InventTransId == _fromInventTransId && fromInventTrans.StatusIssue <= _statusIssue && fromInventTrans.StatusReceipt == StatusReceipt::None join InventLocationId, InventBatchId, InventSerialId from fromInventDim group by InventLocationId, InventBatchId, InventSerialId where fromInventDim.InventDimId == fromInventTrans.InventDimId; } else if (inventDimParm.InventLocationIdFlag && inventDimParm.InventBatchIdFlag) { select forceplaceholders sum(Qty) from fromInventTrans where fromInventTrans.InventTransId == _fromInventTransId && fromInventTrans.StatusIssue <= _statusIssue && fromInventTrans.StatusReceipt == StatusReceipt::None join InventLocationId, InventBatchId from fromInventDim group by InventLocationId, InventBatchId where fromInventDim.InventDimId == fromInventTrans.InventDimId; } else if (inventDimParm.InventLocationIdFlag && inventDimParm.InventSerialIdFlag) { ... |
|
![]() |
#10 |
Участник
|
to Raven
Цитата:
К сожалению это не одна ошибка в этом методе
Цитата:
даже если отбросить тот факт, что про ГТД в этом методе ничего нет
|
|
![]() |
#11 |
Участник
|
Еще наткнулись. Ка-то странно работает кэш (я про это уже писал, но тогда было только тестирование и как-то не зациклились на этой теме).
У нас в разных компаниях номенклатура ведет себя по разному (например, в производственной это спецификация с номенклатурной группой "Готовая продукция", в торговых домах это номенклатура с номенклатурной группой Товар, ну и т.п.). Поэтому справочник не общий, а в каждой компании свой (есть доработка по вводу и синхронизации определенных номенклатур, но суть не в этом). Так вот, простой код джоба: X++: itemId = 'ВентиляторWRW50/40'; intentTable = InventTable::find(itemId); changeCompany('TRD') { inventTableChg = null; select firstOnly inventTableChg where inventTableChg == itemId; ... } То же происходит если в разных компаниях номера складских лотов совпадают. Если после переключения компании искать складские операции по номеру лота, совпадающему с тем, что был выполнен ранее, то вернется ранее найденный лот. Помогает включения в код запрет кэша: X++: itemId = 'ВентиляторWRW50/40'; intentTable = InventTable::find(itemId); changeCompany('TRD') { inventTableChg = null; inventTableChg.disableCash(true); select firstOnly inventTableChg where inventTableChg == itemId; ... } Такое впечатление, то кэш игнорирует компании. вобщем-то можно было бы отключить кэш DAX для всех таблиц (кэш MS SQL хорошо справляется со своей работой), но InventTrans не кэшируется DAX! Так же понятно, что из-за этой проблемы следует стараться иметь для одних и тех же таблиц в разных компаниях разные уникальные идентификаторы. Но, в нашем случае, это возможно для InventTrans, но не интересно для InvntTable. Можно всегда добавлять disableCach, но в наших разработках мы так и делаем, но есть стандартный код! PS: кстати, без использования disableCash Trasert MS SQL показывает, что к базе данных было только оно обращение, то есть цепочка: поиск в одной компании, changeCompany, поиск в другой компании того же значения обрабатывает DAx независимо от типа кэширования. Последний раз редактировалось Raven Melancholic; 29.08.2009 в 21:16. |
|
|
За это сообщение автора поблагодарили: JeS (1), Kabardian (3). |
![]() |
#12 |
Участник
|
Еще один момент. Правда это не ошибка, но непонятка.
В SalesLine и PurchLine для механизма Интеркомпани есть поле InterCompanyInventTransId по которому связаны строки заказа на покупки и заказа на продажу Интеркомпани. Но в классах, наследниках от TradeInterCompany поиск связанной строки почему-то происходит не по этим лотам, а по номерам строк. Я, конечно, понимаю, что индекс, включающий номер строки является кластерным и когда требуется получить все данные строки он работает быстро (тем более, что в интерфейсе поле LineNum не представлено, а в методах InteCompanyMirror оно синхронизируется). Но, все-таки, во всех остальных местах связь идет по полю InterCompanyInventTransId, к тому же, индекс, включающий LineNumне уникальный, что позволяет при работе не из интерфейса, а из кода дублировать номера строк (кстати, в стандартном приложении бывает, что номер строки несколько раз бывает нулевым, правда это относится не к заказам на покупку-продажу, а складским журналам и журналам ГК). Почему для классов, наследников TradeInterCompany сделано исключение из общего правила? |
|