26.06.2013, 19:59 | #1 |
Участник
|
Странное поведение при закрытии склада-ошибка в коде?
Добрый день, подскажите пожалуйста:
Акс 2009. Sp 5 Настройки Группа складских аналитик: 1.1 активный включено аналитики склад, партия, паллета, ячейка- 1.2. физ. наличие включено для аналитик склад, партия, паллета, ячейка, 1.3 .первичные аналитики -склад 1.4. финансовый склад включен для аналитик склад. Настройки Группа складских моделей: 1.1. Складская модель ФИФО Включены настройки: 1.2. Отрицательный физ склад, 1.3. Отрицательный фин склад, 1.4. Заказ на отгрузку, 1.5. Разносить физ операции, 1.6. Разносить фин операции, 1.7. Резервирование- контроль по дате. У нас возникла следующая ситуация -некорректно проставляется корректировка сторно заказа при закрытии склада. Заказ первоначально проведен и отсторнирован апрелем, затем повторно проведен и осторнирован в мае , затем окончательно проведен в мае. 1.до закрытия апреля проводки 1.1. 30.04.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 1.2. 30.04.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. 1.3. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 1.4. 07.05.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. 1.5. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 2. после закрытия апреля (ФИФО) 2.1. 30.04.2013 заказ 1698 продано -2000 шт сумма -20294,6 грв. полностью финансово закрыта проводка 2.2. 30.04.2013 заказ 1698 куплено 2000 шт сумма 81347,3 грв. проводка открыта 2.3. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 2.4. 07.05.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. 2.5. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. если сделать пересчет в мае ( например 7 мая),то проводка 2.2 становится корректной, там итоговая сумма получается 20294,6. перечень всех складских проводок по данной номенклатуре до закрытия и после закрытия привожу в ексель. там по 45 строк. Мы планируем ежемесячно переоценивать складские запасы через корректировку в наличии путем указания процента изменения себестоимости- для всех номенклатур одинаковый процент изменения. Данная складская проводка 2.2 вылазит в в открытые , должна быть переоценена вместе с другими.Но у нее абсолютно неправильная себестоимость. Если мы эту проводку переоценим через корректировку в наличиии,то последующие пересчеты себестоимости ее уже никак не затронут. Поэтому нам очень нужна правильная себестоимость в этой проводке на конец месяца. Я обнаружила ,анализируя закрытие склада для данной номенклатуры в дебагерре, что в методе updateTransIdReturnReceipt класса InventCostItemDim вызывается из : [s] \Classes\InventCostItemDim\updateTransIdReceipt [s] \Classes\InventCostItemDim\updateLevelAdjustment [s] \Classes\InventCostItemDim\updateItem при выборе расходных проводок , исходя из которых должна рассчитаться цена приходной проводки, нет ограничения по финансовой дате расходной проводки . (которое есть при выборе приходных проводок ) таким образом в моем случае при закрытии склада апреля при расчете цены для приходной проводки сторно заказа берутся две расходные проводки: одна из апреля -2000 штук сумма -146400 грв уже имеет корректировку 126105,4 (корректировка рассчитана ранее в момент закрытия склада) а другая из мая. -2000 штук -146400 грв и получается некорректная цена (-146400-146400+126105,4)/4000 штук=41,67 которая и протягивается в приходную проводку сторно заказа и создает неправильную сумму 81347,3 грв. Я не очень глубоко разбираюсь в процессах пересчета и закрытия склада.Поэтому ,извините, возможно задаю не очень профессиональные вопросы. Я обнаружила,что если поставить в коде в данном методе (см ниже отмечено комментариями TEMP) ограничение по финансовой дате расходной проводки, то для приходной проводки сторно заказа выберется только одна расходная проводка : 30.04.2013 -2000 штук сумма -146400 грв уже имеет корректировку 126105,4 и получится цена (-146400+126105,4)/2000 штук=10,15 которая протянется в приходную проводку сторно заказа и создаст правильную сумму 20294,6 грв. Подскажите, пожалуйста: Почему не стоит такое ограничение по финансовой дате расходной проводки? Возможно есть ли случаи, в которых важно чтобы этого ограничения не было? Можем ли мы у себя поставить такое ограничение, если мы будем всегда использовать ФИФО? Проверила в Акс3, там тоже такого ограничения нет. protected void updateTransIdReturnReceipt( InventTransId _inventTransId, InventTransId _inventTransIdReturn, Price _costPrice = 0 // if 0 then it will be recalculated ) { InventTrans receipt; InventTrans issue; CostAmount adjustNow; boolean onHandIsAdjusted; ; if (!_inventTransId || !_inventTransIdReturn) return; if (!_costPrice) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == _inventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == _inventTransId //TEMP &&issue.DateStatus <= inventClosing.TransDate; //TEMP if (!issue.Qty ) return; _costPrice = (issue.CostAmountPosted + issue.CostAmountAdjustment) / issue.Qty; } onHandIsAdjusted = InventAdj::isOnhandAdjusted(_inventTransId, _inventTransIdReturn, ''); while select forupdate receipt index hint TransIdIdx where receipt.InventTransId == _inventTransId && receipt.StatusReceipt == StatusReceipt::Purchased && receipt.StatusIssue == StatusIssue::None && receipt.PackingSlipReturned == 0 && receipt.InventTransIdReturn == _inventTransIdReturn && receipt.DateStatus <= inventClosing.TransDate { adjustNow = Currency::amount(receipt.Qty * _costPrice - receipt.CostAmountPosted - receipt.CostAmountAdjustment,standardCurrency); if (adjustNow) { receipt.CostAmountAdjustment += adjustNow; this.createAdjustSettlement(receipt, adjustNow, ''); // The adjustment for a std cost item will always be // reverted to bring the item cost down to std cost // So there is no need to create an adjustment. /* <SYS> if (!this.inventModelGroup(receipt.ItemId).inventModelType().stdCostBased()) </SYS> */ // <GEEU> if (! this.inventModelType_RU(receipt.ItemId).stdCostBased()) // </GEEU> { if (onHandIsAdjusted) { this.createErrorAdjustment(receipt, -adjustNow); } if (this.costValue(receipt) < 0) this.createErrorAdjustment(receipt, -adjustNow); if ((inventClosing.AdjustmentType == InventAdjustmentType::Closing) && (abs(adjustNow) < inventClosing.MinTransferValue || inventClosing.NumOfIteration >= inventClosing.MaxIterations)) { this.createErrorAdjustment(receipt, -adjustNow); } } else { /* <SYS> this.inventModelGroup(receipt.ItemId).inventModelType().postUpdateFinancialAdjustment(receipt, inventClosing.Voucher, inventClosing.TransDate, adjustNow); </SYS> */ // <GEEU> this.inventModelType_RU(receipt.ItemId).postUpdateFinancialAdjustment(receipt, inventClosing.Voucher, inventClosing.TransDate, adjustNow); // </GEEU> } this.updateCostAmountStd(receipt); receipt.update(); } mapInventTrans.insert(receipt.RecId, receipt); } } |
|
|
За это сообщение автора поблагодарили: Logger (5). |
27.06.2013, 00:31 | #2 |
Участник
|
Цитата:
Цитата:
Цитата:
Цитата:
|
|
|
За это сообщение автора поблагодарили: Aquarius (1). |
27.06.2013, 09:55 | #3 |
Участник
|
Цитата:
Лежит такой товар на складе, никого не трогает - а себестоимость у него сама по себе меняется, просто потому что так захотелось
Реальная себестоимость на оптовом складе где и производят наценку и отпускают товары в розничные точки уже по розничной цене, что позволяет: 1) Материальную ответственность применять по рознице (без потери прибыли) 2) Скрывать моржу от лишних глаз и т.п. и т.д. Кроме того может потребоваться уценить товар... например при подходе сроков годности к концу... Меня всегда убивало что на розничных ценниках необходимо указывать документ прихода (№+дату как аналог партии). При этом несколько одинаковых единиц товара могут быть по разным документам и разным розничным ценам при таком подходе... Поэтому либо менять ценники постоянно... либо производить некую переоценку Последний раз редактировалось ansoft; 27.06.2013 в 10:04. |
|
|
За это сообщение автора поблагодарили: Aquarius (1). |
27.06.2013, 10:25 | #4 |
Moderator
|
Не надо править код закрытия. Надо использовать номер возвращаемого лота. (Указывается где-то в строках заказа и копируется при разноске в складскую проводку - inventTrans.inventTransIdReturn).
Закрытие/пересчет склада по данной номенклатуре начинается с того, что система пробегает по всем незакрытым приходным проводкам с непустым значением в этом поле, рассчитывает себестоимость штуки по лоту расхода, на который данный лот прихода ссылается и переоценивает лот прихода). Этот механизм, в определенной степени противоположен маркировке. Маркировка позволяет обойти механизм закрытия и приравнять стоимость конкретного расхода стоимости конкретного прихода; Лот возврата позволяет приравнять себестоимость прихода себестоимости конкретного расхода. При этом дата возвращаемого заказа не берется во внимание. Даже если у вас возвращен заказ трехлетней давности, система все равно полезет в старые закрытые списания, посчитает их себестоимость и переоценит приход в соответствии с этой себестоимостью. Так что просто проследите что этот лот в возвратах по заказам указан и все будет хорошо. Можете даже попытаться его джобиком подправить для конкретного разнесенного заказа, раз вовремя не указали. С большой вероятностью - закрытие эту правку корректно отработает... Последний раз редактировалось fed; 27.06.2013 в 10:35. |
|
|
За это сообщение автора поблагодарили: Aquarius (1). |
27.06.2013, 10:57 | #5 |
Участник
|
Цитата:
Проблема действительно есть. И мы её лечили таким же способом как предлагает Aquarius. У нас тоже Ax2009 SP5 Когда делали сторно дважды в разных месяцах, то номер возвращаемого лота заполнен автоматом. (Мы это делали через немедленное получение, получалось что номера лота и лота возврата совпадали, хотя по-моему для обсуждаемой проблемы это несущественно) Пример исправления : Класс InventCostItemDim Исправление в двух методах : X++: protected void updateTransIdReturnReceipt( InventTransId _inventTransId, InventTransId _inventTransIdReturn, Price _costPrice = 0 // if 0 then it will be recalculated ) { InventTrans receipt; InventTrans issue; CostAmount adjustNow; boolean onHandIsAdjusted; ; if (!_inventTransId || !_inventTransIdReturn) return; if (!_costPrice) { // GRD_R3790_FixInventCostItemDim_pkoz //pkoz 20.09.2011 --> if ( InventCostItemDim::is3790_FixInentTransIdReturn()) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == _inventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == _inventTransId && issue.DateStatus <= inventClosing.TransDate; if (!issue.Qty ) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == _inventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == _inventTransId; } } else // GRD_R3790_FixInventCostItemDim_pkoz //pkoz 20.09.2011 <-- select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == _inventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == _inventTransId; if (!issue.Qty ) return; _costPrice = (issue.costAmountPosted + issue.costAmountAdjustment) / issue.Qty; } onHandIsAdjusted = InventAdj::isOnhandAdjusted(_inventTransId, _inventTransIdReturn, ''); while select forupdate receipt index hint TransIdIdx where receipt.InventTransId == _inventTransId && receipt.StatusReceipt == StatusReceipt::Purchased && receipt.StatusIssue == StatusIssue::None && receipt.PackingSlipReturned == 0 && receipt.InventTransIdReturn == _inventTransIdReturn && receipt.DateStatus <= inventClosing.TransDate { adjustNow = Currency::amount(receipt.Qty * _costPrice - receipt.CostAmountPosted - receipt.CostAmountAdjustment,standardCurrency); if (adjustNow) { receipt.CostAmountAdjustment += adjustNow; this.createAdjustSettlement(receipt, adjustNow, ''); // The adjustment for a std cost item will always be // reverted to bring the item cost down to std cost // So there is no need to create an adjustment. /* <SYS> if (!this.inventModelGroup(receipt.ItemId).inventModelType().stdCostBased()) </SYS> */ // <GEEU> if (! this.inventModelType_RU(receipt.ItemId).stdCostBased()) // </GEEU> { if (onHandIsAdjusted) { this.createErrorAdjustment(receipt, -adjustNow); } if (this.costValue(receipt) < 0) this.createErrorAdjustment(receipt, -adjustNow); if ((inventClosing.AdjustmentType == InventAdjustmentType::Closing) && (abs(adjustNow) < inventClosing.MinTransferValue || inventClosing.NumOfIteration >= inventClosing.MaxIterations)) { this.createErrorAdjustment(receipt, -adjustNow); } } else { /* <SYS> this.inventModelGroup(receipt.ItemId).inventModelType().postUpdateFinancialAdjustment(receipt, inventClosing.Voucher, inventClosing.TransDate, adjustNow); </SYS> */ // <GEEU> this.inventModelType_RU(receipt.ItemId).postUpdateFinancialAdjustment(receipt, inventClosing.Voucher, inventClosing.TransDate, adjustNow); // </GEEU> } this.updateCostAmountStd(receipt); receipt.update(); } mapInventTrans.insert(receipt.RecId, receipt); } } X++: /// <summary> /// Adjust the cost of item return receipts to that of the corresponding issues. /// </summary> /// <param name="_itemId"> /// The item ID for which to adjust the return receipts. /// </param> protected void updateItemReturnAdjustments(ItemId _itemId = inventCostList.ItemId) { InventTrans inventTrans; InventTrans issue; Price costPrice; CostAmount adjustment; // <GEEU> InventDim inventDim; InventLocation inventLocation; // </GEEU> ; while select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from inventTrans index hint StatusItemIdx group by InventTransId, InventTransIdReturn where inventTrans.ItemId == _itemId && inventTrans.ValueOpen == InventTransOpen::Yes && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.StatusIssue == StatusIssue::None && inventTrans.DateStatus <= inventClosing.TransDate && inventTrans.PackingSlipReturned == 0 && inventTrans.InventTransIdReturn != '' && ( inventTrans.TransType == InventTransType::Sales || inventTrans.TransType == InventTransType::BOMLine || inventTrans.TransType == InventTransType::InventLossProfit || inventTrans.TransType == InventTransType::InventTransaction || inventTrans.TransType == InventTransType::Project || inventTrans.TransType == InventTransType::ProdLine // <GEEU> || (inventTrans.TransType == InventTransType::ProdRelease_RU && featuresRUIsEnabled_RU) // </GEEU> ) { // GRD_R3790_FixInventCostItemDim_pkoz //pkoz 20.09.2011 --> if ( InventCostItemDim::is3790_FixInentTransIdReturn()) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == inventTrans.InventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == inventTrans.InventTransId && issue.DateStatus <= inventClosing.TransDate; if (!issue.Qty) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == inventTrans.InventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == inventTrans.InventTransId; } } else // GRD_R3790_FixInventCostItemDim_pkoz //pkoz 20.09.2011 <-- select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == inventTrans.InventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == inventTrans.InventTransId; if (issue.Qty) { costPrice = (issue.CostAmountPosted + issue.CostAmountAdjustment) / issue.Qty; adjustment = Currency::amount(inventTrans.Qty * costPrice - inventTrans.CostAmountPosted - inventTrans.CostAmountAdjustment,standardCurrency); if (abs(adjustment) >= inventClosing.MinTransferValue && !InventAdj::isOnhandAdjusted(inventTrans.InventTransId, inventTrans.InventTransIdReturn, '')) this.updateTransIdReturnReceipt(inventTrans.InventTransId, inventTrans.InventTransIdReturn, costPrice); } } // <GEEU> if (! featuresRUIsEnabled_RU) return; while select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from inventTrans index hint StatusItemIdx group by InventTransId, InventTransIdReturn where inventTrans.ItemId == _itemId && inventTrans.ValueOpen == InventTransOpen::Yes && inventTrans.StatusReceipt == StatusReceipt::Purchased && inventTrans.StatusIssue == StatusIssue::None && inventTrans.DateStatus <= inventClosing.TransDate && inventTrans.PackingSlipReturned == 0 && inventTrans.InventTransIdReturn != '' && (inventTrans.TransType == InventTransType::TransferOrderScrap || inventTrans.TransType == InventTransType::TransferOrderShip || inventTrans.TransType == InventTransType::TransferOrderReceive) exists join inventDim where inventDim.InventDimId == inventTrans.InventDimId exists join inventLocation where inventLocation.InventLocationId == inventDim.InventLocationId && (inventTrans.TransType == InventTransType::TransferOrderScrap || (inventTrans.TransType == InventTransType::TransferOrderShip && inventLocation.InventLocationType == InventLocationType::Standard) || (inventTrans.TransType == InventTransType::TransferOrderReceive && inventLocation.InventLocationType == InventLocationType::Transit)) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == inventTrans.InventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == inventTrans.InventTransId; if (issue.Qty) { costPrice = (issue.CostAmountPosted + issue.CostAmountAdjustment) / issue.Qty; adjustment = Currency::amount(inventTrans.Qty * costPrice - inventTrans.CostAmountPosted - inventTrans.CostAmountAdjustment,standardCurrency); if (abs(adjustment) >= inventClosing.MinTransferValue && !InventAdj::isOnhandAdjusted(inventTrans.InventTransId, inventTrans.InventTransIdReturn, '')) this.updateTransIdReturnReceipt(inventTrans.InventTransId, inventTrans.InventTransIdReturn, costPrice); } } // </GEEU> } |
|
|
За это сообщение автора поблагодарили: gl00mie (5), Aquarius (1). |
27.06.2013, 10:59 | #6 |
Участник
|
Ну вот это по-моему и неправильно. Нужно чтобы была такая же логика как для приходных проводок, так как в данном случае расходные проводки играют роль приходных - формируют себестоимость. Поэтому надо при их отборе накладывать фильтр : дата финансовая <= дате закрытия/пересчета
|
|
|
За это сообщение автора поблагодарили: Aquarius (1). |
27.06.2013, 11:16 | #7 |
Участник
|
Большое спасибо всем за ответы.
У нас лот возврата был указан в проводках по заказу изначально До закрытия проводки по заказу выглядели так: 1.1. 30.04.2013 заказ 1698 продано -2000 шт сумма -146400 грв. Номер лота IT-AA00005625 Лот возврата IT-AA00005625 1.2. 30.04.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. Номер лота IT-AA00005625 Лот возврата IT-AA00005625 1.3. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. Номер лота IT-AA00005625 Лот возврата IT-AA00005625 1.4. 07.05.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. Номер лота IT-AA00005625 Лот возврата IT-AA00005625 1.5. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 2. после закрытия апреля (ФИФО) так: 2.1. 30.04.2013 заказ 1698 продано -2000 шт сумма -20294,6 грв. полностью финансово закрыта проводка 2.2. 30.04.2013 заказ 1698 куплено 2000 шт сумма 81347,3 грв. проводка открыта 2.3. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. 2.4. 07.05.2013 заказ 1698 куплено 2000 шт сумма 146400 грв. 2.5. 07.05.2013 заказ 1698 продано -2000 шт сумма -146400 грв. Однако себестоимость рассчитывается некорректно. |
|
27.06.2013, 11:16 | #8 |
Moderator
|
Цитата:
P.S. Вчитавшись в описание, я наконец понял о чем речь. Если ты приходную проводку переоцениваешь и у тебя разные части расхода по разной себестоимости, то они усредняться. Ok - ну да - есть такая проблема. Но в таком случае, правильнее было бы не ограничивать дату (а что если мы в последнем месяце три раза приходную проводку переоценивали и у нас списание себестоимости по разным приходным себестоимостям), а сделать и включить какую-то специальную галочку (типа - возврат по последней себестоимости), которая будет брать себестоимость из последнего по времени списания по лоту и именно ее использовать для переоценки. А вообще - как я и сказал - все это зависит от того как в учетной политике описано формирование себестоимости по возврату. Можно 1001 вариант придумать и только один из них реализован в системе. Но это не ошибка, а фича... |
|
|
За это сообщение автора поблагодарили: Logger (1), Aquarius (1). |
27.06.2013, 11:28 | #9 |
Участник
|
Logger,
большое спасибо вам за ответ. а у вас какой метод списания себестоимости -ФИФО? (в компании, в которой вы делали вышеуказанную модификацию кода.) |
|
27.06.2013, 11:33 | #10 |
Участник
|
Да, у нас ФИФО.
|
|
|
За это сообщение автора поблагодарили: Aquarius (1). |
27.06.2013, 13:17 | #11 |
Участник
|
Logger,
подскажите, пожалуйста, вот у вас есть еще дополнительно проверка if (!issue.Qty) { select sum(Qty), sum(CostAmountAdjustment), sum(CostAmountPosted) from issue index hint TransIdIdx where issue.InventTransId == inventTrans.InventTransIdReturn && issue.StatusReceipt == StatusReceipt::None && issue.StatusIssue == StatusIssue::Sold && issue.PackingSlipReturned == 0 && issue.InventTransIdReturn == inventTrans.InventTransId; } получается вы еще дополнительно проверяете, если нет сторно в текущем месяце, т.е. количество 0, то тогда берете данные из следущего месяца по расходным проводкам для формирования цены приходного лота? Последний раз редактировалось Aquarius; 27.06.2013 в 13:57. |
|
27.06.2013, 13:37 | #12 |
Участник
|
Да именно так. Чтобы нулей не получить.
Может это не совсем последовательное решение, но зато так работает. Лучше взять реальную сумму из более позднего периода чем ничего. |
|
|
За это сообщение автора поблагодарили: Aquarius (1). |