Documentation: OneBeat Inventory Delta Function
Overview and Metadata
- Purpose: This SQL function,
ONEBEAT_GET_DELTA_INVENTORIES, is designed to extract and transform inventory data, providing a consolidated view of available, in-transit, and reserved stock quantities for the OneBeat store replenishment system. It specifically filters data relevant to a specified company, adhering to pilot phase conditions. - Data Refresh: On-demand or scheduled, depending on the integration and orchestration of the Snowflake environment. This function is typically called by a data pipeline or application.
- Project Context: This function is a critical component of the Store Replenishment Project, currently in a pilot phase focused on Italian stores. Its output directly supports the calculation of replenishment needs.
- Source Tables:
DW_LOADTARGET.DWH.ONEBEAT_COMPANY_RECOD: Contains company-specific recoding and pilot conditions.DW_LOADTARGET.DWH.TBDWFT_STOCK_BY_SIZE: Core stock fact table, providing detailed inventory by size.DW_LOADTARGET.DWH.WHS_ENABLED_ONEBEAT: Lists warehouses enabled for OneBeat, used for filtering relevant stock locations.DW_LOADTARGET.DWH.VWDWFT_STOCK_W_TECNICA_BY_SIZE: Provides "technical location" stock, which represents stock adjustments or movements.DW_LOADTARGET.DWH.TBDWMD_ARTICLE: Contains master data for articles, including business type and sales collection year.
- Output: The function returns a table with aggregated inventory quantities (
location_id,site_qty,sku_id,source_location_id,status_date,transit_qty,avoid_replenishment,reserved_qty), intended for direct consumption by the OneBeat replenishment logic or related dashboards.
Data Flow Diagram
flowchart TD
subgraph Source Tables
subgraph Sourcing
B[TBDWFT_STOCK_BY_SIZE]:::source
D[VWDWFT_STOCK_W_TECNICA_BY_SIZE]:::source
end
subgraph Filtering
A[ONEBEAT_COMPANY_RECOD]:::source
C[WHS_ENABLED_ONEBEAT]:::source
E[TBDWMD_ARTICLE]:::source
end
end
subgraph CTEs
F[FILTERED_COMPANY_CODS]:::cte
G[TOTAL_STOCK]:::cte
H[FORMATTED_STOCK]:::cte
end
I[ONEBEAT_GET_DELTA_INVENTORIES Output]:::output
A -- :COMPANY --> F
B --> G
C --> G
D --> G
E --> G
F --> G
G --> H
H -- Remove if qty = 0 --> I
Executive Summary & Business Logic
Business Goal: The primary business objective of this query is to provide a precise and up-to-date snapshot of inventory levels across various locations (stores and warehouses) for a specific retail company. This data is crucial for the OneBeat system to accurately determine which products need to be replenished at which stores, ensuring optimal stock levels and minimizing lost sales due to out-of-stock situations. It consolidates different stock types (on-site, in-transit, reserved) into a unified view.
Key Business Rules:
1. Pilot Scope Filtering: The query strictly adheres to pilot conditions, processing data only for the COMPANY specified in the function call, which currently implies Italian stores for the pilot phase.
2. Stock Type Classification: Inventory quantities are meticulously categorized into site_qty (physical stock at a location, adjusted for technical movements), transit_qty (stock currently in movement between locations), and reserved_qty (stock allocated but not yet shipped). This classification is based on specific subject_type_cod and class_cod combinations.
3. Article Eligibility: Only articles that are designated as "sale products" (i.e., business_cod not equal to 'C') and belong to sales collections from 2023 onwards are considered for replenishment, ensuring focus on current and relevant merchandise.
Execution Parameters and Pilot Conditions
This function accepts three parameters:
- START_DATE (NUMBER): The start date (in YYYYMMDD numeric format) for filtering stock posting dates.
- END_DATE (NUMBER): The end date (in YYYYMMDD numeric format) for filtering stock posting dates.
- COMPANY (VARCHAR): The name of the company for which inventory data should be retrieved. This parameter is crucial for enforcing the pilot conditions, as it limits the scope of the query to specific companies (e.g., 'BATA', 'AW_LAB') that are part of the Italy stores pilot. The FILTERED_COMPANY_CODS CTE ensures that only data related to the specified company's country_cod and company_cod is processed. These pilot conditions are subject to change as the project evolves.
Final Columns Data Dictionary
| Column Name | Data Type | Description | Notes |
|---|---|---|---|
location_id |
VARCHAR | Unique identifier for the inventory location (store or warehouse). | Formatted as COUNTRY_PRIMARYCOMPANY_SUBJECTCOD for stores, or PRIMARY_WH for primary warehouses. |
site_qty |
NUMBER | The quantity of stock physically available at the location, adjusted for technical stock movements. | Represents stock available for immediate replenishment. Derived from W_CL1000, W_CL2001, S_CL1000, and TECNICA stock classes. |
sku_id |
VARCHAR | Unique identifier for the Stock Keeping Unit (SKU). | Formatted as COUNTRY_PRIMARYCOMPANY_ARTICLECOD_SIZEDES. |
source_location_id |
VARCHAR | The primary warehouse associated with the company. | Used to identify the main source for replenishment. |
status_date |
TIMESTAMP | The date when the stock status was recorded. | Converted from posting_dat_num (YYYYMMDD) to a timestamp. |
transit_qty |
NUMBER | The quantity of stock currently in transit to the location. | Represents stock that is on its way and will soon be available. Derived from T_CL1000, F_CL1000, and S_CL2000 stock classes. |
avoid_replenishment |
NUMBER | Flag indicating whether replenishment should be avoided for this SKU at this location. | Currently always 0, implying no specific conditions to avoid replenishment are applied within this function. |
reserved_qty |
NUMBER | The quantity of stock that is reserved or allocated. | Represents stock that is not available for general replenishment. Derived from W_CL2001 stock class (negative values are converted to positive). |
Data Flow Logic
FILTERED_COMPANY_CODS
- Purpose: This CTE identifies the specific company codes and associated primary warehouses relevant to the current execution, based on the
COMPANYparameter. This acts as the initial filter for the pilot project scope. - Inputs:
DW_LOADTARGET.DWH.ONEBEAT_COMPANY_RECOD - Main Logic: It selects
country_cod,company_name,company_cod,primary_company, andprimary_whfrom theONEBEAT_COMPANY_RECODtable, filtering records wherecompany_namematches theCOMPANYparameter passed to the function. - Assumptions: Assumes that the
ONEBEAT_COMPANY_RECODtable contains accurate mappings for company names to their respective codes and primary warehouses, and that theCOMPANYparameter will correspond to an existingcompany_namein this table.
TOTAL_STOCK
- Purpose: This CTE consolidates raw stock data from two different sources (
TBDWFT_STOCK_BY_SIZEandVWDWFT_STOCK_W_TECNICA_BY_SIZE), applies initial filters, and enriches the data with company and warehouse information. It also convertsstock_qtyto a numeric type. - Inputs:
DW_LOADTARGET.DWH.TBDWFT_STOCK_BY_SIZE,DW_LOADTARGET.DWH.WHS_ENABLED_ONEBEAT,DW_LOADTARGET.DWH.VWDWFT_STOCK_W_TECNICA_BY_SIZE,DW_LOADTARGET.DWH.TBDWMD_ARTICLE,FILTERED_COMPANY_CODSCTE. - Main Logic:
- It uses a
UNION ALLto combine stock data:- The first part queries
TBDWFT_STOCK_BY_SIZE, joining withWHS_ENABLED_ONEBEATto identify active warehouses and withFILTERED_COMPANY_CODSfor pilot scope. It filters byposting_date_num(betweenSTART_DATEandEND_DATE),flag_origin = 'S'(indicating unpacked stock), and specificsubject_type_cod || '_' || class_codvalues (W_CL1000,W_CL2001,S_CL2000,S_CL1000,T_CL1000,F_CL1000). - The second part queries
VWDWFT_STOCK_W_TECNICA_BY_SIZE(technical stock), joining similarly withWHS_ENABLED_ONEBEATandFILTERED_COMPANY_CODS. It negatesstock_qty(stock_qty*(-1)) and assigns 'TECNICA' asstock_class.
- The first part queries
- Both parts are then joined with
TBDWMD_ARTICLEto apply article-specific filters:business_cod <> 'C'(not sale products) andSALES_COLLECTION_YEAR_NUM >= '2023'.
- It uses a
- Assumptions: Assumes that
flag_origin = 'S'correctly identifies stock ready for replenishment. It also assumes thatW_CL2001stock represents a reserved or negative quantity that needs to be offset, andTECNICAstock represents adjustments that reduce available stock. The article master data is assumed to be accurate for filtering relevant products.
FORMATTED_STOCK
- Purpose: This CTE transforms the raw stock data from
TOTAL_STOCKinto the final desired format, categorizing quantities intosite_qty,transit_qty, andreserved_qty, and constructinglocation_idandsku_idbased on business rules. - Inputs:
TOTAL_STOCKCTE. - Main Logic:
- It uses
CASEstatements to definelocation_id: ifsubject_codlength is greater than 3 (indicating a store), it's formatted ascountry_cod || '_' || primary_company || '_' || subject_cod; otherwise, it defaults toprimary_wh. sku_idis constructed ascountry_cod || '_' || primary_company || '_' || article_cod || '_' || size_des.site_qtyis populated based onstock_class(W_CL1000,W_CL2001,S_CL1000,TECNICA).transit_qtyis populated based onstock_class(T_CL1000,F_CL1000,S_CL2000).reserved_qtyis derived fromW_CL2001stock, with its quantity multiplied by -1 to represent a positive reserved amount.status_dateis converted from the numericposting_dat_numto aTIMESTAMP.avoid_replenishmentis hardcoded to0in this version of the function.
- It uses
- Assumptions: Assumes that the length of
subject_codis a reliable indicator for distinguishing stores from other locations. The specificstock_classmappings tosite_qty,transit_qty, andreserved_qtyare accurate based on business definitions.
Source Code
```sql CREATE OR REPLACE FUNCTION DW_LOADTARGET.DWH.ONEBEAT_GET_DELTA_INVENTORIES(START_DATE NUMBER, END_DATE NUMBER, COMPANY VARCHAR)
RETURNS TABLE ( location_id VARCHAR , site_qty NUMBER , sku_id VARCHAR , source_location_id VARCHAR , status_date TIMESTAMP , transit_qty NUMBER , avoid_replenishment NUMBER , reserved_qty NUMBER ) AS $$ -- retrieve pilot conditions WITH FILTERED_COMPANY_CODS AS ( SELECT country_cod, company_name, company_cod, primary_company, primary_wh FROM DW_LOADTARGET.DWH.ONEBEAT_COMPANY_RECOD WHERE company_name = COMPANY )
, TOTAL_STOCK AS (
SELECT
TOTAL.country_cod
, TOTAL.company_cod
, TOTAL.subject_cod
, TOTAL.article_cod
, TOTAL.size_des
, TOTAL.stock_class
, TOTAL.stock_qty
, TOTAL.posting_dat_num
, TOTAL.primary_company
, TOTAL.primary_wh
FROM (
SELECT
STOCK.country_cod
, STOCK.company_cod
, STOCK.subject_cod
, STOCK.article_cod
, STOCK.size_des
, STOCK.subject_type_cod || '' || STOCK.class_cod AS stock_class
, STOCK.stock_qty::NUMBER as stock_qty
, STOCK.posting_date_num as posting_dat_num
-- utils --
, RECOD.primary_company
, RECOD.primary_wh
FROM DW_LOADTARGET.DWH.TBDWFT_STOCK_BY_SIZE STOCK
LEFT JOIN DW_LOADTARGET.DWH.WHS_ENABLED_ONEBEAT WHS -- retrieve the "active" warehouse per each company
ON WHS.country_cod = STOCK.country_cod
AND WHS.company_cod = STOCK.company_cod
AND WHS.whs_cod = STOCK.subject_cod
INNER JOIN FILTERED_COMPANY_CODS RECOD -- pilot conditions (bata & aw_lab)
ON STOCK.country_cod = RECOD.country_cod
AND STOCK.company_cod = RECOD.company_cod
WHERE 1=1
AND STOCK.posting_date_num BETWEEN START_DATE AND END_DATE
AND STOCK.flag_origin = 'S' -- in magazzino ci bancali in pack (P), in bancali (S) sono giĆ spacchettati by size.
-- we filter the selected stock types
AND STOCK.subject_type_cod || '' || STOCK.class_cod IN ('W_CL1000', 'W_CL2001','S_CL2000', 'S_CL1000', 'T_CL1000', 'F_CL1000')
AND (WHS.whs_cod IS NOT NULL OR LEN(STOCK.subject_cod)>3)
UNION ALL
-- query data from VWDWFT_STOCK_W_TECNICA_BY_SIZE and move the stock_qty to site as "LOCAZIONE TECNICA"
SELECT
TECNICA.country_cod
, TECNICA.company_cod
, subject_cod
, article_cod
, size_des
, 'TECNICA' AS stock_class
, stock_qty*(-1)::NUMBER AS stock_qty
, posting_dat_num
-- utils --
, RECOD.primary_company
, RECOD.primary_wh
FROM DW_LOADTARGET.DWH.VWDWFT_STOCK_W_TECNICA_BY_SIZE TECNICA
INNER JOIN DW_LOADTARGET.DWH.WHS_ENABLED_ONEBEAT WHS
ON WHS.country_cod = TECNICA.country_cod
AND WHS.company_cod = TECNICA.company_cod
AND WHS.whs_cod = TECNICA.subject_cod
INNER JOIN FILTERED_COMPANY_CODS RECOD -- filtering pilot conditions (bata & aw_lab)
ON STOCK.country_cod = RECOD.country_cod
AND STOCK.company_cod = RECOD.company_cod
WHERE 1=1
AND TECNICA.posting_dat_num BETWEEN START_DATE AND END_DATE
) TOTAL
INNER JOIN DW_LOADTARGET.DWH.TBDWMD_ARTICLE ARTICLE
ON ARTICLE.country_cod = TOTAL.country_cod
AND ARTICLE.article_cod = TOTAL.article_cod
WHERE 1=1
-- article conditions
AND ARTICLE.business_cod <> 'C' -- sale products
AND ARTICLE.SALES_COLLECTION_YEAR_NUM >= '2023'
)
/ , REPLENISHMENT_MAPPED_STOCK AS ( SELECT TOTAL.country_cod , TOTAL.company_cod , TOTAL.subject_cod , TOTAL.article_cod , TOTAL.size_des , TOTAL.stock_class , TOTAL.stock_qty , TOTAL.posting_dat_num , TOTAL.primary_company , TOTAL.primary_wh , NVL(REPL.enable_flag,0) AS avoid_replenishment FROM TOTAL_STOCK T_STOCK LEFT OUTER JOIN DW_LOADTARGET.DWH.tabella_avoid_repl REPL ON REPL.country_cod = T_STOCK.country_cod AND REPL.company_cod = T_STOCK.company_cod AND REPL.article_cod = T_STOCK.article_cod AND REPL.size_des = T_STOCK.size_des AND REPL.store_cod = T_STOCK.store_cod AND REPL.posting_date_num = T_STOCK.posting_date_num ) /
, FORMATTED_STOCK AS ( SELECT CASE -- store condition WHEN LEN(subject_cod) > 3 THEN country_cod || ''|| primary_company ||'' || subject_cod ELSE primary_wh END AS location_id , country_cod || '' || primary_company || '' || article_cod || '_' || size_des AS sku_id -- SITE QUANTITY: 'W_CL1000', 'W_CL2001', 'S_CL1000' (W_CL2001 is negative) , CASE WHEN stock_class IN ('W_CL1000', 'W_CL2001', 'S_CL1000', 'TECNICA') THEN stock_qty ELSE 0 END AS site_qty -- TRANSIT QUANTITY: 'T_CL1000', 'F_CL1000', 'S_CL2000' ('S_CL2000' is set as transit quantity to the subject_cod) , CASE WHEN stock_class IN ('T_CL1000', 'F_CL1000', 'S_CL2000') THEN stock_qty ELSE 0 END AS transit_qty -- RESERVED QUANTITY: 'W_CL2001' is multiplied by -1 and set as the reserved quantity in the deafult warehouse WH1 -- since its the dual of the S_CL2000 (aggregated by wh) , CASE WHEN stock_class = 'W_CL2001' THEN stock_qty * (-1) ELSE 0 END AS reserved_qty , primary_wh AS source_location_id , TO_TIMESTAMP(DATE(posting_dat_num,'yyyymmdd')) as status_date , 0 AS avoid_replenishment , stock_class FROM TOTAL_STOCK )
-- Final grouping SELECT location_id -- here we sum the site_qty, i.e. from the total stock (W_CL1000) we remove the "LOCAZIONE TECNICA" and W_CL2001 stock -- in order to have the "available stock for replenishment" , SUM(site_qty) AS site_qty , sku_id , source_location_id , status_date , SUM(transit_qty) AS transit_qty , 0 AS avoid_replenishment
, SUM(reserved_qty) AS reserved_qty
FROM FORMATTED_STOCK GROUP BY ALL -- may happen that W_CL1000 + W_CL2001 (negative) - LOCAZIONE TECNICA = 0 in the warehouse HAVING NOT( SUM(site_qty) = 0 AND SUM(transit_qty) = 0 AND SUM(reserved_qty) = 0) $$ ;