07.10.2020, 18:22 | #1 |
Участник
|
Получение остатков при включенном складе
Такая задача
Нужно получить запросом(т.е. быстро, без создания класса для каждой строки) список с полями Номенклатура, Склад, Значение AvailPhysical(то которое выводится в стандартной форме В наличии Какой вообще правильный и наиболее быстрый способ получения такого списка? Я так понимаю при включенном складе часть остатков хранится в WHSInventReserve, часть в InventSum, как это все соединить вместе? Версия Ax2012R3 последний CU |
|
07.10.2020, 22:34 | #2 |
Banned
|
InventAvailabilityProvider:
X++: InventAvailabilityByUnit result; if (_search.isItemWHSEnabled()) { WHSInventReserveQty whsInventReserveQty = WHSInventReserveQty::newFromParms(_search.inventTable(), _search.inventDimCriteria(), _search.inventDimCriteriaParm(), _search.inventSum()); result = InventAvailabilityByUnit::newFromParms(whsInventReserveQty, whsInventReserveQty); } else if (_search.isInventSumSet()) { InventSumAvailability inventSumAvailability = InventSumAvailability::newFromInventSum(_search.inventSum()); result = InventAvailabilityByUnit::newFromParms(inventSumAvailability, inventSumAvailability); } else { InventOnHandQty inventOnHandQty = InventOnHandQty::newParameters(_search.itemId(), _search.inventDimCriteria(), _search.inventDimCriteriaParm()); result = InventAvailabilityByUnit::newFromParms(inventOnHandQty, inventOnHandQty); } return result; |
|
08.10.2020, 00:57 | #3 |
Участник
|
Ну да, это дисплей метод AvailPhysical . Вопрос - как эти данные получить запросом, сразу для всех номенклатур, без создания класса для каждой номенклатуры.
В варианте "без склада" это будет типа того что написано ниже X++: while select ItemId, sum(AvailPhysical) from inventSum group by ItemId join InventLocationId from inventDim group by InventLocationId where inventSum.InventDimId == inventDim.InventDimId .. |
|
08.10.2020, 08:22 | #4 |
Участник
|
А чем union не устраивает ? В том плане, что как писал Евгений - для номенклатуры используется ИЛИ, т.е. остатки либо по inventsum считать, либо по WHSInventReserve.
Интересует сам запрос по WHSInventReserve ? C WHS опыта мало, но я бы смотрел в сторону следующих методов(если уровень склада одинаков во всех иерархиях) WhsInventOnHand\getReserveAvailQty WhsInventOnHand\getAvailPhysicalForLevel Либо запрос из SP, в случае, если до склада есть другие аналитики (например у вас иерархия [статус, сайт, склад]), возможно запрос можно использовать и более универсально - для всех данных, правда по производительности может быть хуже чем из классов AX 2012 R3. Ускорение sp_WHSOnHand и sp_WHSOnHandWithDelta В итоге должно получится примерно следующее : X++: //ваш запрос по inventsum union //думаю здесь запрос по inventReserve в реальности будет по сложнее select ItemId, minOf(AvailPhysical) from inventReserve group by ItemId where inventReserve.HierarchyLevel >= locationLevel join InventLocationId from inventDim group by InventLocationId where inventReserve.InventDimId == inventDim.InventDimId //или select ItemId, sum(AvailPhysical) from inventReserve group by ItemId where inventReserve.HierarchyLevel == locationLevel join InventLocationId from inventDim group by InventLocationId where inventReserve.InventDimId == inventDim.InventDimId // или запрос из SP
__________________
Sergey Nefedov |
|
|
За это сообщение автора поблагодарили: trud (1). |
08.10.2020, 08:46 | #5 |
Участник
|
Цитата:
Т.е. у меня скорее вопрос - как правильно то делать, чтобы покрыть все случаи. Как разграничивать этот union - где-то делается с WHSInventEnabled(таблица содержащая одно поле ItemId), где-то с WHSInventReserve Нашел документ, который описывает структуру, но в нем только обращение через API https://www.microsoft.com/en-gb/down....aspx?id=43284 |
|
|
За это сообщение автора поблагодарили: Vadik (1), Logger (3). |
08.10.2020, 09:33 | #6 |
Участник
|
Про не одинаков - это характеристика номенклатуры, ну т.е. для ItemId уровень определяется однозначно.
Но я скорее о том, что если уровень склада в иерархии 1-2 то получить можно условно простым запросом по whsinventReserve(т.к. нет пустых аналитик перед складом), а вот если склад уже ниже, то у нас есть пустые аналитики в иерархии и в таких случаях система лезет за получением остатка в SP и запрос нужно скорее всего из неё брать за базу и менять, можно ли как то получить просто запросом из WHSInventRerserve - типа select ItemId, sum(AvailPhysical) from inventReserve where HierarchyLevel = locationLevel не ясно.
__________________
Sergey Nefedov |
|
08.10.2020, 14:12 | #7 |
Модератор
|
Критерии "правильности" и "лучшести" зависят от задачи. Если нужно быстро получить остатки по нескольким / многим / всем номенклатурам и 100% актуальность данных некритична, можно посмотреть как в D365 в ритейле product availability считается. Там снэпшот остатков который инкрементно батчем обновляется, а потом агрегируется и отправляется в channel DB. Понятно что есть отставание от реального склада, но зато быстро и в оффлайне работает
__________________
-ТСЯ или -ТЬСЯ ? Последний раз редактировалось Vadik; 08.10.2020 в 14:15. |
|
13.10.2020, 10:37 | #8 |
Участник
|
В итоге сделал так - в начале получаются остатки из InventSum
X++: while select sum(AvailPhysical), sum(PhysicalInvent), sum(OnOrder), sum(ReservOrdered), sum(ReservPhysical) from inventSum group by ItemId where inventSum.ClosedQty == NoYes::No join InventLocationId from inventDim group by InventLocationId where inventDim.InventDimId == inventSum.InventDimId && inventDim.InventLocationId == _inventLocationId X++: while select sum(AvailPhysical), sum(ReservOrdered), sum(ReservPhysical) from WHSInventReserve group by ItemId join WHSReservationHierarchyItem group by ItemId where WHSReservationHierarchyItem.ItemId == WHSInventReserve.ItemId && WHSReservationHierarchyItem.ItemDataAreaId == WHSInventReserve.dataAreaId join WHSReservationHierarchyElement group by DimensionFieldId where WHSReservationHierarchyElement.DimensionFieldId == fieldNum(InventDim, InventLocationId) && WHSReservationHierarchyElement.ReservationHierarchy == WHSReservationHierarchyItem.ReservationHierarchy && WHSReservationHierarchyElement.ReservationHierarchyLevel == WHSInventReserve.HierarchyLevel join InventLocationId from inventDim group by InventLocationId where inventDim.InventDimId == WHSInventReserve.InventDimId && inventDim.InventLocationId == _inventLocationId ... |
|
|
За это сообщение автора поблагодарили: fed (5), EVGL (5), raz (5), sukhanchik (8), Logger (5), SRF (1). |
13.10.2020, 10:53 | #9 |
Участник
|
А насколько быстрее работает group by inventlocationid по сравнению с exist join? Там же и так есть фильтр по складу.
|
|
13.10.2020, 14:48 | #10 |
Участник
|
не думаю что есть какая-то разница
|
|
13.10.2020, 21:25 | #11 |
Участник
|
|
|