|
11.11.2008, 09:47 | #1 |
Участник
|
Поле CostAmountAdjustment в InventTrans
Как можно проверить в InventTrans поле CostAmountAdjustment для ValueOpen = да?
Проверить на предмет, что оно посчитано правильно. Сравнить с аналогичным полем в InventSettlement не предлагать (Не в этом вопрос).
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 10:01 | #2 |
----------------
|
если не в этом, то в чем?
посмотреть с кем сопоставлена проводка и сравнить их costValue по сопоставленному кол-ву... опять же возвращаемся к InventSettlement |
|
11.11.2008, 10:28 | #3 |
Участник
|
Цитата:
Есть такая проблема. Есть приложение сильное изменённое. В нём хватает чужого кода в классах закрытия, пересчёта и корректирки. По одной номенклатуре (возможно их больше) не получается скорректировать себестоимость через корректировку наличия. Выкидывает сообщение Отрицательная себестоимость не возможна. (S) \Classes\InventTransAdjust\updateNow - line 72 Не могу понять в чём дело. Считается вроде всё правильно и интуиция подсказывает возможно входные данные не правильны. А именно поле корректировки. Предположил что это поле на InventTrans проверяется таким образом. Для ValueOpen = да X++: display Amount MRD_calcCostAmountAdjustment() { Amount costAmountAdjustment; ; if(this.QtySettled) costAmountAdjustment = this.Qty * this.CostAmountSettled / this.QtySettled - this.CostAmountPosted; else costAmountAdjustment = this.CostAmountSettled; return costAmountAdjustment; } 1) Цифры в основном различаются на втором знаке после запятой. На той проводке которая меня интересует на первой после запятой. Как раз мне мальца и нехватает чтоб ошибку убрать. 2) Что меня ещё смущает? Что есть прводки без сопоставления, но с корректировкой. Не понятно тогда откуда эти суммы беруться, если нет сопоставления. Визуально вижу что эти цифры иногда совпадают с проводками по той же номенклатуре но по которой были сопоставления. Связано это или нет не знаю точно. Первый вопрос более интересен. Но если кто сможет объяснить второй (Почему так) тоже будет хорошо.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. Последний раз редактировалось miklenew; 11.11.2008 в 10:47. Причина: описался место номенклатуры написал накладной |
|
11.11.2008, 18:00 | #4 |
Moderator
|
Цитата:
Сообщение от miklenew
Выкидывает сообщение
Отрицательная себестоимость не возможна. (S) \Classes\InventTransAdjust\updateNow - line 72 Не могу понять в чём дело. Считается вроде всё правильно и интуиция подсказывает возможно входные данные не правильны. А именно поле корректировки. Предположил что это поле на InventTrans проверяется таким образом. Для ValueOpen = да Возможно, я не прав и топикстартер уже разобрался в том что происходит в этих классах. В таком случае, просьба написать почему возникло подозрение что неверно значение именно в inventTrans.costAmountAdjustment. |
|
12.11.2008, 10:54 | #5 |
Участник
|
К чему в результате дошёл
1) \Classes\InventSumOpenTransact\add Закидываем в буфер costAmountPosted 2) (S) \Classes\InventSumOpenTransact\setTransAdjustNow - line 4 Инициализируем суммы корректировки нулями 3)(S) \Classes\InventSumOpenTransact\setAdjustment - line 49 Может получиться что расчитанная сумма корректировки нам не подходит, тогда корректировка = this.transValue(x)+this.transAdjustNow(x) Фактически это this.transValue(x) т.к. transAdjustNow(x) = 0 4) (S) \Classes\InventTransAdjust\updateNow - line 35 inventTrans.updateSplit(inventTrans.financialOpenQty()); Делим на две проводки (старая+новая) И все суммы и количества пропорционально распределяем, кроме суммы по корректировке. Корректировку оставляем на изначальной проводке. Т.к. в InventSettlement связь не только по лоту но и по recId. После этой процедуры место старого inventTrans в памяти уже другой. Вот это я исправил, так как это не правильно. Поставил в верху метода X++: RefRecId origRecId; X++: if (inventTrans.financialOpenQty() != inventTrans.qty)
inventTrans.updateSplit(inventTrans.financialOpenQty()); X++: if (inventTrans.financialOpenQty() != inventTrans.qty) { origRecId = inventTrans.RecId; inventTrans.updateSplit(inventTrans.financialOpenQty()); if(inventTrans.RecId != origRecId) inventTrans = InventTrans::findRecId(origRecId, true); }
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
12.11.2008, 19:27 | #6 |
Участник
|
Есть подозрения, что сделал не правильно.
Завтра ещё буду юзать. Но неужели не у кого нет мыслей зачем там updatesplit(). Буду благодарен за любые догадки, даже неправильные.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
01.03.2009, 19:19 | #7 |
Участник
|
Цитата:
Расщепление InventSplitTrans_Remain и коррекция в наличии |
|
11.11.2008, 13:14 | #8 |
Участник
|
Цитата:
Проверить CostAmountSettled сравнивая проводки по которым было сопоставление можно. А вот как проверить CostAmountAdjustment?
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 13:37 | #9 |
Member
|
Цитата:
Сообщение от miklenew
...
А вот как проверить CostAmountAdjustment? ... Вам даже метод таблицы InventTrans показали, который это делает.
__________________
С уважением, glibs® |
|
11.11.2008, 13:49 | #10 |
Участник
|
Цитата:
Я их проверил и до того как нашёл этот метод.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 14:16 | #11 |
Участник
|
И ещё такой вопрос: Можно ли удалять сопоставление по закрытым проводкам (ValueOpen = нет)?
А то у нас себестоимость считается по средней стоимости. Таблица InventSettlement пухнет как на дрожях.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 11:33 | #12 |
Member
|
Проверка целостности данных компании пересчитывает это поле по InventSettlement. Попробуйте запустить на тестовой базе, посмотрите что получится.
Проверку целостности лучше выдрать из стандартного кода и пустить джобом. А то стандартная там много чего проверяет, и может затянуться надолго.
__________________
С уважением, glibs® |
|
|
За это сообщение автора поблагодарили: miklenew (5). |
11.11.2008, 11:44 | #13 |
Участник
|
Спасибо нашёл.
InventTrans\checkFixSettlement() Щас посмотрю. Чёто сначало по галочкам прошёл, с сопоставлением не нашёл. Но не подумал, что оно может в проверке Проводки.
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 11:51 | #14 |
Участник
|
Рано обрадовался. Там простенькие проверки на соответствие inventTrans и inventSettlement.
Может кто в Ax 2009 или в Ax 4.0 посмотрит написано ли ещё что в InventTrans\checkFixSettlement().
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. |
|
11.11.2008, 12:04 | #15 |
Программатор
|
AX 4
X++: void checkFixSettlement(InventConsistencyCheck_Trans inventConsistencyCheck_Trans) { InventSettlement inventSettlement; setprefix("@SYS55578"); while select forupdate inventSettlement where inventSettlement.TransRecId == this.RecId && inventSettlement.InventTransCurrency_RU == InventTransCurrency_RU::PrimaryCur { setprefix(#prefixField(inventSettlement,RecId)); if (inventSettlement.ItemId != this.ItemId || inventSettlement.InventTransId != this.InventTransId) { checkFailed("@SYS67934",'', SysInfoAction_TableField::newBufferField(inventSettlement, fieldnum(InventSettlement, RecId))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { inventSettlement.doDelete(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } } select sum(QtySettled),sum(CostAmountSettled),sum(CostAmountAdjustment) from inventSettlement where inventSettlement.TransRecId == this.RecId && inventSettlement.Cancelled == NoYes::No && inventSettlement.SettleModel != InventSettleModel::PhysicalValue && inventSettlement.InventTransCurrency_RU == InventTransCurrency_RU::PrimaryCur; if (inventSettlement.QtySettled != this.QtySettled) { checkFailed("@SYS67938",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, QtySettled))); if(inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.QtySettled = inventSettlement.QtySettled; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } if (inventSettlement.CostAmountSettled != this.CostAmountSettled) { checkFailed("@SYS67939",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, CostAmountSettled))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.CostAmountSettled = inventSettlement.CostAmountSettled; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } if (inventSettlement.CostAmountAdjustment != this.CostAmountAdjustment) { checkFailed("@SYS67940",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, CostAmountAdjustment))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.CostAmountAdjustment = inventSettlement.CostAmountAdjustment; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } } |
|
|
За это сообщение автора поблагодарили: miklenew (2). |
11.11.2008, 12:19 | #16 |
Участник
|
В 2009 почти то же самое (без российского функционала)
X++: public void checkFixSettlement(InventConsistencyCheck_Trans inventConsistencyCheck_Trans) { InventSettlement inventSettlement; setprefix("@SYS55578"); while select forupdate inventSettlement where inventSettlement.TransRecId == this.RecId { setprefix(#prefixField(inventSettlement,RecId)); if (inventSettlement.ItemId != this.ItemId || inventSettlement.InventTransId != this.InventTransId) { checkFailed("@SYS67934",'', SysInfoAction_TableField::newBufferField(inventSettlement, fieldnum(InventSettlement, RecId))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { inventSettlement.doDelete(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } } select sum(QtySettled),sum(CostAmountSettled),sum(CostAmountAdjustment) from inventSettlement where inventSettlement.TransRecId == this.RecId && inventSettlement.Cancelled == NoYes::No && inventSettlement.SettleModel != InventSettleModel::PhysicalValue; if (inventSettlement.QtySettled != this.QtySettled) { checkFailed("@SYS67938",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, QtySettled))); if(inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.QtySettled = inventSettlement.QtySettled; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } if (inventSettlement.CostAmountSettled != this.CostAmountSettled) { checkFailed("@SYS67939",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, CostAmountSettled))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.CostAmountSettled = inventSettlement.CostAmountSettled; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } if (inventSettlement.CostAmountAdjustment != this.CostAmountAdjustment) { checkFailed("@SYS67940",'', SysInfoAction_TableField::newBufferField(this, fieldnum(InventTrans, CostAmountAdjustment))); if (inventConsistencyCheck_Trans.checkFix() == CheckFix::Fix) { this.CostAmountAdjustment = inventSettlement.CostAmountAdjustment; this.doUpdate(); inventConsistencyCheck_Trans.updateCorrected(); } else inventConsistencyCheck_Trans.updateNotCorrected(); } } |
|
|
За это сообщение автора поблагодарили: miklenew (2). |
12.11.2008, 19:41 | #17 |
Moderator
|
Извиняюсь - занят был - сразу не ответил. Этот самый updateSplit() - единственное что отличает переоценку остатков от переоценки проводок. Вот допустим ты купил 100 процессоров по $100 каждый и за месяц продал половину по цене $120. Потом 1ого числа Intel планово снизил цены за процы до $70 и даже компенсировал тебе разницу. Теперь ты должен ОСТАВШИЕСЯ 50 процессоров переоценить до $70 и продавать их по $85.
Если ты просто переоценишь проводку (или уберешь updateSplit()), то у тебя сумма переоценки равномерно размажется по всему приходному лоту (в том числе и по процессорам которые ты уже продал). В итоге у тебя получиться что первый месяц ты торговал процессорами с себестоимостью $85 при продажной цене $120; второй месяц ты торговал процессорами тоже с себестоимостью $85 при продажной цене $85. Получается что маржа и себестоимость криво посчитаны. А из за того что у тебя при переоценке остатков расщепляется на открытую и закрытую части, переоценка попадет только на открытую часть. В итоге у тебя себестоимость старых продаж не измениться, а новых - упадет ровно настолько насколько нужно. Кстати - это единственное место в Аксапте, которое я знаю, которое расщепляет ФИНАНСОВО разнесенные проводки. Во всех остальных местах, расщепление финансово разнесенных проводок запрещено |
|
|
За это сообщение автора поблагодарили: miklenew (7). |
12.11.2008, 20:21 | #18 |
Участник
|
Цитата:
Т.е. по-моему это еще один случай, когда система расщепляет фин. разнесенные проводки. |
|
12.11.2008, 22:55 | #19 |
Участник
|
Допустим есть такая ситуация есть 3 прихода по номенклатуре
Было закрытие (если нет ни одного закрытия система не позволит сделать корректировку) Эти приходы ни с одним расходом не сопоставились. И коррекция равна 0. Просто так легче дальше считать. Так вот Пример1 X++: Qty CostAmountPosted 10 100 5 20 20 300 X++: 35 420 35*5-420 = -245 Считаем Adjustment InventSumOpenTransact\setAdjustment() (47) adjustNow = Currency::amount(this.transQty(x) * adjustInTotal/ qtyTotal); (для 1 прихода) 10*(-245)\35= - 70 (для 2 прихода) 5*(-245)\35= - 35 (для 3 прихода) 20*(-245)\35= - 140 Видим что для второго прихода получилось 35, а разнесённая сумма 20 Смотрим InventSumOpenTransact\setAdjustment() (49) if (this.transValue(x) + this.transAdjustNow(x) + adjustNow < 0) Ну раз 35 снять не можем снимем = 20 Теперь эти 15 пропали и мы должны их всунуть или в 1 или 3 приход иначе у нас себестоимость остатка 5 не будет. Смотрим InventSumOpenTransact\setAdjustment() (44) if (this.transQty(x) >= qtyRemain) adjustNow = Currency::amount(amountRemain); Т.е. эти 15 войдут в в последний приход Если в последнем меньше чем коррекция Пример2 X++: Qty CostAmountPosted 10 300 5 20 20 100 -70 -20 -100 А так как распределение не всё пройдёт вторая итерация -70 (ещё -70) = -140 -20 -100 (и на последней +остаток 15) = - 85 И здесь всё ок (когда сопоставлений не было). Но вот когда появляются частично сопоставлененые проводки. Например если бы 2-ой приход был сопоставлен при закрытие 3 ед из 5. То произойдёт разбиение проводки на количество 3 и 2(CostAmountPosted 12 и 8 соответственно). И в результате будет попытка корректировки второй проводки (где Qty = 2 и CostAmountPosted = 8) А в буфере то у нас 20. От туда и ошибка про отрицательную себестоимость. Разделение проводки будет происходить для всех частично сопоставленых проводок которые участвуют в коррекции. Так вот вопрос почему бы в методе InventSumOpenTransact\add массив transValue для тех проводок у которых есть сопоставление заполнять не costAmountPosted, а costAmountPosted - (qtySettled*costAmountPosted)\qty = наши 8 И массив transQty = qty - qtySettled = наши 2 несопоставленные ед?
__________________
Энергия молодых и неравнодушных способна изменить мир к лучшему. Последний раз редактировалось miklenew; 12.11.2008 в 23:01. |
|
12.11.2008, 23:24 | #20 |
Moderator
|
Ну кстати, если посмотреть на inventSumOpenTransact.add(), то там в начале есть такой малоприметный метод inventTrans.setTransValueDate(). Он как раз занимается тем, что исключительно для целей коррекции остатков в наличии, отнимает от inventTrans.qty и inventTrans.costAmountPosted количества и сумму складских сопоставлений сделанных до даты переоценки. Так что если с этим методом никто не поигрался, то у тебя там не совсем оригинальные значения qty и costAmountPosted из исходной проводки должны в массиве лежать, а как раз что-то похожее на то что ты написал.
|
|
Теги |
логистика, переоценка |
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|