AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.06.2013, 10:25   #1  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,913 / 5736 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Не надо править код закрытия. Надо использовать номер возвращаемого лота. (Указывается где-то в строках заказа и копируется при разноске в складскую проводку - inventTrans.inventTransIdReturn).
Закрытие/пересчет склада по данной номенклатуре начинается с того, что система пробегает по всем незакрытым приходным проводкам с непустым значением в этом поле, рассчитывает себестоимость штуки по лоту расхода, на который данный лот прихода ссылается и переоценивает лот прихода). Этот механизм, в определенной степени противоположен маркировке. Маркировка позволяет обойти механизм закрытия и приравнять стоимость конкретного расхода стоимости конкретного прихода; Лот возврата позволяет приравнять себестоимость прихода себестоимости конкретного расхода. При этом дата возвращаемого заказа не берется во внимание. Даже если у вас возвращен заказ трехлетней давности, система все равно полезет в старые закрытые списания, посчитает их себестоимость и переоценит приход в соответствии с этой себестоимостью.
Так что просто проследите что этот лот в возвратах по заказам указан и все будет хорошо. Можете даже попытаться его джобиком подправить для конкретного разнесенного заказа, раз вовремя не указали. С большой вероятностью - закрытие эту правку корректно отработает...

Последний раз редактировалось fed; 27.06.2013 в 10:35.
За это сообщение автора поблагодарили: Aquarius (1).
Старый 27.06.2013, 10:57   #2  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от fed Посмотреть сообщение
Не надо править код закрытия. Надо использовать номер возвращаемого лота. (Указывается где-то в строках заказа и копируется при разноске в складскую проводку - inventTrans.inventTransIdReturn).
Денис, позволю себе все же не согласиться.
Проблема действительно есть. И мы её лечили таким же способом как предлагает 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>
}
Статический метод is3790_FixInentTransIdReturn возвращает true. Введен для отладки, чтобы можно было модификацию включать по условию.
За это сообщение автора поблагодарили: gl00mie (5), Aquarius (1).
Старый 27.06.2013, 10:59   #3  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,983 / 3273 (117) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Сообщение от fed Посмотреть сообщение
...При этом дата возвращаемого заказа не берется во внимание. Даже если у вас возвращен заказ трехлетней давности, система все равно полезет в старые закрытые списания, посчитает их себестоимость и переоценит приход в соответствии с этой себестоимостью...
Ну вот это по-моему и неправильно. Нужно чтобы была такая же логика как для приходных проводок, так как в данном случае расходные проводки играют роль приходных - формируют себестоимость. Поэтому надо при их отборе накладывать фильтр : дата финансовая <= дате закрытия/пересчета
За это сообщение автора поблагодарили: Aquarius (1).
Старый 27.06.2013, 11:16   #4  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,913 / 5736 (197) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Цитата:
Сообщение от Logger Посмотреть сообщение
Ну вот это по-моему и неправильно. Нужно чтобы была такая же логика как для приходных проводок, так как в данном случае расходные проводки играют роль приходных - формируют себестоимость. Поэтому надо при их отборе накладывать фильтр : дата финансовая <= дате закрытия/пересчета
Нууу - собственно, а почему ? Если у тебя товар не быстро обесценивающийся, то в течении месяца-другого-третьего, ты можешь его принимать по цене списания (подставляя номер лота возврата). Если же тебе товар сильно позже вернули, или же товар быстро устаревающий, то лот возврата не надо указывать, надо просто рассчитать некоторую справедливую цену (скажем - текущая рыночная стоимость - 10%) и по ней оприходовать. Там где-то в строке возврата можно указать себестоимость по которой приходуется...

P.S. Вчитавшись в описание, я наконец понял о чем речь. Если ты приходную проводку переоцениваешь и у тебя разные части расхода по разной себестоимости, то они усредняться. Ok - ну да - есть такая проблема. Но в таком случае, правильнее было бы не ограничивать дату (а что если мы в последнем месяце три раза приходную проводку переоценивали и у нас списание себестоимости по разным приходным себестоимостям), а сделать и включить какую-то специальную галочку (типа - возврат по последней себестоимости), которая будет брать себестоимость из последнего по времени списания по лоту и именно ее использовать для переоценки.
А вообще - как я и сказал - все это зависит от того как в учетной политике описано формирование себестоимости по возврату. Можно 1001 вариант придумать и только один из них реализован в системе. Но это не ошибка, а фича...
За это сообщение автора поблагодарили: Logger (1), Aquarius (1).
Старый 27.06.2013, 11:16   #5  
Aquarius is offline
Aquarius
Участник
 
139 / 29 (1) +++
Регистрация: 08.02.2007
Адрес: Одесса
Большое спасибо всем за ответы.
У нас лот возврата был указан в проводках по заказу изначально
До закрытия проводки по заказу выглядели так:
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 грв.
Однако себестоимость рассчитывается некорректно.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
ошибка при закрытии склада disana DAX: Прочие вопросы 19 11.02.2011 12:23
Ошибка при закрытии склада vazerdim DAX: Функционал 3 03.03.2010 12:54
Ошибка при закрытии склада jaran DAX: Прочие вопросы 10 24.12.2004 15:56
Ошибка при закрытии склада, при закрытии более ранней датой, чем пересчет Berkoff DAX: Функционал 2 25.10.2004 17:52
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 21:24.