01.03.2009, 19:16 | #1 |
Участник
|
Расщепление InventSplitTrans_Remain и коррекция в наличии
Привет всем
Хотел бы обсудить работу механизма расщепления проводок InventTrans в Аксапте 3.0 SP5 (класс \Classes\InventSplitTrans_Remain) Выяснились некоторые неприятные моменты. Суть баги в том, что если мы имеем частично закрытую приходную проводку то при её расщеплении, может оказаться так, что сумма сопоставления в проводке и сумма проводки не будут совпадать. (Причина этого в том что система некорректно обрабатывает ошибки округления) Из-за этого в дальнейшем проводка никогда не закрывается и ломается функция Коррекция-В наличии. Рассмотрим пример. 1. 1-е марта делаем приход на 1080 штук, сумма 10983,05 2. 2-е марта делаем 2 расхода по 30 штук. (Для воспроизведения бага важно чтобы было именно 2 расхода по 30 а не 1 по 60) 3. Закрываем склад на 2-е марта (или позднее - это непринципиально) Что получается: В приходной проводке имеем Закрытое количество (QtySettled) 60 Рассчитанная сумма (CostAmountSettled) 610,16 Если сделать Коррекция-В наличии на процент -100 т.е. попытаться обнулить остаток, то система выдаст ошибку в момент расщепления, которое выполняется при такой коррекции. Тогда сделаем просто расщепление проводки. Проводки - Функции - Разбиение Укажем количество 1020, т.е. оставшаяся после расщепления проводка должна закрыться, так как для неё будет qtySettled == Qty Но этого не происходит, потому что при расщеплении система записала в InventTrans.CostAmountPosted сумму 610,17 в то время как CostAmountSettled == 610,16 (Проводка не закрывается потому что в методе InventTrans.setClosedOpen() не отрабатывает условие на закрытие проводки X++: case this.isUpdatedFinancial() &&
abs(this.qty - this.qtySettled) < InventAdj::settleQtyDiff() &&
Currency::amount(this.costValue() - this.costAmountSettled) == 0 : Теперь понятно почему при выполнении функции Коррекция - В наличии была ошибка. Ошибка происходит потому что сумма, которую надо сминусовать рассчитывается по нерасщепленной проводке (\Classes\InventAdj_SumUp\updateInvent) и равна 10372,89 а после расщепления из-за неправильных округлений сумма в открытой проводке равна 10372,88 поэтому при коррекции сумма положительной проводки загоняется в минус на 1 копейку и возникает ошибка. Во вложении прилагается попытка исправления данной баги. Суть в том, что при расщеплении система проверяет полностью ли закрыта проводка по количеству и если да, то скидывает все округления в поле InventTrans.CostAmountPosted искусственно подгоняя себестоимость проводки под сумму (InventTrans.CostAmountSettled) При этом не совсем понятно что делать с остальными полями себестоимости costAmountStd costAmountPhysical costAmountOperations Поскольку costAmountOperations обычно равен costAmountPosted то аналогичные исправления я делаю и в costAmountOperations. |
|
|
За это сообщение автора поблагодарили: fed (3), gl00mie (7), Aquarius (1). |
02.03.2009, 11:59 | #2 |
Moderator
|
В общем - автор прав похоже что. Надеюсь что участник Kashperuk, проверит это дело на DAX2009/DAX v.next и запостит ошибку если что
Способ исправления ошибки явно правильный. Проще чуть-чуть подправить расщепление чем курочить очень сложное закрытие. По поводу полей: CostAmountOperations - сумма по затратному счету прихода. В 99% случаев равна отрицательному значению costAmountPosted. Единственное исключение о котором я прямо сейчас помню - приход услуг по закупке. В таких проводках amountPosted=0; amountOPerations= себестоимости(без минуса).Поскольку услуги на складе не переоценивают - мы этот случай можем игнорировать CostAmountPhysical - физическая себестоимость по отборочной накладной (грубо говоря). На расчет окончательной себестоимости влияет мало, я бы просто не стал это поле трогать.(Точнее говоря - влияет, но только в тех случаях когда проводка не разнесена финансово и amountPosted==0) CostAmountStd - стандартная себестоимость. Используется для расчета отклонения между стандартной и закупочной стоимостью. Грубо говоря - для приходов по стандартной себестоимости - CostAmountPosted= закупочной себестоимости, CostAmountStd = стандартной; costAmountAdjustment=costAmountStd-costAmountPosted. Я бы это поле тоже трогать не стал бы, поскольку оно скорее для исторических целей интересно чем для реальных манипуляций с себестоимостью. |
|
03.03.2009, 09:29 | #3 |
Участник
|
Offtopic.
В \Data Dictionary\Tables\InventTrans\Methods\setClosedOpen обнаружилась очень интересная конструкция, заменяющая последовательные if .. else if .. else if .. else: X++: switch(true) { case this.packingSlipReturned : // ... case this.isUpdatedQuotation() : // ... case this.RecId && this.valueOpen == InventTransOpen::No : // ... case this.isUpdatedFinancial() && abs(this.qty - this.qtySettled) < InventAdj::settleQtyDiff() && Currency::amount(this.costValue() - this.costAmountSettled) == 0 : default : // ... } |
|
03.03.2009, 13:15 | #4 |
Участник
|
Интересно.
По-моему так читать код удобнее. Надо взять на вооружение. |
|
03.03.2009, 13:58 | #5 |
Moderator
|
|
|
Теги |
creditnote, inventsplittrans, inventsplittrans_remain, коррекция в наличии, коррекция себестоимости, немедленное получение, ошибка, расщепление проводок, сопоставление |
|
|