Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
unais
Helper V
Helper V

Inventory Qutantity wise Againg Report FIFO

Team,

 

 

Please advise how can get create Invontry quantiy wise Stock againg Report in FIFO model.

Same table having Selling and Buying information.

Refer below link same Data source here sepcified to calculate FIFO selling value , where i need to create Againg report for current stock , how long this stocks available.

https://radacad.com/dax-inventory-or-stock-valuation-using-fifo#comment-349084

1 ACCEPTED SOLUTION
Anonymous
Not applicable

I am not very clear what you want to do with Sales Returns and Purchase Returns, but if you want adjust the "Returns" quantity in the original document itself, you can add two calculated columns to your table to get the following results.

 

 

DO NoDateMaterialTypeQtyReferenceAdjustmentAdjQty
000101 January 2019AaaBuy15 150
000201 February 2019AaaBuy10  10
000301 May 2019AaaPurchase Return150001 15
000402 April 2019AaaSales5 23
000502 June 2019AaaSales Return20004 2

 

The DAX for the last two columns "Adjustment" & "AdjQty" is as follows...

 

 

Adjustment = 
SUMX(
    FILTER(
        zinventory,
        zinventory[Reference]=EARLIER(zinventory[DO No])),
        zinventory[Qty])
AdjQty = zinventory[Qty]-zinventory[Adjustment]

 

 

 

Please note that I have just copied the sample data you sent on your last post and gave the table a name "zinventory". 

Once you do add these columns, instead of running inventory ageing transactions on the "Qty" field, you can run it on "AdjQty" field by changing the formulas accordingly.

 

If you follow this method, your inventory ageing report will show the ageing based on the original date of purchase and sales.

 

Alternatively, You can treat all "Purchase Returns" as "Sale" and all "Sales Returns" as "Buy"  and in this approach, you ageing will vary accordingly which will be like a true FIFO stack. The adjustment method mentioned above will be like, you will following "FIFO" only for "Buy" and "Sale" only and violate the FIFO (physically) by inserting at random positions in your stack, if you were to visualise a true FIFO stack operation.

View solution in original post

13 REPLIES 13
amitchandak
Super User
Super User
Anonymous
Not applicable

To start with, post the list of tables with field names and the relationship between the tables in your data model. Or atleast, give some sample data from your table showing all the fields with few lines of data. 

 

Without this, no one will be able answer your question to the point. May be people will direct you to some blog post and you will have to spend considerable time reading, understanding, modifying and adapting the concepts to match your requirements. 

Anonymous
Not applicable

Hi,

 

Assuming that you have the following table in your data model...

 

Table Name: Table1

 

SymboltypeUnitsdatevalue per unitTotal Value
AAAbuy501 January 2014$100.00$500.00
AAAbuy1001 May 2016$200.00$2,000.00
AAAsale601 August 2016$500.00$3,000.00
AAAbuy2001 January 2017$800.00$16,000.00
AAAsale2201 May 2017$700.00$15,400.00
BBBbuy1305 June 2016$300.00$3,900.00
BBBsale1301 July 2016$120.00$1,560.00
CCCbuy5501 July 2018$100.00$5,500.00
DDDbuy401 January 2018$1.10$4.40
DDDbuy402 January 2018$1.20$4.80
DDDbuy403 January 2018$1.30$5.20
DDDbuy404 January 2018$1.40$5.60
DDDbuy405 January 2018$1.50$6.00
DDDsale1306 January 2018$2.50$32.50
DDDbuy407 January 2018$1.70$6.80
DDDbuy408 January 2018$1.80$7.20
DDDbuy409 January 2018$1.90$7.60
DDDsale810 January 2018$3.50$28.00
DDDsale611 January 2018$4.50$27.00

 

Note: I have deleted all calculated columns from your pbix file.

 

Step1: Add the following calculated column to your table.

 

 

StockInHandToday =
VAR CurrentSymbol = Table1[Symbol]
VAR CurrentDate = Table1[date]
VAR CurrentLineQty = Table1[Units]
VAR TotalPurchases =
    SUMX (
        FILTER ( Table1, Table1[Symbol] = CurrentSymbol && Table1[type] = "buy" ),
        Table1[Units]
    ) + 0
VAR TotalSales =
    SUMX (
        FILTER ( Table1, Table1[Symbol] = CurrentSymbol && Table1[type] = "sale" ),
        Table1[Units]
    ) + 0
VAR PurchasesAfterCurrentDate =
    SUMX (
        FILTER (
            Table1,
            Table1[Symbol] = CurrentSymbol
                && Table1[type] = "buy"
                && Table1[date] > CurrentDate
        ),
        Table1[Units]
    ) + 0
VAR CurrentStock =
    MAX (
        0,
        MIN ( TotalPurchases - TotalSales - PurchasesAfterCurrentDate, CurrentLineQty )
    )
VAR Result =
    IF ( Table1[type] = "Buy", CurrentStock, 0 )
RETURN
    IF ( Result = 0, BLANK (), Result )

 

 

Step 2: Add another calculated column for Ageing Days.

 

 

StockAgeingInDays = 
VAR CurrentDate = TODAY()
VAR BuyDate = Table1[date]
VAR Age = ROUND(CurrentDate-BuyDate,0)
RETURN Age & " Days"

 

 

Sample Output:

InventoryAgeing.png

 

 

Disclaimer: It is assumed that your data's granularity is at day level. If your actual data is at document level with multiple purchase or sales documents on the same day, there is a chance that the stock-in-hand will get repeated for every document on the same day and your aggregation will show a wrong stock figure. In that case, you have to modify the formula accordingly or use a table with day-level granularity.

 

 

hi Sreenath,

Thanks for your update.

I had updated source files, with small changes Added the Same Date with the Same item multiple transactions then again values are coming wrong..

https://almaznetae-my.sharepoint.com/:w:/g/personal/unais_almaz_net_ae/EWIi96BorxtJpSZlQlXTU5gBlrydq...

 

 

please advise whats the best way to create Day Wise Filter Table with grouping Transaction Type With Date Wise.

Anonymous
Not applicable

You can change the granularity of your source data from "document level" to "day & type" level using SUMMARIZE. Refer to the example on your sample data given below...

 

Start with your Source Data.

 

Table Name: SourceData

 

SymbolTypeUnitsDateValue Per UnitTotal Value
DDDbuy401-01-20201.14.4
DDDbuy402-01-20201.24.8
DDDbuy403-01-20201.35.2
DDDbuy404-01-20201.45.6
DDDbuy405-01-20201.56
DDDsale1306-01-20202.532.5
DDDbuy407-01-20201.76.8
DDDbuy408-01-20201.87.2
DDDbuy409-01-20201.97.6
DDDbuy409-01-20201.97.6
DDDsale810-01-20203.528
DDDsale611-01-20204.527
DDDsale211-01-20204.59
DDDsale111-01-20204.54.5

 

Step 1: Add a "Calculated Table" to summarize at date and type level (Use NewTable option)

 

Table1 = 
    SUMMARIZE(
        SourceData,
        SourceData[Symbol],
        SourceData[Type],
        SourceData[Date],
        "Units",SUM(SourceData[Units]),
        "Value",SUM(SourceData[Total Value])
    )

 

Here we have given "Table1" as the name of the new table that we have created now.

 

Step 2: Add the following calculated columns. These are the same calculated columns that we have used in my earlier post.

 

 

StockInHandToday =
VAR CurrentSymbol = Table1[Symbol]
VAR CurrentDate = Table1[date]
VAR CurrentLineQty = Table1[Units]
VAR TotalPurchases =
    SUMX (
        FILTER ( Table1, Table1[Symbol] = CurrentSymbol && Table1[type] = "buy" ),
        Table1[Units]
    ) + 0
VAR TotalSales =
    SUMX (
        FILTER ( Table1, Table1[Symbol] = CurrentSymbol && Table1[type] = "sale" ),
        Table1[Units]
    ) + 0
VAR PurchasesAfterCurrentDate =
    SUMX (
        FILTER (
            Table1,
            Table1[Symbol] = CurrentSymbol
                && Table1[type] = "buy"
                && Table1[date] > CurrentDate
        ),
        Table1[Units]
    ) + 0
VAR CurrentStock =
    MAX (
        0,
        MIN ( TotalPurchases - TotalSales - PurchasesAfterCurrentDate, CurrentLineQty )
    )
VAR Result =
    IF ( Table1[type] = "Buy", CurrentStock, 0 )
RETURN
    IF ( Result = 0, BLANK (), Result )

 

 

 

StockAgeingInDays = 
VAR CurrentDate = TODAY()
VAR BuyDate = Table1[date]
VAR Age = ROUND(CurrentDate-BuyDate,0)
RETURN Age & " Days"

 

 

Add this to a matrix visual and you will get the following result.

 

InventoryAgeing2.png

 

In comparison to my earlier solution, the only change we have done this time is that we have changed the granularity of your "SourceData" table from "Document" level to "Day & Type" level using SUMMARIZE columns and used our formula in this new summarized table. To understand more about SUMMARIZE function, refer to the following link...

https://docs.microsoft.com/en-us/dax/summarize-function-dax 

 

 

Thank you very much for this great sılution. I've been looking for this kind of solution for months.

Anonymous
Not applicable

Additional Info

 

If you use this method for inventory ageing, although the quantity and age will show correctly, in case if you apply the same to the value of inventory, it will show based on moving average price.

 

Consider the following "buy" data

SymbolTypeUnitsDateValue Per UnitTotal Value
DDDbuy409-01-202028
DDDbuy409-01-2020312
Total 8  20

 

Here the 8 units purchased on 9th Jan 2020 are at different prices ($2 and $3). So the average value will be $2.5 (20/8). In case you have sold the 4 units bought at $2 and the remaining stocks are of value $3 per unit physically, your ageing report will still show the value based on $2.5 (the moving average) for the remaining 4 units because there is no way the system can determine that the balance stocks are bought at $3.

 

If you want to address this issue and want to show the value correctly, You are gonna need something like a "batch number" in your data for both "buy" and "sale" transactions and include the same to the "SUMMARIZE" function. If a "batch" number or some similar identifier is available to correlate the "buy" and "sale" data, then accurate value can be shown. Otherwise you will have to be content with the moving average price for "stock-in-hand". Hope you understand this limitation.

Hi Sreenath,

Thanks for your support.

I had created Summary Table with Date wise with Transaction type and Material.

But , I had issue with Purchase and Sales Return Transactions these transaction need to treated as seperate

DO No   Date      Material               Type                  QTY                            Reference no

0001       01/01/2019         Aaa        Buy                        15          

0002       02/01/2019         Aaa        Buy                        10          

0003       05/01/2019         Aaa        Purchase return      15                     0001

0004       04/02/2019         Aaa        Sales                        5             

0005       06/02/2019         Aaa        Sales return            2                       0004

 

Based on Above Scenario how can we handle,

 

Can we handline adding new QTY column if Return QTY different from original QTY ( Based on Reference No Column Original Doc No )  and if Return QTY is same as original QTY then can Exclude Original and Return transaction  with Additional Column indicator.

Anonymous
Not applicable

I am not very clear what you want to do with Sales Returns and Purchase Returns, but if you want adjust the "Returns" quantity in the original document itself, you can add two calculated columns to your table to get the following results.

 

 

DO NoDateMaterialTypeQtyReferenceAdjustmentAdjQty
000101 January 2019AaaBuy15 150
000201 February 2019AaaBuy10  10
000301 May 2019AaaPurchase Return150001 15
000402 April 2019AaaSales5 23
000502 June 2019AaaSales Return20004 2

 

The DAX for the last two columns "Adjustment" & "AdjQty" is as follows...

 

 

Adjustment = 
SUMX(
    FILTER(
        zinventory,
        zinventory[Reference]=EARLIER(zinventory[DO No])),
        zinventory[Qty])
AdjQty = zinventory[Qty]-zinventory[Adjustment]

 

 

 

Please note that I have just copied the sample data you sent on your last post and gave the table a name "zinventory". 

Once you do add these columns, instead of running inventory ageing transactions on the "Qty" field, you can run it on "AdjQty" field by changing the formulas accordingly.

 

If you follow this method, your inventory ageing report will show the ageing based on the original date of purchase and sales.

 

Alternatively, You can treat all "Purchase Returns" as "Sale" and all "Sales Returns" as "Buy"  and in this approach, you ageing will vary accordingly which will be like a true FIFO stack. The adjustment method mentioned above will be like, you will following "FIFO" only for "Buy" and "Sale" only and violate the FIFO (physically) by inserting at random positions in your stack, if you were to visualise a true FIFO stack operation.

Anonymous
Not applicable

Although we have adjusted the "Returns" quantity in the orginal document, the "Returns" line still shows the qty in AdjQty. If you don't want this, you could either make AdjQty to 0 in cases of "Returns" lines using conditional statements or filter out those "Returns" line from the table itself before passing this to the ageing calculation. 

hi sreenath.

 

Actually we need to follow orginal purchase , if we treat sales retun as buy then again will start from Retun Date where has its orginal purchase date may be diffrent...  thanks for your support and appreciated your support.

 

if you have any sinario for fast moving item DAX query please share me same. Same above data sinario need to Find Fast moving items and High Margin items.

 

 

 

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.