155_ Model _Power BI & Power Pivot Safety stock of purchase, sales and inventory
One 、 background
When talking about the concept of purchase, sales and inventory , We also need to mention another concept : safety stock .
Inventory turnover in an ideal state is to achieve zero inventory , However, under the balance of internal capital occupation, uncertain delivery cycle and external customers' spot rate , It is almost impossible to achieve zero inventory . In this equilibrium state, there is safety stock ; The above is the author's perception in ordinary production and life .
Here we first introduce the mathematical formula of safety stock :

explain
Distribution according to the standard of ideal state , The safety stock is only used as a reference point , The understanding of business needs to be added to the actual production , Adjustment .
The mathematical formula is transformed into DAX The formula :SS = z * SQRT ( σd ^ 2 * μL + σL ^ 2 * μd ^ 2 )
SS: safety stock (Safe Stock).
z : Service level coefficient , service level ( Spot rate ) by 0.95, Look up the table under the standard normal distribution to get , Corresponding z = 1.65.
L : Purchase lead time , The corresponding warehousing interval days in this case .
μL: Average lead time .
σL: Lead time L Standard deviation .
d : Number of sunrise warehouses .
μd: Average daily delivery quantity .
σd: Sunrise storage d Standard deviation .
The standard deviation formula uses :STDEVX.S
For more information on safety stock, please refer to :
https://baike.baidu.com/item/ safety stock
Power BI Actual effects link :
https://demo.jiaopengzi.com/pbi/155-full.html

Two 、DAX Model
1、 Data sheets and relationships
Dimension table :01_Calendar; T01_ Store table ; T00_ Product list
Fact table :T04_ Order master ; T05_ Order sub table
measurements :00_Measure
Auxiliary table :04_RefreshTime
Calculation table :02_Row
The specific fields and relationships are shown in the following figure :

For detailed data fields, see :
https://jiaopengzi.com/1435.html
2、 measurements
A map of measures

Next, let's put up some key measures .
0001_ Product quantity _ Put in storage
0001_ Product quantity _ Put in storage =
SUM ( 'T03_ Warehousing information table '[F_02_ Quantity of warehoused products ] )
0002_ Product quantity _ Out of stock
Note that issue is calculated according to the delivery date in the order main table , So we need to use USERELATIONSHIP Activate the relationship .
0002_ Product quantity _ Out of stock =
CALCULATE (
SUM ( 'T05_ Order sub table '[F_05_ Number of products sold ] ),
USERELATIONSHIP ( 'T04_ Order master '[F_04_ Delivery date ], '01_Calendar'[C01_Dates] )
)
0003_ Product quantity _ stock _ End of term
About the calculation of inventory , Here's an idea for you . Inventory is the difference between historical cumulative receipt and historical cumulative issue at the current time point . We use a picture to show .

In this way of thinking , We can use it easily DAX Write the inventory measurement in the sales inventory .
Of course, inventory can be divided into opening inventory and closing inventory according to the status at different time points , The measurement values of opening and closing smart inventory can be learned in my course .
https://jiaopengzi.com/video/video-101?rkvid=100

0003_ Product quantity _ stock _ End of term =
VAR DATE_START0 =
CALCULATE ( FIRSTDATE ( '01_Calendar'[C01_Dates] ), ALL ( '01_Calendar' ) )
VAR DATE_END0 =
LASTDATE ( '01_Calendar'[C01_Dates] )
VAR DATE_TABLE0 =
DATESBETWEEN ( '01_Calendar'[C01_Dates], DATE_START0, DATE_END0 )
VAR IN0 =
CALCULATE ( [0001_ Product quantity _ Put in storage ], DATE_TABLE0 )
VAR OUT0 =
CALCULATE ( [0002_ Product quantity _ Out of stock ], DATE_TABLE0 )
VAR DATE_START_ABS0 =
CALCULATE ( LASTDATE ( 'T04_ Order master '[F_04_ Delivery date ] ), ALL () ) // Compatible display to the last date of the fact table .
RETURN
IN0 - OUT0
//IF(DATE_START_ABS0>=DATE_END0,IN0 - OUT0,BLANK())
0004_ Product quantity _ safety stock
The most important measurement in this case ; If you have difficulty understanding the intermediate process , You can use what we have prepared for you Excel Auxiliary calibration table .
Specific use case attachments Power BI The second page in the document 《P2 Check the data 》 Export the corresponding data , In the attachment Excel 《 Safety stock step breakdown 》 Distribution experience in .
Excel There are formulas in it for easy understanding .

0004_ Product quantity _ safety stock =
/*
Distribution according to the standard of ideal state , The safety stock is only used as a reference point , The understanding of business needs to be added to the actual production , Adjustment .
SS = z * SQRT ( σd ^ 2 * μL + σL ^ 2 * μd ^ 2 )
SS: safety stock (Safe Stock).
z : Service level coefficient , service level ( Spot rate ) by 0.95, Corresponding to the standard Abelian distribution z = 1.65.
L : Purchase lead time , The corresponding warehousing interval days in this case .
μL: Average lead time .
σL: Lead time L Standard deviation .
d : Number of sunrise warehouses .
μd: Average daily delivery quantity .
σd: Sunrise storage d Standard deviation .
*/
VAR N = [02_ROW value ]// Default 30 God
VAR DATE_END0 =
LASTDATE ( '01_Calendar'[C01_Dates] )
VAR DATE_START0 =
DATEADD ( DATE_END0, - N + 1, DAY ) // Note that no boundaries are included .
VAR DATE_Table0 =
DATESBETWEEN ( '01_Calendar'[C01_Dates], DATE_START0, DATE_END0 )
VAR T01 =
CALCULATETABLE ( 'T03_ Warehousing information table ', DATE_Table0 )
VAR T02 =
SUMMARIZE (
T01,
'01_Calendar'[C01_Dates],
'T00_ Product list '[F_01_ Product number ],
'T01_ Store table '[F_01_ Store number ],
"@ Put in storage ", [0001_ Product quantity _ Put in storage ]
)
VAR T03 =
SUMMARIZE (
T02,
[F_01_ Product number ],
[F_01_ Store number ],
"@μL",
VAR P0 = [F_01_ Product number ]
VAR M0 = [F_01_ Store number ]
VAR T_FILTER =
FILTER ( T02, [F_01_ Product number ] = P0 && [F_01_ Store number ] = M0 )
VAR DATE_MAX =
MAXX ( T_FILTER, [C01_Dates] )
VAR DATE_MIN =
MINX ( T_FILTER, [C01_Dates] )
VAR DAY_DIFF =
DATEDIFF ( DATE_MIN, DATE_MAX, DAY )
VAR T_ROWS =
COUNTROWS ( T_FILTER ) - 1 // Take care to remove the boundary minus 1 .
RETURN
DIVIDE ( DAY_DIFF, T_ROWS, 0 ),
"@σL",
VAR P0 = [F_01_ Product number ]
VAR M0 = [F_01_ Store number ]
VAR T_FILTER =
FILTER ( T02, [F_01_ Product number ] = P0 && [F_01_ Store number ] = M0 )
VAR T_INDEX =
SUBSTITUTEWITHINDEX (
ADDCOLUMNS ( T_FILTER, "@date", [C01_Dates] ),
"@INDEX", T_FILTER,
[C01_Dates], ASC
)
VAR T_INDEX_N =
ADDCOLUMNS (
T_INDEX,
"@N",
VAR INDEX0 = [@INDEX]
VAR T_1 =
FILTER ( T_INDEX, [@INDEX] = INDEX0 - 1 )
VAR DATE_1 =
MAXX ( T_1, [@date] )
VAR N0 =
DATEDIFF ( DATE_1, [@date], DAY )
RETURN
N0
)
VAR T_INDEX_N_NOT_BLANK =
FILTER ( T_INDEX_N, [@N] <> BLANK () )
RETURN
IFERROR ( STDEVX.S ( T_INDEX_N_NOT_BLANK, [@N] ), 0 )
)
VAR T11 =
CALCULATETABLE (
'T05_ Order sub table ',
DATE_Table0,
USERELATIONSHIP ( 'T04_ Order master '[F_04_ Delivery date ], '01_Calendar'[C01_Dates] )
) // The delivery date needs to be activated .
VAR T12 =
SUMMARIZE (
T11,
'01_Calendar'[C01_Dates],
'T00_ Product list '[F_01_ Product number ],
'T01_ Store table '[F_01_ Store number ],
"@ Out of stock ", [0002_ Product quantity _ Out of stock ]
)
VAR T13 =
SUMMARIZE (
T12,
[F_01_ Product number ],
[F_01_ Store number ],
"@μd",
VAR P0 = [F_01_ Product number ]
VAR M0 = [F_01_ Store number ]
VAR T_FILTER =
FILTER ( T12, [F_01_ Product number ] = P0 && [F_01_ Store number ] = M0 )
VAR AVG0 =
AVERAGEX ( T_FILTER, [@ Out of stock ] )
RETURN
AVG0,
"@σd",
VAR P0 = [F_01_ Product number ]
VAR M0 = [F_01_ Store number ]
VAR T_FILTER =
FILTER ( T12, [F_01_ Product number ] = P0 && [F_01_ Store number ] = M0 )
VAR STDE0 =
IFERROR ( STDEVX.S ( T_FILTER, [@ Out of stock ] ), 0 )
RETURN
STDE0
)
VAR T =
NATURALINNERJOIN ( T03, T13 )
VAR z = [0010_ Product quantity _ safety stock _z]
VAR SS =
//SS= z * SQRT( σd ^ 2 * μL + σL ^ 2 * μd ^ 2 )
SUMX ( T, z * SQRT ( [@σd] ^ 2 * [@μL] + [@σL] ^ 2 * [@μd] ^ 2 )
)
RETURN
SS
3、 ... and 、 summary
1、 Safety stock is an important reference for inventory management , In this case, the rational case of standard Zhengtai distribution is used , Therefore, in the actual production and life, it is necessary to readjust according to the business characteristics .
2、 This case gives a statistical significance of safety stock use DAX Calculation ideas .
3、 In addition, the understanding of inventory calculation , Historical accumulation corresponds to DAX Chinese is easy to write , First, find the time starting point of the business , Because the starting point of time will not change , You can also write death directly , Find the current time point , combination DATESBETWEEN We can build the various business time descriptions we need .
by Jiaopengzi









