12. INVENTORY DASHBOARD

12. INVENTORY DASHBOARD


ENTIDADES GOLD DEL TABLERO DE INVENTARIOS 

El Tablero de Inventario está compuesto por entidades que consolidan información clave de órdenes de compra, órdenes de venta, órdenes de producción y tablas descriptivas (tablas TXT). Su objetivo es proporcionar una proyección de stock a futuro, permitiendo una gestión eficiente de inventarios basada en:

  • Materiales comprometidos (en proceso de venta). 
  • Stock entrante (en proceso de compra). 
  • Transferencia de stock (movimientos internos de materiales). 
  • Stock en producción (materiales en órdenes de fabricación). 

Estas entidades permiten visualizar la disponibilidad de materiales y prever posibles faltantes o excesos, optimizando la planificación de suministros y el cumplimiento de pedidos.




Entidades que componen el Tablero de Inventarios 

Las siguientes entidades forman parte de este modelo:

  1. OI_GOLD_SD_OPEN_TRACKER_ECC.sql
  2. OI_GOLD_SD_OPEN_TRACKER_RECIVINGS_ECC.sql
  3. OI_GOLD_SD_INVENTORY_ECC.sql


OI_GOLD_SD_OPEN_TRACKER_ECC 

Este modelo pertenece a la capa Gold de la arquitectura medallón y se compone de la entidad Silver de órdenes de venta. Su propósito es identificar órdenes de venta no completadas con fecha de entrega a futuro, permitiendo estimar el stock comprometido.




Dependencias 

  • OI_SILVER_SD_SALES_ORDER_ECC (Órdenes de Venta - Capa Silver)
    Contiene información consolidada de las órdenes de venta dentro del módulo SD en SAP ECC.
    <client>_<environment>_SD_ORDENES_VENTA_SILVER
  • MARD (Stock de Material por Almacén)
    Almacena información sobre los niveles de inventario de los materiales en cada almacén, permitiendo gestionar la disponibilidad de stock en tiempo real.
    <client>_<environment>_MM_MATERIAL_ALMACEN
  • T001W (Centros de Planta)
    Contiene la lista de centros en SAP, representando ubicaciones físicas donde se realizan operaciones logísticas, productivas o de almacenamiento.
    <client>_<environment>_DM_PLANTAS
  • TVKOT (Organización de Ventas - Descripción)
    Contiene las descripciones de las organizaciones de ventas en diferentes idiomas, permitiendo identificar las estructuras comerciales dentro de SAP.
    <client>_<environment>_DM_ORGANIZACION_VENTAS_TXT
  • TVTWT (Canales de Distribución - Descripción)
    Almacena las descripciones de los canales de distribución utilizados en SAP SD, facilitando la segmentación y gestión de ventas.
    <client>_<environment>_DM_CANAL_DISTRBUCION_TXT
  • TSPAT (Grupo de Estadísticas de Materiales)
    Contiene información sobre la clasificación de materiales para estadísticas de ventas y análisis de desempeño comercial.
    <client>_<environment>_DM_SECTOR_COMERCIAL_TXT
  • T023T (Grupo de Materiales - Descripción)
    Almacena las descripciones de los grupos de materiales en diferentes idiomas, facilitando la categorización de productos.
    <client>_<environment>_DM_GRUPO_MATERIAL_TXT
  • TVKBT (Grupos de Clientes - Descripción)
    Contiene las descripciones de los grupos de clientes en SAP.
    <client>_<environment>_DM_OFICINA_VENTAS_TXT
  • T179T (Jerarquía de Materiales - Descripción)
    Almacena la información estructurada de la jerarquía de materiales, facilitando la clasificación de productos dentro del sistema.
    <client>_<environment>_DM_JERARQUIA_MATERIALES_TXT
  • MAKT (Descripción de Materiales)
    Contiene las descripciones de los materiales en diferentes idiomas.
    <client>_<environment>_MM_MATERIAL_DESCRIPCION
  • KNA1 (Maestro de Clientes - Datos Generales)
    Almacena los datos generales de los clientes en SAP.
    <client>_<environment>_SD_MAESTRO_CLIENTES



Supuestos 

  • Se consideran órdenes de venta completadas únicamente aquellos registros donde statusglob_vbuk = 'C'
  • El estado del inventario se calcula con la suma de la cantidad disponible de stock libre para su uso, consolidado por planta y material:
    SUM(mard.libre_utiliz) AS disponible, agrupado por planta y material. 
  • El estado de entrega se determina como la diferencia en días entre la fecha actual y la fecha de entrega estimada, calculada de la siguiente manera:
    dateDiff('day', NOW(), toDate(sso.feentrega_vbep, '%Y%m%d')) AS delivery_time



Instalación 

La instalación de esta entidad sigue el mismo proceso que OI_SILVER_SD_SALES_ORDER_ECC, ya que ambas forman parte de una instalación en cadena.

Es importante asegurarse de que todas las dependencias y entidades previas en la cadena de instalación estén correctamente configuradas antes de proceder con la ejecución.

Para desplegar el modelo, ejecutar el siguiente comando:

docker-compose up -d dbt_oi_sales_order --build



Modelo sql ejecutado 

  1. {{ config(
  2.    order_by='(mandante_vbak, docvtas_vbak, posicion_vbap)',
  3.    engine='ReplacingMergeTree(_version)',
  4.    materialized='incremental',
  5.    incremental_strategy='append',
  6.     pre_hook=[
  7.         "{% if is_incremental() %}
  8.             ALTER TABLE {{this}} DELETE
  9.             WHERE (docvtas_vbak) NOT IN (
  10.                 SELECT docvtas_vbak 
  11.                 FROM {{ ref('OI_SILVER_SD_SALES_ORDER_ECC') }})
  12.         {% endif %}"
  13.     ],
  14.     post_hook=[
  15.         "ALTER TABLE {{this}} DELETE
  16.        WHERE statusglob_vbuk = 'C'",
  17.     ]
  18. ) }}

  19. /*
  20. * SOLO PROCESARÁ VENTAS NUEVAS O REALIZARÁ UN RECALCULO EN CASO DE UN VENTA ELIMINADA.
  21. */
  22. WITH new_data AS (
  23.     SELECT

  24.         sso.mandante_vbak as mandante_vbak,
  25.         sso.docvtas_vbak as docvtas_vbak, 
  26.         sso.posicion_vbap as posicion_vbap,
  27.         sso.material_vbap as material_vbap, 
  28.         sso.centro_vbap as centro_vbap,
  29.         sso.ctdped_vbep as ctdped_vbep,
  30.         formatDateTime(toDate(sso.feentrega_vbep, '%Y%m%d'), '%Y-%m-%d') as fecha_entrega,
  31.         formatDateTime(toDate(sso.feentrega_vbep, '%Y%m%d'), '%Y-%m') as mes_entrega,

  32.         sso.solic_vbak as solic_vbak,
  33.         sso.grclient_vbkd as grclient_vbkd,
  34.         sso.pais_vbpa as pais_vbpa,
  35.         sso.feentrega_vbep as feentrega_vbep,
  36.         sso.fechsol_vbak as fechsol_vbak,
  37.         sso.direccion_vbpa as direccion_vbpa,
  38.         sso.condexp_vbak as condexp_vbak,
  39.         sso.orgventas_vbak as orgventas_vbak,
  40.         sso.candistr_vbak as candistr_vbak,
  41.         sso.oficvta_vbak as oficvta_vbak,
  42.         sso.jquiaprod_vbap as jquiaprod_vbap,
  43.         sso.sector_vbap as sector_vbap,
  44.         sso.priorentr_vbap as priorentr_vbap,
  45.         sso.gpoartic_vbap as gpoartic_vbap,
  46.         sso.ruta_vbap as ruta_vbap,
  47.         sso.zona_vbpa as zona_vbpa,
  48.         sso.statusglob_vbuk as statusglob_vbuk,
  49.         sso._version as updated_at

  50.     FROM {{ ref('OI_SILVER_SD_SALES_ORDER_ECC')}} as sso FINAL
  51.     {% if is_incremental() %}
  52.     WHERE sso._version >= (SELECT max(updated_at) FROM {{this}})
  53.     {% endif %}
  54. ),

  55. inventory as (
  56.     SELECT 
  57.         mard.mandante as mandante,
  58.        mard.material as material,
  59.        mard.centro as centro,
  60.         SUM(mard.libre_utiliz) disponible
  61.         FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_ALMACEN') }} mard FINAL
  62.         GROUP BY mard.mandante, mard.material, mard.centro
  63. )

  64. SELECT DISTINCT
  65.     sso.mandante_vbak as mandante_vbak,
  66.    sso.docvtas_vbak as docvtas_vbak, 
  67.    sso.posicion_vbap as posicion_vbap,
  68.    sso.material_vbap as material_vbap, 
  69.    sso.centro_vbap as centro_vbap,
  70.    sso.ctdped_vbep as ctdped_vbep,
  71.    sso.fecha_entrega as fecha_entrega,
  72.    sso.mes_entrega as mes_entrega,

  73.    sso.solic_vbak as solic_vbak,
  74.    sso.grclient_vbkd as grclient_vbkd,
  75.    sso.pais_vbpa as pais_vbpa,
  76.    sso.feentrega_vbep as feentrega_vbep,
  77.    sso.fechsol_vbak as fechsol_vbak,
  78.    sso.direccion_vbpa as direccion_vbpa,
  79.    sso.condexp_vbak as condexp_vbak,
  80.    sso.orgventas_vbak as orgventas_vbak,
  81.    sso.candistr_vbak as candistr_vbak,
  82.    sso.oficvta_vbak as oficvta_vbak,
  83.    sso.jquiaprod_vbap as jquiaprod_vbap,
  84.    sso.sector_vbap as sector_vbap,
  85.    sso.priorentr_vbap as priorentr_vbap,
  86.    sso.gpoartic_vbap as gpoartic_vbap,
  87.    sso.ruta_vbap as ruta_vbap,
  88.    sso.zona_vbpa as zona_vbpa,
  89.    sso.statusglob_vbuk as statusglob_vbuk,
  90.    sso.updated_at as updated_at,
  91.    dateDiff('day',  NOW(), toDate(sso.feentrega_vbep, '%Y%m%d')) as delivery_time,
  92.     LEAST(delivery_time, 8) as status,
  93.     
  94.     ssiv.disponible as stock_disponible, 

  95.     t001w.nom1 as centro,
  96.    t001w.idioma  AS idioma,
  97.    tvkot.denomin AS orgventas,
  98.    tvtwt.denomin AS candistr,
  99.    tspat.denomin AS sector,
  100.    t023t.gpoartic1 AS gpoartic,
  101.    tvkbt.denomin AS oficvta,
  102.    t179t.denom  as jquiaprod,

  103.     makt.denominacion as material,
  104.     kna1.nombre1 as cliente,
  105.     --tvsbt.denomin as condexp,

  106. --     tvrot.name as route,
  107. -- tzon.ctryreg as ctryreg,
  108. -- tzon.descript as zone_txt,
  109.    now64() as _version
  110. FROM new_data as sso
  111. --TODO: CAMBIAR LUEGO
  112. LEFT JOIN inventory as ssiv 
  113.     ON ssiv.material  = sso.material_vbap and ssiv.centro  = sso.centro_vbap
  114. LEFT JOIN (SELECT cp, nom1, centro , idioma   FROM {{ source('oneconnect', 'PR0_B_DM_PLANTAS') }} FINAL) AS  t001w  on t001w.centro  = sso.centro_vbap AND t001w.idioma ='S'
  115. LEFT JOIN (SELECT denomin, orgventas, idioma FROM {{ source('oneconnect', 'PR0_B_DM_ORGANIZACION_VENTAS_TXT') }} FINAL) AS tvkot on tvkot.orgventas  = sso.orgventas_vbak  and tvkot.idioma = t001w.idioma
  116. LEFT JOIN (SELECT denomin, candistr, idioma FROM {{ source('oneconnect', 'PR0_B_DM_CANAL_DISTRBUCION_TXT') }} FINAL) AS tvtwt  on tvtwt.candistr  = sso.candistr_vbak  and tvtwt.idioma = t001w.idioma
  117. LEFT JOIN (SELECT idioma, sector, denomin FROM {{ source('oneconnect', 'PR0_B_DM_SECTOR_COMERCIAL_TXT') }} FINAL) AS  tspat  on tspat.sector  = sso.sector_vbap and tspat.idioma = t001w.idioma
  118. LEFT JOIN (SELECT gpoartic1, gpoartic, idioma FROM {{ source('oneconnect', 'PR0_B_DM_GRUPO_MATERIAL_TXT') }} FINAL) AS t023t  on  t023t.gpoartic = sso.gpoartic_vbap and t023t.idioma = t001w.idioma
  119. LEFT JOIN (SELECT idioma, oficvta, denomin  FROM {{ source('oneconnect', 'PR0_B_DM_OFICINA_VENTAS_TXT') }} FINAL) AS tvkbt  on tvkbt.oficvta = sso.oficvta_vbak and tvkbt.idioma = t001w.idioma
  120. LEFT JOIN (SELECT idioma, jquiaprod, denom  FROM {{ source('oneconnect', 'PR0_B_DM_JERARQUIA_MATERIALES_TXT') }} FINAL) AS t179t  on t179t.jquiaprod = sso.jquiaprod_vbap and t179t.idioma = t001w.idioma
  121. LEFT JOIN (SELECT denominacion, material, idioma FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_DESCRIPCION') }} FINAL) AS makt  on makt.material = sso.material_vbap and makt.idioma = t001w.idioma
  122. LEFT JOIN (SELECT nombre1, cliente, idioma FROM {{ source('oneconnect', 'PR0_B_SD_MAESTRO_CLIENTES') }} FINAL) AS kna1  on kna1.cliente = sso.solic_vbak and kna1.idioma = t001w.idioma
  123. --LEFT JOIN (SELECT idioma, condexp, denomin FROM {{ source('oneconnect', 'PR0_B_DM_COND_EXPEDICION_TXT') }} FINAL) AS tvsbt  on tvsbt.condexp = sso.condexp_vbak and tvsbt.idioma = t001w.idioma

  124. ORDER BY fecha_entrega ASC




OI_GOLD_SD_OPEN_TRACKER_RECIVINGS_ECC 

Este modelo consolida información clave de órdenes de compra, órdenes de producción y transferencias de stock, enfocándose en aquellos registros con fechas de entrega futuras y estados no completados. Su objetivo es proporcionar una visión integral de las operaciones pendientes, facilitando el seguimiento y la planificación del inventario.

Componentes del Modelo:

  • Órdenes de compra: Información sobre los materiales solicitados a proveedores, asegurando visibilidad de los suministros entrantes. 
  • Órdenes de producción: Datos de los productos en proceso de fabricación, permitiendo anticipar la disponibilidad de manufactura. 
  • Transferencias de stock: Registros de movimientos de materiales entre plantas, optimizando la gestión de inventario interno. 

El modelo filtra los registros con estados distintos a "completado" y fechas de entrega posteriores a la fecha actual, asegurando un seguimiento preciso de las actividades en curso y su impacto en la disponibilidad de stock.




Dependencias 

  • OI_SILVER_MM_PURCHASE_ORDER_ECC (Órdenes de Compra - Capa Silver)
    Contiene información consolidada de las órdenes de compra dentro del módulo MM en SAP ECC, proporcionando visibilidad sobre los materiales solicitados a proveedores.
    OI_SILVER_MM_PURCHASE_ORDER_ECC
  • OI_SILVER_PP_PRODUCTION_ORDER_ECC (Órdenes de Producción - Capa Silver)
    Almacena datos estructurados de las órdenes de producción en el módulo PP de SAP, permitiendo el análisis y seguimiento de materiales en proceso de fabricación.
    OI_SILVER_PP_PRODUCTION_ORDER_ECC
  • MARD (Stock de Material por Almacén)
    Almacena información sobre los niveles de inventario de los materiales en cada almacén, permitiendo gestionar la disponibilidad de stock en tiempo real.
    <client>_<environment>_MM_MATERIAL_ALMACEN
  • T001W (Centros de Planta)
    Contiene la lista de centros en SAP, representando ubicaciones físicas donde se realizan operaciones logísticas, productivas o de almacenamiento.
    <client>_<environment>_DM_PLANTAS
  • MAKT (Descripción de Materiales)
    Contiene las descripciones de los materiales en diferentes idiomas.
    <client>_<environment>_MM_MATERIAL_DESCRIPCION



Supuestos 

  • Se considera Orden de Compra no completadas a los registros de la entidad OI_SILVER_MM_PURCHASE_ORDER_ECC filtros:

...

fechaentrgestad_eket <> '00000000'

and fechaentrgestad_eket <> ''

and cantidad_pedido_ekpo <> 0

and tipo_posicion_ekpo <> '7'

and entregado_compl_ekpo <> 'X'

and material_ekpo <> ''

...


  • Se considera Transferencia de Stock no completados a los registros de la entidad OI_SILVER_MM_PURCHASE_ORDER_ECC con filtros:

...

fechaentrgestad_eket <> '00000000'

and fechaentrgestad_eket <> ''

and cantidad_pedido_ekpo <> 0

and tipo_posicion_ekpo = '7'

and entregado_compl_ekpo <> 'X'

and material_ekpo <> ''

...


  • Se considera Orden de Producción no completados o en progreso a los registros de la entidad OI_SILVER_PP_PRODUCTION_ORDER_ECC con los siguientes filtros:

...

fin_programado_afpo <> '' 

and fin_programado_afpo  <> '00000000'

and notiffinal_afru <> 'X'

...





Instalación 

docker-compose up -d dbt_oi_production_order --build




Modelo sql ejecutado 

  1. {{ config(
  2.    order_by='(operacion, nro_orden, posicion, material, centro)',
  3.    engine='ReplacingMergeTree(_version)',
  4.    materialized='incremental',
  5.    incremental_strategy='append'
  6. ) }}

  7. WITH inventory as (
  8.     
  9.     SELECT 
  10.         mard.mandante as mandante,
  11.        mard.material as material,
  12.        mard.centro as centro,
  13.         SUM(mard.libre_utiliz) disponible
  14.     FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_ALMACEN') }} mard FINAL
  15.     GROUP BY mard.mandante, mard.material, mard.centro
  16. ),

  17. purchase_orders as (

  18.    SELECT
  19.        'Orden de Compra' as operacion,
  20.         ospo.doccompras_ekpo as nro_orden,
  21.         ospo.posicion_ekpo as posicion,
  22.         ospo.centro_ekpo as centro, 
  23.         ospo.material_ekpo as material, 
  24.         formatDateTime(toDate(ospo.fechaentrgestad_eket, '%Y%m%d'), '%Y-%m-%d') as fecha_entrega,
  25.         ospo.fechaentrgestad_eket as fecha_entrega_str,
  26.         ospo.cantidad_pedido_ekpo as cantidad_pedido,
  27.         formatDateTime(toDate(ospo.fechaentrgestad_eket, '%Y%m%d'), '%Y-%m') as mes_entrega,
  28.         ospo._version as purchase_updated_at,
  29.        toDateTime64(0, 8) as transfer_updated_at,
  30.        toDateTime64(0, 8) as production_updated_at

  31.     FROM {{ ref('OI_SILVER_MM_PURCHASE_ORDER_ECC') }} AS ospo FINAL
  32.     WHERE
  33.         
  34.         ospo.fechaentrgestad_eket <> '00000000'
  35.         and ospo.fechaentrgestad_eket <> ''
  36.         and ospo.cantidad_pedido_ekpo <> 0
  37.         and ospo.tipo_posicion_ekpo <> '7'
  38.         and ospo.entregado_compl_ekpo <> 'X'
  39.         and ospo.material_ekpo <> ''
  40.         {% if is_incremental() %}
  41.         and ospo._version >= (select max(purchase_updated_at) from {{this}})
  42.         {% endif %}
  43. ),

  44. stock_orders as (

  45.    SELECT
  46.         'Transferencia de Stock' as operacion,
  47.         ospo.doccompras_ekpo as nro_orden,
  48.         ospo.posicion_ekpo as posicion,
  49.         ospo.centro_ekpo as centro_ekpo, 
  50.         ospo.material_ekpo as material, 
  51.         formatDateTime(toDate(ospo.fechaentrgestad_eket, '%Y%m%d'), '%Y-%m-%d') as fecha_entrega,
  52.         ospo.fechaentrgestad_eket as fecha_entrega_str,
  53.         ospo.cantidad_pedido_ekpo as cantidad_pedido,
  54.         formatDateTime(toDate(ospo.fechaentrgestad_eket, '%Y%m%d'), '%Y-%m') as mes_entrega,
  55.        toDateTime64(0, 8) as purchase_updated_at,
  56.        ospo._version as transfer_updated_at,
  57.        toDateTime64(0, 8) as production_updated_at
  58.     FROM {{ ref('OI_SILVER_MM_PURCHASE_ORDER_ECC') }} AS ospo FINAL
  59.     WHERE
  60.         ospo.fechaentrgestad_eket <> '00000000'
  61.         and ospo.fechaentrgestad_eket <> ''
  62.        and ospo.cantidad_pedido_ekpo <> 0
  63.        and ospo.tipo_posicion_ekpo = '7'
  64.        and ospo.entregado_compl_ekpo <> 'X'
  65.        and ospo.material_ekpo <> ''
  66.         {% if is_incremental() %}
  67.         and ospo._version >= (select max(transfer_updated_at) from {{this}})
  68.         {% endif %}
  69. ),

  70. production_orders as (

  71.    SELECT
  72.        'Orden de Producción' as operacion,
  73.         ssp.orden_afpo as nro_orden,
  74.         ssp.n_posicion_afpo as posicion,
  75.         ssp.centro_afpo as centro,
  76.         ssp.numero_material_afpo as material,
  77.         formatDateTime(toDate(ssp.fin_programado_afpo, '%Y%m%d'), '%Y-%m-%d') as fecha_entrega,
  78.         ssp.fin_programado_afpo as fecha_entrega_str,
  79.         ssp.cantidad_pos_afpo as cantidad_pedido,
  80.         formatDateTime(toDate(ssp.fin_programado_afpo, '%Y%m%d'), '%Y-%m') as mes_entrega,
  81.        toDateTime64(0, 8) as purchase_updated_at,
  82.        toDateTime64(0, 8) as transfer_updated_at,
  83.        ssp._version as production_updated_at
  84.     FROM {{ ref('OI_SILVER_PP_PRODUCTION_ORDER_ECC') }} AS ssp FINAL
  85.     where 
  86.         ssp.fin_programado_afpo <> '' 
  87.         and ssp.fin_programado_afpo  <> '00000000'
  88.         and ssp.notiffinal_afru <> 'X'
  89.         {% if is_incremental() %}
  90.         and ssp._version >= (select max(production_updated_at) from {{this}})
  91.         {% endif %}
  92. ),

  93. plants as (
  94.     SELECT
  95.         nom1, 
  96.         centro, 
  97.         idioma   
  98.     FROM {{ source('oneconnect', 'PR0_B_DM_PLANTAS') }} 
  99.     FINAL
  100. ),

  101. material_desc as (
  102.     SELECT 
  103.         denominacion, 
  104.         material, 
  105.         idioma 
  106.     FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_DESCRIPCION') }} 
  107.     FINAL
  108. )

  109. SELECT 
  110.    orders.operacion as operacion,
  111.     orders.nro_orden as nro_orden,
  112.     orders.posicion as posicion,
  113.     orders.centro as centro,
  114.    orders.material as material,
  115.     orders.fecha_entrega as fecha_entrega,
  116.    orders.fecha_entrega_str as fecha_entrega_str,
  117.    orders.cantidad_pedido as cantidad_pedido,
  118.     orders.mes_entrega as mes_entrega,
  119.    orders.purchase_updated_at as purchase_updated_at,
  120.    orders.transfer_updated_at as transfer_updated_at,
  121.    orders.production_updated_at as production_updated_at,
  122.    mard.disponible as disponible,
  123.    t001w.nom1  as desc_centro,
  124.    makt.denominacion AS desc_material,
  125.    now64() as _version
  126. FROM (
  127.    SELECT *
  128.    FROM purchase_orders
  129.    UNION ALL
  130.    SELECT *
  131.    FROM  stock_orders
  132.    UNION ALL
  133.    SELECT *
  134.    FROM production_orders
  135. ) AS orders
  136. left JOIN inventory as mard on mard.material = orders.material and mard.centro = orders.centro
  137. left JOIN plants AS t001w  on t001w.centro  = orders.centro AND t001w.idioma = 'S'
  138. left JOIN material_desc as makt on makt.material = mard.material and makt.idioma = t001w.idioma



OI_GOLD_SD_INVENTORY_ECC 

Este modelo proporciona una proyección dinámica del estado del inventario a futuro, integrando información clave de múltiples fuentes para ofrecer una visión completa de la disponibilidad de stock en el tiempo.

Componentes del Modelo:

El modelo combina diversas fuentes de datos para generar una previsión precisa del inventario:

  • Órdenes de ventas: Cantidades comprometidas para entregas futuras, reduciendo la disponibilidad de stock. 
  • Órdenes de compras: Materiales en tránsito desde proveedores, aumentando la disponibilidad proyectada. 
  • Órdenes de producción: Productos en proceso de fabricación, impactando el inventario una vez finalizados. 
  • Transferencias de stock entre plantas: Movimientos internos planificados que afectan la disponibilidad en distintas ubicaciones. 



Dependencias 
  • OI_SILVER_MM_PURCHASE_ORDER_ECC (Órdenes de Compra - Capa Silver)
    Contiene información consolidada de las órdenes de compra dentro del módulo MM en SAP, proporcionando visibilidad sobre los materiales solicitados a proveedores y su impacto en la planificación de inventario.
    <client>_<environment>_MM_ORDENES_COMPRA_SILVER
  • OI_SILVER_PP_PRODUCTION_ORDER_ECC (Órdenes de Producción - Capa Silver)
    Almacena datos estructurados de las órdenes de producción en el módulo PP de SAP, permitiendo el análisis y seguimiento de materiales en proceso de fabricación.
    <client>_<environment>_PP_ORDENES_PRODUCCION_SILVER
  • OI_GOLD_SD_OPEN_TRACKER_ECC (Seguimiento de Órdenes Abiertas - Capa Gold)
    Consolida información de órdenes de venta no completadas con fechas de entrega a futuro, proporcionando un seguimiento del stock comprometido y su impacto en la disponibilidad de inventario.
    <client>_<environment>_SD_ORDENES_ABIERTAS_GOLD
  • MARC (Datos de Material por Centro)
    Almacena información específica de cada material por centro.
    <client>_<environment>_MM_MATERIAL_PLANTA
  • MARD (Stock de Material por Almacén)
    Almacena información sobre los niveles de inventario de los materiales en cada almacén, permitiendo gestionar la disponibilidad de stock en tiempo real.
    <client>_<environment>_MM_MATERIAL_ALMACEN
  • T001W (Centros de Planta)
    Contiene la lista de centros en SAP, representando ubicaciones físicas donde se realizan operaciones logísticas, productivas o de almacenamiento.
    <client>_<environment>_DM_PLANTAS
  • MAKT (Descripción de Materiales)
    Contiene las descripciones de los materiales en diferentes idiomas.
    <client>_<environment>_MM_MATERIAL_DESCRIPCION


Supuestos 

  • Se considera Stock disponible a la operacion SUM(mard.libre_utiliz) agrupado por planta y material. 
  • Se considera Cantidad Recibido por día a la operación ventana de la cantidad esperada de las ordenes de compras, ordenes de producción o transferencias de stock de la entidad OI_GOLD_SD_OPEN_TRACKER_RECIVINGS_ECC :

...

SUM(cantidad_pedido_dia) OVER (PARTITION BY material, centro   ORDER BY fecha_entrega ASC) as cantidad_pedido_dia_ventana,

...


  • Se considera Cantidad de perdido al día a la operación ventana de la cantidad comprometida de las ordenes de ventas:

...

SUM(cantidad_pedido_dia) OVER (PARTITION BY material, centro  ORDER BY fecha_entrega ASC) as cantidad_pedido_dia_ventana

...


  • Se considera Stock futuro a la operación :

...

(stock_disponible + cantidad_recibido_dia_ventana - cantidad_pedido_dia_ventana) as future_stock,

...


  • Se considera Stock actual a la operación :

...

(stock_disponible - cantidad_pedido_dia_ventana)  as actual_stock,

...





Instalación 

docker-compose up -d dbt_oi_sales_order --build





Modelo sql ejecutado 

  1. {{ config(
  2.    order_by='(material, centro, fecha_entrega_str)',
  3.    engine='ReplacingMergeTree(_version)',
  4.    materialized='incremental',
  5.    incremental_strategy='append'
  6. ) }}
  7. /* new_sales_orders: muestra los nuevas ordenes de ventas registradas.
  8. * sales_orders_affected: muestra todas las ordenes de ventas pasadas en el mes y mismo material.
  9. * sales_orders_sumary: Calculo de las ventas por días y periodo.
  10. */
  11. WITH new_sales_orders as (
  12.    select DISTINCT
  13.        got.fecha_entrega as fecha_entrega,
  14.        got.feentrega_vbep as fecha_entrega_str,
  15.        got.mes_entrega  as mes_entrega,
  16.        got.docvtas_vbak as orden,
  17.        got.material_vbap as material,
  18.        got.centro_vbap as centro,
  19.        got.ctdped_vbep as cantidad_pedido, -- KWMENG
  20.        got._version as _version
  21.    FROM {{ ref('OI_GOLD_SD_OPEN_TRACKER_ECC')}} got FINAL
  22.    {% if is_incremental() %}
  23.    WHERE got._version >= (select max(got_version) from {{this}})
  24.    {% endif %}
  25. ),

  26. sales_orders_affected as (
  27.    SELECT 
  28.        *
  29.    FROM new_sales_orders
  30.    {% if is_incremental() %}
  31.     UNION DISTINCT
  32.     SELECT
  33.         got.fecha_entrega as fecha_entrega,
  34.        got.feentrega_vbep as fecha_entrega_str,
  35.        got.mes_entrega  as mes_entrega,
  36.        got.docvtas_vbak as orden,
  37.        got.material_vbap as material,
  38.        got.centro_vbap as centro,
  39.        got.ctdped_vbep as cantidad_pedido,
  40.        got._version as _version
  41.     FROM {{ ref('OI_GOLD_SD_OPEN_TRACKER_ECC')}} AS got FINAL
  42.     where (got.centro_vbap, got.material_vbap) IN (SELECT DISTINCT centro, material FROM new_sales_orders)
  43.     {% endif %}
  44. ),

  45. sales_orders_sumary as (
  46.         SELECT 
  47.            fecha_entrega,
  48.            fecha_entrega_str,
  49.            material,
  50.            centro,
  51.            SUM(cantidad_pedido) as cantidad_pedido_dia,
  52.            MAX(_version) AS _version
  53.        FROM sales_orders_affected
  54.        GROUP BY fecha_entrega,fecha_entrega_str, material, centro
  55. ),

  56. new_orders_receiving  as (
  57.    SELECT DISTINCT 
  58.             operacion,
  59.             fecha_entrega,
  60.             fecha_entrega_str,
  61.             mes_entrega,
  62.            nro_orden,
  63.            cantidad_pedido,
  64.             centro,
  65.             material,
  66.             _version
  67.         FROM {{ ref('OI_GOLD_SD_OPEN_TRACKER_RECIVINGS_ECC')}}
  68.         FINAL
  69.         {% if is_incremental() %}
  70.        WHERE _version >= (select max(goptr_version) from {{this}}) 
  71.        {% endif %}
  72. ),

  73. orders_receiving_affected as (
  74.    SELECT 
  75.        *
  76.    FROM new_orders_receiving
  77.    {% if is_incremental() %}
  78.     UNION DISTINCT
  79.     SELECT
  80.         operacion,
  81.        fecha_entrega,
  82.        fecha_entrega_str,
  83.        mes_entrega,
  84.        nro_orden,
  85.        cantidad_pedido,
  86.        centro,
  87.        material,
  88.        _version as goptr_version
  89.     FROM {{ ref('OI_GOLD_SD_OPEN_TRACKER_RECIVINGS_ECC')}}
  90.    FINAL
  91.     where (centro, material) IN (SELECT DISTINCT centro, material FROM new_orders_receiving)
  92.     {% endif %}
  93. ),

  94. orders_receiving_sumary as (
  95.    SELECT 
  96.         fecha_entrega,
  97.         fecha_entrega_str,
  98.        centro,
  99.        material,
  100.        SUM(cantidad_pedido) as cantidad_recibido_dia,
  101.        MAX(_version) as _version
  102.     FROM orders_receiving_affected
  103.     GROUP BY fecha_entrega, fecha_entrega_str, material, centro
  104. ),

  105. material_quantity_sumary as (
  106.     SELECT *,
  107.     -- SUM(sumary.cantidad_recibido_dia - sumary.quantity_sales_order_day) OVER (PARTITION BY material, centro   ORDER BY fecha_entrega ASC) as orders_sumary,
  108.    SUM(sumary.cantidad_pedido_dia) OVER (PARTITION BY material, centro   ORDER BY fecha_entrega ASC) as cantidad_pedido_dia_ventana,
  109.    SUM(sumary.cantidad_recibido_dia) OVER (PARTITION BY material, centro   ORDER BY fecha_entrega ASC) as cantidad_recibido_dia_ventana
  110.     -- MAX(sumary.cantidad_pedido_total) OVER (PARTITION BY material, centro ) as cantidad_pedido_total
  111.     FROM (
  112.        SELECT 
  113.            greatest(rqs.fecha_entrega, oqs.fecha_entrega) as fecha_entrega,
  114.            greatest(rqs.fecha_entrega_str, oqs.fecha_entrega_str) as fecha_entrega_str,
  115.            greatest(rqs.material, oqs.material) as material,
  116.            greatest(rqs.centro, oqs.centro) as centro,
  117.            
  118.            coalesce(rqs.cantidad_recibido_dia,0) as cantidad_recibido_dia,
  119.            --coalesce(rqs.order_recivings_sum_period,0) as quantity_receivings_period,
  120.            rqs._version as goptr_version,
  121.            
  122.            coalesce(oqs.cantidad_pedido_dia,0) as cantidad_pedido_dia,
  123.            -- coalesce(oqs.cantidad_pedido_total,0) as cantidad_pedido_total,
  124.        
  125.            
  126.            oqs._version as got_version
  127.        FROM sales_orders_sumary as oqs
  128.        FULL JOIN orders_receiving_sumary as rqs 
  129.            ON rqs.centro = oqs.centro and rqs.material = oqs.material and rqs.fecha_entrega_str = oqs.fecha_entrega_str
  130.     ) as sumary
  131. ),

  132. status_inventory as (
  133.    SELECT 
  134.        mard.mandante as mandante,
  135.        mard.material as material,
  136.        mard.centro as centro,
  137.        -- SUM(mard.stockintfr) AS in_transit,
  138.        -- SUM(mard.restricted) AS on_order,
  139.        -- SUM(mard.restricted) AS in_quality_control,
  140.        -- SUM(mard.blocked) AS allocated, --SPEME
  141.        -- SUM(mard.returns) AS damaged, --RETME
  142.        SUM(mard.libre_utiliz) stock_disponible, --LABST
  143.        MAX(marc.stock_maximo) AS stock_maximo, -- MABST
  144.        MAX(marc.stock_seguridad) AS stock_seguridad, --EISBE
  145.        CASE
  146.             WHEN stock_disponible > stock_maximo THEN 'Excess Stock'
  147.             WHEN stock_disponible < stock_seguridad THEN 'Low Stock'
  148.             WHEN stock_disponible = 0 THEN 'Out of Stock'
  149.             ELSE 'Balanced Stock'
  150.        END as status,
  151.        max(mard._version) as _version
  152.    FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_ALMACEN') }} mard FINAL
  153.    INNER JOIN (
  154.        SELECT stock_maximo, stock_seguridad, centro, material 
  155.        FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_PLANTA') }} FINAL
  156.    ) AS marc
  157.        ON mard.centro = marc.centro and mard.material = marc.material
  158.    {% if is_incremental() %}
  159.    WHERE 
  160.        mard._version >= (select max(mard_version) from {{this}}) 
  161.        OR mard.material in (select material from material_quantity_sumary)
  162.    {% endif %}
  163.    GROUP BY mard.mandante, mard.material, mard.centro
  164. )

  165. SELECT 
  166.    mqs.fecha_entrega as fecha_entrega,
  167.    mqs.fecha_entrega_str as fecha_entrega_str,
  168.    mqs.material as material,
  169.    mqs.centro as centro,

  170.    mqs.cantidad_recibido_dia as cantidad_recibido_dia,
  171.    mqs.cantidad_recibido_dia_ventana as cantidad_recibido_dia_ventana,
  172.    -- mqs.cantidad_pedido_total as cantidad_pedido_total,

  173.    mqs.cantidad_pedido_dia as cantidad_pedido_dia,
  174.    mqs.cantidad_pedido_dia_ventana as cantidad_pedido_dia_ventana,
  175.    --mqs.on_hand as quantity_sales_order_period,

  176.    ssin.stock_maximo as stock_maximo,
  177.    ssin.stock_seguridad as stock_seguridad,
  178.    ssin.status as status,
  179.    ssin.stock_disponible  as stock_disponible,
  180.    (ssin.stock_disponible + mqs.cantidad_recibido_dia_ventana - mqs.cantidad_pedido_dia_ventana) as future_stock,
  181.    (ssin.stock_disponible - mqs.cantidad_pedido_dia_ventana)  as actual_stock,
  182.    --SUM(mqs.cantidad_recibido_dia - mqs.quantity_sales_order_day) OVER (PARTITION BY mqs.material, mqs.centro   ORDER BY mqs.fecha_entrega ASC) as future_stock,
  183.    
  184.    t001w.nom1  as plant,
  185.    t001w.cp  as codigo_postal,
  186.    makt.denominacion as desc_material,
  187.    -- ssin.in_transit as  in_transit,
  188.    -- ssin.on_order as on_order,
  189.    -- ssin.allocated as allocated,
  190.    -- ssin.damaged as damaged,
  191.    -- ssin.in_quality_control as in_quality_control,

  192.    ssin._version as updated_at,
  193.    ssin._version as mard_version,
  194.    mqs.goptr_version as goptr_version,
  195.    mqs.got_version as got_version,
  196.    now64() as _version
  197. FROM material_quantity_sumary as mqs 
  198. LEFT JOIN status_inventory ssin
  199.    ON mqs.material = ssin.material and mqs.centro = ssin.centro
  200. LEFT JOIN ( SELECT cp, nom1, centro, idioma FROM {{ source('oneconnect', 'PR0_B_DM_PLANTAS') }} FINAL ) AS  t001w  
  201.    ON t001w.centro  = mqs.centro AND t001w.idioma ='S'
  202. LEFT JOIN (SELECT denominacion, material, idioma FROM {{ source('oneconnect', 'PR0_B_MM_MATERIAL_DESCRIPCION') }} FINAL) AS makt  
  203.    ON makt.material = mqs.material and makt.idioma ='S'

    • Related Articles

    • INVENTORY DASHBOARD

      Tablero de Inventarios Descripción General Propósito: El Tablero de Inventario está compuesto por entidades que consolidan información clave de órdenes de compra, órdenes de venta y órdenes de producción para mostrar los materiales entrantes y ...
    • INVOICE DASHBOARD

      Tablero de Facturación Descripción General Propósito: Análisis de ventas y facturación mensual. Fuente de Datos: ClickHouse. Instalación del Tablero Paso 1: Importar el JSON en Grafana Iniciar sesión en Grafana. Ir a Dashboards → Manage → Import. ...
    • PRODUCCTION DASHBOARD

      Tablero de Producción Descripción General Propósito: Seguimiento de ordenes y el seguimiento del performance de los procesos de producción, como la cantidad, calidad y eficiencia. Fuente de Datos: ClickHouse. Instalación del Tablero Paso 1: Importar ...
    • 13 PRODUCCTION DASHBOARD

      ENTIDADES GOLD DEL TABLERO DE PRODUCCIÓN El Tablero de Producción está compuesto por múltiples entidades Gold, proporcionando información clave sobre las órdenes de producción y su ejecución por período. Estas entidades permiten el análisis detallado ...
    • 11 INVOICE DASHBOARD

      ENTIDAD GOLD DE TABLERO DE FACTURAS También conocido como Tablero de Ventas, este modelo pertenece a la capa Gold de la arquitectura de medallón y está compuesto por la entidad BI_SILVER_SD_INVOICE_ECC. Su objetivo principal es proporcionar una ...