|
14.02.2011, 12:43 | #1 |
Участник
|
Проблемы при закрытии склада DAX2009 SP1 RU5/RU6
Решил поделиться проблемами и решениями, которые возникли при закрытии склада. Большая часть проблем связана с расширенным расчетом производственной себестоимости, который был добавлен RU5.
ПРОБЛЕМА 1: Неверная себестоимость расходов при расширенном расчете себестоимости. Основная логика по закрытию склада находится в классе InventCostItemDim. В методе updateItem вызывается updateLevelAdjustment() в котором коррекции, которые «прилетели» на данную номенклатуру с предыдущих шагов, распределяются на приходные проводки этой номенклатуры. X++: while select sum(Adjustment) from inventCostListTrans index hint ItemIdx group by InventTransId,InventTransIdReturn,VoucherPhysical where inventCostListTrans.Voucher == inventClosing.Voucher && inventCostListTrans.NumOfIteration == inventCostList.NumOfIteration && inventCostListTrans.ItemId == inventCostList.ItemId { // <GEEU> if (calculationProdWIP_RU && inventCostListTrans.InventTransId && this.calcWIPProdHistoricalCost_RU(inventCostListTrans.InventTransId, inventCostListTrans.VoucherPhysical)) { continue; } // </GEEU> this.updateTransIdReceipt(inventCostListTrans.InventTransId, inventCostListTrans.Adjustment, inventCostListTrans.InventTransIdReturn, inventCostListTrans.VoucherPhysical); } Если включен расширенный расчет себестоимости и приходная проводка имеет тип «Производство», то вызывается метод calcWIPProdHistoricalCost (), в нем вызывается написанная в RU5 логика, рассчитывается фактическая себестоимость расходов по производственному заказу, себестоимость выходов (побочной и основной продукции), делается коррекция приходов. Так вот, первая проблема связана с тем, что наши локализаторы забыли для основного выхода сделать вставку в вышеупомянутый mapInventTrans и все коррекции, которые были добавлены к приходам, не распространялись на расходы. РЕШЕНИЕ Нужно в конце метода ProdCalculatingWIPEngine_RU:: createAdjustSettlement() вызвать inventCostItemDim.updateInventTrans(_inventTrans): X++: //+ DPL InventClosingFix_OK 11.02.2011 OK if (inventCostItemDim != null) { inventCostItemDim.updateInventTrans(_inventTrans); } else //- DPL InventClosingFix_OK 11.02.2011 OK _inventTrans.update(); } X++: //+ DPL InventClosingFix_OK 11.02.2011 OK //protected void updateInventTrans(InventTrans _inventTrans) public void updateInventTrans(InventTrans _inventTrans) //- DPL InventClosingFix_OK 11.02.2011 OK ... |
|
|
За это сообщение автора поблагодарили: fed (30), Logger (15), madm (1), zhan (2), imir (1). |
14.02.2011, 12:47 | #2 |
Участник
|
ПРОБЛЕМА 2. Неверная себестоимость расходов по побочной продукции.
Эта проблема очень похожа на предыдущую, но причина немного в другом. Рассмотрим на примере. Вся логика выполняется на 0-й итерации. Есть продукция «какао-масло» и побочная «жмых», в расход идет «какао-тертое». На предыдущих шагах закрытия склада были сделаны коррекции «какао-тертого», то есть изменилась себестоимость расхода. Эта коррекция попала в таблицу inventCostListTrans, чтобы система переоценила стоимость связанных выходов «какао-масла» и «какао-тертого». Далее система доходит до расчета «какао-масла», запускает расчет RU5, рассчитывается стоимость выхода основной и побочной продукции. Для побочной продукции локализаторы , в отличие от проблемы №1 сделали правильно – вызвали из своей логики метод updateTransIdReceipt(), который отразил коррекцию на приходе побочной продукции и добавил проводку в mapInventTrans, чтобы «распространить» коррекцию на сопоставленные расходные проводки. Все бы было хорошо, если бы это не было 0-й итерации и самым первым расчетом для «какао-масла». На нулевой итерации в методе InventCostItemDim:: updateItem() запускается сопоставление по модели: X++:
se = setInventDim.getEnumerator();
while (se.moveNext())
{
inventDim = se.current();
this.initMapInventTrans();
this.load(inventDim);
this.updateReceiptAdjustment();
this.updateModel(inventDim);
} РЕШЕНИЕ В методе InventCostItemDim:: updateItem() перед циклом сопоставления нужно вызвать updateReceiptAdjustment(): X++: else { // if this is not a closing, or if this is the first time, then match .. // first match issues and receipts that are marked this.updateSettleRefItem(inventCostList.ItemId); //+ DPL InventClosingFix_OK 12.02.2011 OK //если здесь не вызвать этот метод-не идут дальше коррекции по побочной продукции if (calculationProdWIP_RU) this.updateReceiptAdjustment(); //- DPL InventClosingFix_OK 12.02.2011 OK // then match remaining issues and receipts according to inventory model if (! isServiceItem) { setInventDim = new Set(Types::Record); // find all financial dimension combinations queryRun = inventCostHelp.initQueryRunTrans(this.inventTable(inventCostList.ItemId), this.inventModelGroup(inventCostList.ItemId)); while (queryRun.next()) { inventDim = queryRun.get(tablenum(InventDim)); setInventDim.add(inventDim); } // match issues and receipts per financial dimension combination se = setInventDim.getEnumerator(); while (se.moveNext()) { inventDim = se.current(); this.initMapInventTrans(); this.load(inventDim); this.updateReceiptAdjustment(); this.updateModel(inventDim); } setInventDim = null; } } |
|
14.02.2011, 12:49 | #3 |
Участник
|
ПРОБЛЕМА 3. Все коррекции, сделанные по приходным проводкам с типом «Производство» при помощи коррекции проводок в форме «Закрытие и коррекция» отменяются!
При расширенном расчете себестоимости, который запускается из InventCostItemDim ::calcWIPProdHistoricalCost_RU после расчета стоимости основного выхода, себестоимость этого выхода корректируется в ProdCalculatingWIPEngine_RU ::createProdReceiptAdjust по формуле [коррекция] = [рассчитанная стоимость] – [текущая стоимость]. Таким образом, если вы перед закрытием распределили затраты на приходы из производства, то эти суммы будут успешно отменены и себестоимость выходов будет равна себестоимости расходов по производственному заказу. РЕШЕНИЕ На таблице InventTrans создайте метод: X++: // DPL InventClosingFix_OK 13.02.2011 OK //расчет суммы коррекций добавленной распределением затрат Amount calcManualCorrAmount_OK() { InventSettlement invSettlement; InventClosing inventClosing; ; select sum(CostAmountAdjustment) from invSettlement where invSettlement.Cancelled == NoYes::No && invSettlement.TransRecId == this.RecId exists join inventClosing where inventClosing.Voucher == invSettlement.Voucher && inventClosing.AdjustmentType == InventAdjustmentType::Transaction; return invSettlement.CostAmountAdjustment; } X++: //+ DPL InventClosingFix_OK 13.02.2011 OK //отнимаем чтобы не отсторнировать распределение затрат costAmount -= inventTrans.calcManualCorrAmount_OK(); //- DPL InventClosingFix_OK 13.02.2011 OK ProdWIPHistoricalCostTable_RU::createProductionRecord(prodTable.ProdId, |
|
14.02.2011, 12:51 | #4 |
Участник
|
ПРОБЛЕМА 4 . Есть проблемы с производительностью при расширенном расчете себестоимости.
Есть неоптимальные запросы, которые вызываются из логики, добавленной в RU5. РЕШЕНИЕ. Рекомендую добавить следующие индексы: 1. На таблице InventTrans по полям InventTransIdFather,DateFinancial. 2. На таблице InventTrans по полям TransRefId, TransType, DatePhysical. 3. На таблице ProdWIPHistoricalCostTable_RU по полю ReleaseRefRecId. 4. На таблице InventByProductTable_RU включить индекс на RecId. |
|
|
За это сообщение автора поблагодарили: Poleax (3). |
14.02.2011, 12:52 | #5 |
Участник
|
ПРОБЛЕМА 5 . Не работает отмена закрытия или пересчета в пакетном режиме, если есть выделенный пакетный сервер.
Если делать отмену закрытия в пакетном режиме и указывать пакетную группу, система создает первую задачу с указанной пакетной группой, а все остальные, от которых зависит первая создает с пустой пакетной группой. Если на эту пустую группу не настроен ни один АОС, то она никогда не завершится. РЕШЕНИЕ. Если без доработок, то нужно добавить пустую пакетную группу к какому-либо серверу. |
|
|
За это сообщение автора поблагодарили: b_nosoff (1). |
14.02.2011, 13:12 | #6 |
Moderator
|
Цитата:
Сообщение от Bega
ПРОБЛЕМА 5 . Не работает отмена закрытия или пересчета в пакетном режиме, если есть выделенный пакетный сервер.
Если делать отмену закрытия в пакетном режиме и указывать пакетную группу, система создает первую задачу с указанной пакетной группой, а все остальные, от которых зависит первая создает с пустой пакетной группой. Если на эту пустую группу не настроен ни один АОС, то она никогда не завершится. РЕШЕНИЕ. Если без доработок, то нужно добавить пустую пакетную группу к какому-либо серверу. |
|
01.03.2011, 12:40 | #7 |
SDET, Dynamics AX
|
Цитата:
Сообщение от Bega
ПРОБЛЕМА 5 . Не работает отмена закрытия или пересчета в пакетном режиме, если есть выделенный пакетный сервер.
Если делать отмену закрытия в пакетном режиме и указывать пакетную группу, система создает первую задачу с указанной пакетной группой, а все остальные, от которых зависит первая создает с пустой пакетной группой. Если на эту пустую группу не настроен ни один АОС, то она никогда не завершится. РЕШЕНИЕ. Если без доработок, то нужно добавить пустую пакетную группу к какому-либо серверу. Отличная тема. Попросил соответствующих людей чтоб посмотрели что тут описано. |
|
07.10.2011, 11:15 | #8 |
Читатель
|
кмк, эту проблему можно глобально решить в классе BatchHeader - при добавлении новой задачи к шапке инициализировать у нее batchGroupId (вообще непонятно, почему этого нет в базовой комплектации ))
|
|
10.02.2012, 16:20 | #9 |
Developer
|
Цитата:
+ к связи по ваучеру неплохо бы добавить связь по дате Только при "доукомплектации ПЗ" аналогичная проблема все равно останется т.е. вместо X++: select sum(CostAmountAdjustment) from invSettlement where invSettlement.Cancelled == NoYes::No && invSettlement.TransRecId == this.RecId exists join inventClosing where inventClosing.Voucher == invSettlement.Voucher && inventClosing.AdjustmentType == InventAdjustmentType::Transaction; X++: select sum(CostAmountAdjustment) from inventSettlement where inventSettlement.Cancelled == NoYes::No && inventSettlement.TransRecId == this.RecId exists join inventClosing where inventClosing.Voucher == inventSettlement.Voucher && inventClosing.TransDate == inventSettlement.TransDate && (inventClosing.AdjustmentType == InventAdjustmentType::Transaction || inventClosing.AdjustmentType == InventAdjustmentType::InventOnHand); Последний раз редактировалось vallys; 10.02.2012 в 18:04. |
|
|
За это сообщение автора поблагодарили: Bega (5). |
10.02.2012, 21:55 | #10 |
Участник
|
Цитата:
Сообщение от vallys
При суммировании сумм сопоставлений следует добавить еще тип корректировки "В наличии" (InventAdjustmentType::InventOnHand). Иначе при калькуляции ПЗ после "уценки/дооценки" (корректировка в наличии), сначала будет "отмена", а затем повторная коррекция на сумму "уценки/дооценки", только возможно (в зависимости от настроек) с другим корр. счетом (из InventAdj::errorAccountOperations(...))
+ к связи по ваучеру неплохо бы добавить связь по дате Только при "доукомплектации ПЗ" аналогичная проблема все равно останется |
|
25.02.2011, 16:49 | #11 |
Участник
|
Обнаружена такая проблема:
Производство не используется (отключена лицензия). При закрытии склада система пытается сделать какой-то расчет по производственным заказам (InventCostHelp.runProdWIPCalculation_RU()), при этом не находит номерной серии, которая должна быть настроена в параметрах модуля Производство и закрытие останавливается с ошибкой. Я так понимаю, проверка на то, что вообще нужен этот расчет, должна быть до начала каких-либо действий. Стоит добавить проверку на конфигурационный ключ Prod или есть какой-то еще признак, который позволит это сделать?
__________________
Ivanhoe as is.. |
|
25.02.2011, 16:54 | #12 |
Участник
|
Цитата:
Сообщение от Ivanhoe
Обнаружена такая проблема:
Производство не используется (отключена лицензия). При закрытии склада система пытается сделать какой-то расчет по производственным заказам (InventCostHelp.runProdWIPCalculation_RU()), при этом не находит номерной серии, которая должна быть настроена в параметрах модуля Производство и закрытие останавливается с ошибкой. Я так понимаю, проверка на то, что вообще нужен этот расчет, должна быть до начала каких-либо действий. Стоит добавить проверку на конфигурационный ключ Prod или есть какой-то еще признак, который позволит это сделать? X++: .. if (masterClient && CompanyInfo::features_W() == CRSEFeatures_W::RU //+DPL && isConfigurationkeyEnabled(configurationkeynum(Prod)) //-DPL ) { ... Последний раз редактировалось Bega; 25.02.2011 в 16:58. |
|
|
За это сообщение автора поблагодарили: EVGL (10). |
25.02.2011, 16:58 | #13 |
Участник
|
Собственно так и сделал Странно, что нет нормального управления этим. По факту там дальше перебираются все производственные заказы в периоде и по каждому проверяется - нужно ли считать эту расширенную себестоимость. Кому-то "опять двойка"
__________________
Ivanhoe as is.. |
|
25.02.2011, 17:00 | #14 |
Участник
|
Да, локализаторы в 5-м роллапе допустили много ошибок, как-то в попыхах все, на бегу
|
|
25.02.2011, 18:06 | #15 |
Moderator
|
|
|
25.02.2011, 19:22 | #16 |
Участник
|
Ну раз пошла такая пьянка
Отмена закрытия склада при отключенном ключе двух-валютного склада пропускает удаление проводок SummedUp со всеми вытекающими вкусностями Class / InventCostClosingCancel_WorkInvent / deleteVirtualTransfers X++: ... while select forupdate inventTrans order by InventTransId where inventTrans.ValueOpen == InventTransOpen::Yes // <GEEU> // && inventTrans.ValueOpenSecCur_RU == InventTransOpen::Yes && inventTrans.ValueOpenSecCur_RU == (isConfigurationKeyEnabled(configurationkeynum(InventClosingSecCur_RU)) ? InventTransOpen::Yes : InventTransOpen::No) // </GEEU> ... PS. Интересно, много ли еще таких мест ? |
|
|
За это сообщение автора поблагодарили: EVGL (5), Bega (1). |
28.02.2011, 17:54 | #17 |
Участник
|
Цитата:
X++: ... while select forupdate inventTrans order by InventTransId where inventTrans.ValueOpen == InventTransOpen::Yes // <GEEU> //+ DPL InventClosingFix_OK 28.02.2011 OK //inventTrans.ValueOpenSecCur_RU == InventTransOpen::Yes) && ( !isConfigurationKeyEnabled(configurationkeynum(InventClosingSecCur_RU)) || inventTrans.ValueOpenSecCur_RU == InventTransOpen::Yes) //- DPL InventClosingFix_OK 28.02.2011 OK ... |
|
16.05.2012, 14:16 | #18 |
Banned
|
Цитата:
Сообщение от Alexius
Ну раз пошла такая пьянка
Отмена закрытия склада при отключенном ключе двух-валютного склада пропускает удаление проводок SummedUp со всеми вытекающими вкусностями Class / InventCostClosingCancel_WorkInvent / deleteVirtualTransfers X++: ... while select forupdate inventTrans order by InventTransId where inventTrans.ValueOpen == InventTransOpen::Yes // <GEEU> // && inventTrans.ValueOpenSecCur_RU == InventTransOpen::Yes && inventTrans.ValueOpenSecCur_RU == (isConfigurationKeyEnabled(configurationkeynum(InventClosingSecCur_RU)) ? InventTransOpen::Yes : InventTransOpen::No) // </GEEU> ... PS. Интересно, много ли еще таких мест ? В RU8 ошибка старательно перенесена в метод \Classes\InventCostClosingCancel_End\deleteVirtualTransfers |
|
25.02.2011, 20:29 | #19 |
Banned
|
Bega, а вы с Microsoft по поводу этих багов связались? Как-то не хотелось бы править из версии в версию.
|
|
28.02.2011, 09:31 | #20 |
Участник
|
|
|
Теги |
баг, закрытие склада, ошибка, ошибка при закрытии склада, себестоимость |
|
|