Forum Discussion
Iterative Stock Cover Calculation
- 7 years ago
Hi Anonymous
Here is an example pbix showing one way to do the calculations.
I put a table in the PBIX showing the key figures:
Generally, when you have Sales/Production data and you want to derive balances at any point in time, you need to create a series of cumulative calculations.
In this case I started with a table pretty much as you described. Opening Value exists only in the first week.
Then created a set of base measures (Opening, Production, Sales) and corresponding cumulative measures.
Opening = SUM ( Forecast[Opening Value] ) Production = SUM ( Forecast[ProductionPlan] ) Sales = SUM ( Forecast[SalesForecast] ) Cumulative Opening = VAR MaxWeek = MAX ( Forecast[Week] ) RETURN CALCULATE ( [Opening], Forecast[Week] <= MaxWeek + 1 ) Cumulative Production = VAR MaxWeek = MAX ( Forecast[Week] ) RETURN CALCULATE ( [Production], Forecast[Week] <= MaxWeek ) Cumulative Sales = VAR MaxWeek = MAX ( Forecast[Week] ) RETURN CALCULATE ( [Sales], Forecast[Week] <= MaxWeek )Then created Closing/Opening balance measures, representing "stock" on hand at the end/start of each week:
Balance Closing = [Cumulative Opening] + [Cumulative Production] - [Cumulative Sales] Balance Opening = VAR MaxWeek = MAX ( Forecast[Week] ) RETURN CALCULATE ( [Balance Closing], Forecast[Week] = MaxWeek - 1 )Then the Cover measure makes use of the above measures.
Cover = VAR BalanceOpening = [Balance Opening] VAR MaxWeek = MAX ( Forecast[Week] ) VAR FutureWeeks = FILTER ( ALL ( Forecast[Week] ), Forecast[Week] >= MaxWeek ) VAR PreviousSalesCumulative = CALCULATE ( [Cumulative Sales], Forecast[Week] < MaxWeek ) VAR FutureSales = GENERATE ( FutureWeeks, VAR SalesInWeek = [Sales] VAR FutureSalesCumulative = [Cumulative Sales] - PreviousSalesCumulative VAR FutureSalesCumulativePre = FutureSalesCumulative - SalesInWeek RETURN ROW ( "WeekIndex", Forecast[Week] - MaxWeek, "SalesInweek", SalesInWeek, "FutureCumulativeSales", FutureSalesCumulative, "FutureCumulativeSalesPre", FutureSalesCumulativePre ) ) VAR CoverResult = MINX ( FutureSales, IF ( [FutureCumulativeSales] >= BalanceOpening && [FutureCumulativeSales] - [SalesInweek] <= BalanceOpening, [WeekIndex] + DIVIDE ( BalanceOpening - [FutureCumulativeSalesPre], [SalesInWeek] ) ) ) RETURN CoverResultThis particular measure finds the earliest week where the Opening Balance is exhausted by future sales, then calculates the fractional week index where this occurs. The FutureSales variable stores the key values used in the calculation, then CoverResult finds the appropriate row and does the final calculation (using MINX). The above code could well be improved!
Regards,
Owen
Hi Anonymous
Here is an example pbix showing one way to do the calculations.
I put a table in the PBIX showing the key figures:
Generally, when you have Sales/Production data and you want to derive balances at any point in time, you need to create a series of cumulative calculations.
In this case I started with a table pretty much as you described. Opening Value exists only in the first week.
Then created a set of base measures (Opening, Production, Sales) and corresponding cumulative measures.
Opening =
SUM ( Forecast[Opening Value] )
Production =
SUM ( Forecast[ProductionPlan] )
Sales =
SUM ( Forecast[SalesForecast] )
Cumulative Opening =
VAR MaxWeek =
MAX ( Forecast[Week] )
RETURN
CALCULATE ( [Opening], Forecast[Week] <= MaxWeek + 1 )
Cumulative Production =
VAR MaxWeek =
MAX ( Forecast[Week] )
RETURN
CALCULATE ( [Production], Forecast[Week] <= MaxWeek )
Cumulative Sales =
VAR MaxWeek =
MAX ( Forecast[Week] )
RETURN
CALCULATE ( [Sales], Forecast[Week] <= MaxWeek )Then created Closing/Opening balance measures, representing "stock" on hand at the end/start of each week:
Balance Closing =
[Cumulative Opening] + [Cumulative Production] - [Cumulative Sales]
Balance Opening =
VAR MaxWeek =
MAX ( Forecast[Week] )
RETURN
CALCULATE ( [Balance Closing], Forecast[Week] = MaxWeek - 1 )Then the Cover measure makes use of the above measures.
Cover =
VAR BalanceOpening = [Balance Opening]
VAR MaxWeek =
MAX ( Forecast[Week] )
VAR FutureWeeks =
FILTER ( ALL ( Forecast[Week] ), Forecast[Week] >= MaxWeek )
VAR PreviousSalesCumulative =
CALCULATE ( [Cumulative Sales], Forecast[Week] < MaxWeek )
VAR FutureSales =
GENERATE (
FutureWeeks,
VAR SalesInWeek = [Sales]
VAR FutureSalesCumulative = [Cumulative Sales] - PreviousSalesCumulative
VAR FutureSalesCumulativePre = FutureSalesCumulative - SalesInWeek
RETURN
ROW ( "WeekIndex", Forecast[Week] - MaxWeek,
"SalesInweek", SalesInWeek,
"FutureCumulativeSales", FutureSalesCumulative,
"FutureCumulativeSalesPre", FutureSalesCumulativePre )
)
VAR CoverResult =
MINX (
FutureSales,
IF (
[FutureCumulativeSales] >= BalanceOpening
&& [FutureCumulativeSales] - [SalesInweek]
<= BalanceOpening,
[WeekIndex]
+ DIVIDE ( BalanceOpening - [FutureCumulativeSalesPre], [SalesInWeek] )
)
)
RETURN
CoverResultThis particular measure finds the earliest week where the Opening Balance is exhausted by future sales, then calculates the fractional week index where this occurs. The FutureSales variable stores the key values used in the calculation, then CoverResult finds the appropriate row and does the final calculation (using MINX). The above code could well be improved!
Regards,
Owen
- Anonymous7 years agoNot applicable
Hello OwenAuger
For this data set it's working fine, but when my data set change cover calculation breakes.
If the Balance Opening Valeu is greater than cumulative sales, it doesn't calculate cover measure.
I'm sharing PBIX Link for this dataset.
Thanks for your helps.- OwenAuger7 years agoSuper User
Anonymous
Thanks for pointing out this issue.
The situation you have highlighted is that when the Opening Balance is so high that it is never exhausted by forecast sales, my measure can't find a week where it is exhausted, and returns blank.
In this situation, it might make more sense to return the number of weeks remaining, because the Opening Balance will cover at least those weeks.
I have updated my file with this measure, and changed the Opening value to 190 as in your latest example.
Cover = VAR BalanceOpening = [Balance Opening] VAR MaxWeek = MAX ( Forecast[Week] ) VAR FutureWeeks = FILTER ( ALL ( Forecast[Week] ), Forecast[Week] >= MaxWeek ) VAR PreviousSalesCumulative = CALCULATE ( [Cumulative Sales], Forecast[Week] < MaxWeek ) VAR FutureSales = GENERATE ( FutureWeeks, VAR SalesInWeek = [Sales] VAR FutureSalesCumulative = [Cumulative Sales] - PreviousSalesCumulative VAR FutureSalesCumulativePre = FutureSalesCumulative - SalesInWeek RETURN ROW ( "WeekIndex", Forecast[Week] - MaxWeek, "SalesInweek", SalesInWeek, "FutureCumulativeSales", FutureSalesCumulative, "FutureCumulativeSalesPre", FutureSalesCumulativePre ) ) VAR CoverResult = MINX ( FutureSales, IF ( [FutureCumulativeSales] >= BalanceOpening && [FutureCumulativeSales] - [SalesInweek] <= BalanceOpening, [WeekIndex] + DIVIDE ( BalanceOpening - [FutureCumulativeSalesPre], [SalesInWeek] ) ) ) VAR WeeksRemaining = MAXX ( FutureSales, [WeekIndex] ) + 1 RETURN IF ( NOT ISBLANK ( CoverResult ), CoverResult, WeeksRemaining )Does this make sense as an alternative, or would you want to do something different?
Regards,
Owen
- dduc23102 years agoFrequent Visitor
Hi. I am applying this solution to my work. But the issue I have at the moment is that when the current period closing balance is negative the opening balance is also negative which might not reflect the actual picture. Say you ending with -100 stock that means you were out of stock and didnt cover the sales in this period but the opening bal for the next period should be 0 and any production coming in from there will be used to cover the next sales (instead of accounted for the sales not covered in previous period). How can I apply that to this case? Thanks
- goreavin3 years agoHelper I
Hi OwenAuger ,
I really like your solution and think it is the most complete one I have seen so far.
One thing where I need some help is how to display the Date instead of the Week# when showing the measure. I want to display the Cover in a chart for example with the x-axis shoing the real date (and not week number) and y-axis showing the coverage. May be it is obivious, but I for one could not figure out a easy way to do this...
How would you solve it?
Cheers, Avi