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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.08.2009, 21:16   #1  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
DAX4 Интеркомпани, ошибка разноски внутрихолдинговой накладной
Для информации, может быть кому понадобится.
Совместно с rINT обнаружили ошибку расчета количества при разноске внутрихолдинговой накладной.
При разноске накладной по внутрихолдинговому заказу на продажу автоматически разносится накладная по внутрихолдинговому заказу на покупку. При этом определяется количество, которое нужно разносить.
В классе SalesFormLetter в методе createParmLine есть следующий код:
X++:
[newSalesParmLine.DeliverNow, newSalesParmLine.RemainBefore      , newSalesParmLine.RemainAfter]        = this.qtySales  (_salesLineOrig, this.interCompanyParmLineQty(_salesLineOrig));
[newSalesParmLine.InventNow , newSalesParmLine.RemainBeforeInvent, newSalesParmLine.RemainAfterInvent]  = this.qtyInvent (_salesLineOrig, this.interCompanyParmLineQty(_salesLineOrig));
То есть, и для количества в единицах заказа на продажу и для количества в единицах складского хранения используется один и тот же метод interCompanyParmLineQty. В результате расчет недопоставки / перпоставки идет неверно если складские единицы и единицы в заказе отличаются.
Решение проблемы: для второго вызова interCompanyParmLineQty результат необходимо пересчитать в складские единицы.
За это сообщение автора поблагодарили: kashperuk (5).
Старый 20.08.2009, 10:23   #2  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
Есть такое дело. Тоже исправлял. Вообще в Intercompany я много косяков в свое время нарыл. Такое ощущение, что эту функциональность плохо тестировали.
Старый 21.08.2009, 13:04   #3  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Raven, а расскажите плз, как именно вы исправляли эту ошибку. Передачей true при втором вызове метода interCompanyParmLineQty?
И, если будет время, было бы здорово привести сценарий, с помощью которого можно воспроизвести это поведение в стандартном функционале.

Спасибо

Последний раз редактировалось kashperuk; 21.08.2009 в 13:07.
За это сообщение автора поблагодарили: Raven Melancholic (4).
Старый 21.08.2009, 15:08   #4  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
Лично я исправлял как Вы сказали:
Цитата:
Передачей true при втором вызове метода interCompanyParmLineQty
Как воспроизвести точно не помню, но вроде так:
создать цепочку заказов (внутрихолд заказ продажи - внутрихолд заказ покупки - исходный заказ) типа прямая поставка. И разнести ее.
За это сообщение автора поблагодарили: Raven Melancholic (2).
Старый 21.08.2009, 15:33   #5  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от JeS Посмотреть сообщение
Лично я исправлял как Вы сказали:

Как воспроизвести точно не помню, но вроде так:
Тогда уже исправили. Спасибо
За это сообщение автора поблагодарили: mazzy (2).
Старый 21.08.2009, 17:17   #6  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
Ну тогда, позвольте я еще про одну ошибку изложу. Скажу сразу, что толком не помню как ее воспроизвести (давненько это было). Кроется она в классе IntercompanyTransferInventDim метод transfer:
X++:
...
while (qr.next())
{
     fromInventTrans = qr.get(tablenum(InventTrans));
     fromInventDim   = qr.get(tablenum(InventDim));
     ...
     fromQty = -fromInventTrans.Qty;
     if (inventDimParm.InventLocationIdFlag && fromInventDim.InventLocationId)
     {
        convInventLocation = new TradeInterCompanyConv();
        salesInventLocationId = fromInventDim.InventLocationId;
        convInventLocation.axInventLocationId(fromValueMap, fromInventDim.InventLocationId);
     }
     ...
     changecompany(_toDataAreaId)
     {
          toInventTrans = null;
          
          select forceplaceholders sum(Qty) from toInventTrans
                           where toInventTrans.InventTransId == _toInventTransId
                           &&   (toInventTrans.StatusReceipt <= StatusReceipt::Registered
                              || toInventTrans.InterCompanyInventDimTransferred == true)
                           &&    toInventTrans.StatusIssue   == StatusIssue::None
         #inventDimJoin(toInventTrans.InventDimId,toInventDim,fromInventDim,inventDimParm);

         fromQty -= toInventTrans.Qty;
        ....
Обратите внимание на третий параметр в макросе #inventDimJoin, и что этот запрос исполняется уже в другой компании. В случае, если стоит настройка, при которой происходит синхронизация складов между компаниями через внешние коды, то последний запрос будет всегда возвращать ноль. То есть лечить надо примерно так: сначала сконвертировать значение fromInventDim.InventLocationId, и только потом использовать его в запросе.

P.S.: надеюсь понятно пояснил, как-то сумбурно получилось, млин
Старый 21.08.2009, 17:20   #7  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
Забыл добавить: DAX 4.0 SP2
Старый 21.08.2009, 21:30   #8  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Raven, а расскажите плз, как именно вы исправляли эту ошибку. Передачей true при втором вызове метода interCompanyParmLineQty?
Нет, Иван, это вариант не для всех ситуаций. Как бы мы не написали метод interCompanyParmLineQty, он работает по данным компании-продавца и даст данные по единицам складского учета компании-продавца. Однако, складские единицы могут различаться в компаниях. Например, наш случай: в закупочной компании складские единицы тонны, а в компании-покупатели килограммы. Если единицы продажи/покупки механизм интеркомпани заставляет делать одинаковыми (какой-бы метод согласования в настройках конечных точкек мы не выбрали, пересчета на стыке компаний не будет), то складские единицы могут различаться. Если метод interCompanyParmLineQty вернет мне тонны, а у меня в покупающей компании складскими единицами являются килограммы, то проблема остается.
Поэтому лучше получить данные методом interCompanyParmLineQty для единиц закупки/продажи и приводить к складским уже в компании-покупателе.
Старый 24.08.2009, 10:11   #9  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
В предыдущем сообщении, где приводил пример кода, я допустил ошибку. Исправляюсь. Код в базовой функциональности должен выглядеть так:
X++:
while (fromInventTrans)
{
     ...
     fromQty = -fromInventTrans.Qty;
     if (inventDimParm.InventLocationIdFlag && fromInventDim.InventLocationId)
     {
        convInventLocation = new TradeInterCompanyConv();
        salesInventLocationId = fromInventDim.InventLocationId;
        convInventLocation.axInventLocationId(fromValueMap, fromInventDim.InventLocationId);
     }
     ...
     changecompany(_toDataAreaId)
     {
          toInventTrans = null;
          
          select forceplaceholders sum(Qty) from toInventTrans
                           where toInventTrans.InventTransId == _toInventTransId
                           &&   (toInventTrans.StatusReceipt <= StatusReceipt::Registered
                              || toInventTrans.InterCompanyInventDimTransferred == true)
                           &&    toInventTrans.StatusIssue   == StatusIssue::None
         #inventDimJoin(toInventTrans.InventDimId,toInventDim,fromInventDim,inventDimParm);

         fromQty -= toInventTrans.Qty;
        ....
Но, вобщем, сути дела это не меняет, но сбить столку кого-нибудь может.
Кстати непонятно зачем нужно было писать такую "этажерку" в этом методе до вышеописанного цикла:
X++:
if (inventDimParm.InventLocationIdFlag && inventDimParm.InventBatchIdFlag && inventDimParm.InventSerialIdFlag)
            {
                select forceplaceholders sum(Qty) from fromInventTrans
                       where fromInventTrans.InventTransId == _fromInventTransId
                       &&    fromInventTrans.StatusIssue   <= _statusIssue
                       &&    fromInventTrans.StatusReceipt == StatusReceipt::None
                join InventLocationId, InventBatchId, InventSerialId from fromInventDim
                     group by InventLocationId, InventBatchId, InventSerialId
                     where fromInventDim.InventDimId == fromInventTrans.InventDimId;
            }
            else if (inventDimParm.InventLocationIdFlag && inventDimParm.InventBatchIdFlag)
            {
                select forceplaceholders sum(Qty) from fromInventTrans
                       where fromInventTrans.InventTransId == _fromInventTransId
                       &&    fromInventTrans.StatusIssue   <= _statusIssue
                       &&    fromInventTrans.StatusReceipt == StatusReceipt::None
                join InventLocationId, InventBatchId from fromInventDim
                     group by InventLocationId, InventBatchId
                     where fromInventDim.InventDimId == fromInventTrans.InventDimId;
            }
            else if (inventDimParm.InventLocationIdFlag && inventDimParm.InventSerialIdFlag)
            {
            ...
и так далее, перебирая всевозможные комбинации аналитик. Почему нельзя было воспользоваться QueryBuild-классами? Может я чего-то не понимаю. Просто если вдруг понадобится добавить скажем еще 2 аналитики, то становится дурно (одну то точно добавить хочется - ГТД).
Старый 24.08.2009, 10:20   #10  
JeS is offline
JeS
Участник
 
61 / 22 (1) +++
Регистрация: 30.10.2007
Адрес: СПб
to Raven
Цитата:
К сожалению это не одна ошибка в этом методе
За это спасибо
Цитата:
даже если отбросить тот факт, что про ГТД в этом методе ничего нет
локализация вообще как-то стороной обошла Intercompany. Помимо ГТД добавлю, что и счета-фактуры не синхронизируются, что вобщем-то тоже напрашивается. Более того, если будешь разносить сразу фактуру во внутрихолдинговом заказе на продажу (в цепочке типа прямой поставки) - то просто выкинет ошибку.
Старый 29.08.2009, 21:08   #11  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1296 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Еще наткнулись. Ка-то странно работает кэш (я про это уже писал, но тогда было только тестирование и как-то не зациклились на этой теме).
У нас в разных компаниях номенклатура ведет себя по разному (например, в производственной это спецификация с номенклатурной группой "Готовая продукция", в торговых домах это номенклатура с номенклатурной группой Товар, ну и т.п.). Поэтому справочник не общий, а в каждой компании свой (есть доработка по вводу и синхронизации определенных номенклатур, но суть не в этом). Так вот, простой код джоба:
X++:
itemId = 'ВентиляторWRW50/40';
intentTable = InventTable::find(itemId);
changeCompany('TRD')
{
   inventTableChg = null;
   select firstOnly inventTableChg where inventTableChg == itemId;
   ...
}
Думаете, что после переключения мы нашли номенклатуру в компании TRD? Сильно ошибаетесь. Возвращена номенклатура компании, в которой запустили джоб! Если в компании запуска не было поиска по этому номенклатурному номеру, то все нормально.
То же происходит если в разных компаниях номера складских лотов совпадают. Если после переключения компании искать складские операции по номеру лота, совпадающему с тем, что был выполнен ранее, то вернется ранее найденный лот.
Помогает включения в код запрет кэша:
X++:
itemId = 'ВентиляторWRW50/40';
intentTable = InventTable::find(itemId);
changeCompany('TRD')
{
   inventTableChg = null;
   inventTableChg.disableCash(true);
   select firstOnly inventTableChg where inventTableChg == itemId;
   ...
}
Если по номенклатуре это можно понять (есть кэширование), то по InventTrans что-то невнятное: у этой таблице CashLookup стоит NONE.
Такое впечатление, то кэш игнорирует компании. вобщем-то можно было бы отключить кэш DAX для всех таблиц (кэш MS SQL хорошо справляется со своей работой), но InventTrans не кэшируется DAX!
Так же понятно, что из-за этой проблемы следует стараться иметь для одних и тех же таблиц в разных компаниях разные уникальные идентификаторы. Но, в нашем случае, это возможно для InventTrans, но не интересно для InvntTable. Можно всегда добавлять disableCach, но в наших разработках мы так и делаем, но есть стандартный код!
PS: кстати, без использования disableCash Trasert MS SQL показывает, что к базе данных было только оно обращение, то есть цепочка: поиск в одной компании, changeCompany, поиск в другой компании того же значения обрабатывает DAx независимо от типа кэширования.

Последний раз редактировалось Raven Melancholic; 29.08.2009 в 21:16.
За это сообщение автора поблагодарили: JeS (1), Kabardian (3).
Теги
ax4.0, intercompany, ошибка, интеркомпани

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Отмена разноски отборочной накладной Iskorka DAX: Функционал 7 03.07.2008 18:23
ошибка при обработке накладной по заказу kashperuk DAX: Функционал 9 18.09.2006 10:40
Настройка разноски Накладной в Заказах vesna DAX: Функционал 19 18.11.2005 16:11
разноска счета на оплату после разноски накладной OlegKocherga DAX: Функционал 14 12.03.2004 17:48
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

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

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

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