HOWTO: Consultar inventario disponible mediante X++

Consultar el nivel de inventario disponible de un artículo es mas complicado de lo que se suele suponer en un principio, aunque no tan complicado como se suele suponer la primera vez que se intenta 🙂

Para consultar cualquiera de los niveles de disponible que nos ofrece Microsoft Dynamics AX (Disponible físico, reservado, ordenado, etc. …) mediante código X++ debemos simular el funcionamiento del formulario estándar dedicado a ello:

  • En primer lugar podemos buscar el disponible por artículo o no. Depende de si queremos saber cuánto disponible hay de un determinado producto, o cuanto disponible hay en una ubicación de cualquier producto (por ejemplo).
  • Por otro lado tendremos que definir un nivel de “profundidad” en las dimensiones de inventario. Nos puede interesar cuánto disponible de un producto tenemos en una ubicación determinada, simplemente cuánto disponible hay en general o en un almacén, o sencillamente si hay disponible o no (en cualquier lugar).
  • Y por último tendremos que saber cuál de los niveles de disponible nos interesa. El inventario físico disponible, el físico reservado, ordenado, ordenado reservado, pedido … cada valor indica un dato que es importante en cada situación.

¿Cómo consultar todos estos casos mediante el estándar?

Microsoft Dynamics AX | Consulta de inventario disponible

El estándar nos ofrece este formulario que contiene toda la información disponible a su máximo nivel de detalle, y nos ofrece varios métodos de filtrar y agrupar esa información si queremos un detalle mas agrupado. El más importante es el botón “Presentación de dimensiones” que hay en la botonera derecha, y que se encuentra en muchos otros formularios del estándar, siempre con el mismo funcionamiento, es un clásico:

Microsoft Dynamics AX | Presentación de dimensiones

Este formulario nos permite contestar a las dos primeras preguntas que planteaba anteriormente. Desde aquí definimos el nivel de detalle al que queremos agrupar el inventario disponible, primero si queremos o no detalle por producto (Campo “Código de artículo“), después detallando qué dimensiones de inventario queremos utlizar, y por último decidiendo si queremos tener en cuenta las transacciones cerradas o mostrar las líneas que NO tienen disponible (Cantidad <> 0).

Configurando correctamente este formulario tendremos el nivel de agupación deseado y simplemente tendremos que elegir entre las columnas que se nos muestran para obtener el valor de inventario deseado.

¿Cómo consultar estos casos mediante código X++?

Para buscar este dato por código hay que proceder de la misma manera. La consulta de disponible se almacena en las tablas InventSum y el estándar nos ofrece algunas ayudas para utilizarlas, entre otras cosas, mediante las clase del mismo nombre. Primero obtenemos los datos al nivel de agrupación deseado, después aplicamos los filtros que necesitemos (para buscar un solo producto, por ejemplo) y luego elegimos la columna adecuada (de la tabla directamente, en este caso).

Por ejemplo, si quisieramos que hacer por código la misma consulta que en el formulario de la captura de pantalla anterior, haríamos lo siguiente:

Query           query;
QueryRun        queryRun;
inventDimParm   inventDimParmCriteria;
inventDimParm   inventDimParmGroupby;
InventDim       inventDim;
InventSum       inventSum;
;

// Códido de artículo
inventDimParmGroupby.ItemIdFlag             = NoYes::Yes;
// Sitio
inventDimParmGroupby.InventSiteId           = NoYes::Yes;
// Almacén
inventDimParmGroupby.InventLocationIdFlag   = NoYes::Yes;
// Ubicación
inventDimParmGroupby.WMSLocationIdFlag      = NoYes::Yes;
// Transacciones cerradas
inventDimParmCriteria.ClosedFlag            = NoYes::No;
// Cantidad <> 0
inventDimParmCriteria.ClosedQtyFlag         = NoYes::Yes;

// La propia tabla InventSum nos monta una Query que podremos iterar
// con los parámetros que hemos configurado
query = InventSum::newQuery(query, '', null, inventDimParmCriteria, inventDimParmGroupby);
// A la query podemos añadir nuestros propios filtros
// (igual que al formulario), por ejemplo: Física disponible > 0
query.dataSourceTable(tablenum(Inventsum)).addRange(fieldnum(inventsum, AvailPhysical)).value('>0');

// Para consultar los datos ejecutamos la query
queryRun = new QueryRun(query);
while (queryRun.next())
{
    // Podemos extraer los valores del queryRun ...
    inventSum = queryRun.get(tableNum(InventSum));
    inventDim = queryRun.get(tableNum(InventDim));

    // ... utilizarlos como queramos
    info(strfmt("Alm: %1, Ubi: %2, Prod: %3, Disp: %4",
                    inventdim.InventLocationId,
                    inventdim.wMSLocationId,
                    inventsum.ItemId,
                    inventsum.AvailPhysical));
}

Descarga

2 comentarios