Latest Enterprise DNA Initiatives

Allocation Question - Flow of Goods

Hello Community:

I have personal question which I hope to learn for some future reference. I wanted to know what type of DAX could be used to spread the order value to the appropriate date based on an in-stock position.

I have attached a simple file to demonstrate the question. Essentially how can I move the order value to the date when it becomes in stock again in a dynamic and efficient way?

If anyone has input on this I would greatly appreciate it. I just learned a very cool application from Brian and I thought I’d ask for additional input.

Thank you! File attached.Flow of Goods.pbix (71.7 KB)

@Whitewater100,

I jumped in and started writing DAX to try to meet your requirements, but the further in I got, the more I realized that the data model for the example may have been simplified past the point at which it makes logical sense. For example, the product dimension table contains fact-type elements like stock status and in-stock date, which implies either that each product only has one unique in stock date, or product ID does not uniquely determine product. In addition the order table does not have an order ID, but uses product ID as its key, implying that each product can only be ordered once.

This is one of those cases where no matter how skillfully the DAX is written, it will not return proper results due to flaws in the data model. The good news is that Enterprise DNA has extensive showcase resources on inventory management, where you can take a look at the PBIX files and based on those build an inventory management data model that will support the analyses you need to do.

Here’s an excellent blog entry by @sam.mckay on how to set up such a model. I suspect once you get that set up, it will make writing the correct DAX much easier.

I hope this is helpful.

– Brian

1 Like

Hi Brian:

I just checked out Sam’s video’s and I se some great application for me. So thanks for that:-)

What I’m trying do accomplish is based on the updated example file. Essentially dynamically revising the flow of goods based on the new in-stock dates. To demonstrate I created an extra table that shows how the desired ship date get’s changed to the new in-stock date (if it was out-of-stock).

I was wondering about the DAX to be used versus me creating an extra table like I am doing here. I made the model ultra-simple just to show a revised ship pattern. I’ll attach the updated one so you can see what I mean.Flow of GoodsR.pbix (75.0 KB)

I hope this makes more sense.

Thanks for your help in the past and any ideas on this one.

@Whitewater100,

Okay, taking the data model as a given, see if this does the trick:

image

Here are the key measures:

Revised Ship Date = 
VAR SelProd =
    SELECTEDVALUE( Product_Status[Product] )
VAR SelDesiredDate =
    SELECTEDVALUE( Order_Data[Desired Ship Date] )
VAR MinFulfillDate =
    CALCULATE(
        MIN( Product_Status[In-Stock Date] ),
        FILTER(
            'Product_Status',
            Product_Status[Product] = SelProd
                && Product_Status[In-Stock Date] >= SelDesiredDate
        )
    )
VAR NewDate =
    CALCULATE(
        SWITCH(
            TRUE(),
            SELECTEDVALUE( Product_Status[Stock Status] ) = "In-Stock", FORMAT( SELECTEDVALUE( Order_Data[Desired Ship Date] ), "m/d/yyyy" ),
            SELECTEDVALUE( Product_Status[Stock Status] ) = "Out of Stock", FORMAT( MinFulfillDate, "m/d/yyyy" )
        ),
        FILTER( Order_Data, [Total Order Amount] <> BLANK() )
    )
VAR Result =
    IF( LEN( NewDate ) = 0, "Cannot be Fulfilled", NewDate )
RETURN
    IF( HASONEVALUE( Order_Data[Desired Ship Date] ), Result, BLANK() )

Revised Ship Amount = 
VAR RevisedAmount =
    IF(
        [Revised Ship Date] = "Cannot be Fulfilled",
        0,
        SELECTEDVALUE( 'Order_Data'[Order Amt] )
    )
VAR Adj =
    CALCULATE(
        SUM( 'Order_Data'[Order Amt] ),
        FILTER( 'Order_Data', [Revised Ship Date] = "Cannot be Fulfilled" )
    )
VAR vTable =
    ADDCOLUMNS(
        SUMMARIZE(
            Order_Data,
            Product_Status[Product],
            Product_Status[Stock Status],
            Product_Status[In-Stock Date],
            Order_Data[Desired Ship Date],
            Order_Data[Order Amt]
        ),
        "@RevAmt", RevisedAmount
    )
VAR Result =
    IF(
        HASONEVALUE( Order_Data[Desired Ship Date] ),
        RevisedAmount,
        SUM( 'Order_Data'[Order Amt] ) - Adj
    )
RETURN
    Result

I hope this is helpful. Full solution file attached below.

1 Like

Hi Brian:

You are amazing. I appreciate the work you do to support people like me in the forum. I took a shot of a potential alternative and have not totally flushed it out. If I put both the desired ship date and new ship date in the same table I am wondering if this approach makes sense to call out the adjustment. Then possibly manipulate the original flow of goods to take into account the pushed back ship dates. The measures look like this below. The first one is a calculated Flag column. What do you think?

Out of Stock Flag CC = IF(OOSQL[New Ship Date] > OOSQL[DESIRED_SHIP_DATE], TRUE(), FALSE())

Open Order Amnt (New Ship Date) =
CALCULATE([Open Order Amt],
USERELATIONSHIP(Dates[Date], OOSQL[New Ship Date]),
OOSQL[Out of Stock Flag] = TRUE()
)

Open Order Adj FOG = [Open Order Amt] - [Open Order Amnt (New Ship Date)]

Thanks again and have a great weekend!

Best regards,
Bill

@Whitewater100,

Glad to hear that you are reworking the data model. The fact that I had to create a “Cannot Be Fulfilled” bucket in the above DAX measure was a flashing red siren indicating that ship was going down (over time every row of the table would fall into that bucket).

My recommendation would be to forget about any more DAX at this point and focus on developing:

  1. plain English specification of the questions you ultimately want to be able to answer (i.e., analysis plan). Here’s an example of the type of analysis planning that I do in advance of data modeling. There are often many ways to construct a star schema model for a given project, and a sound analysis plan provides a great blueprint for that construction.

  2. build the star schema data model that will support answering those questions

Once you’ve done these things, particularly if you’ve pushed everything upstream to Power Query that should be done in the data prep stage, your DAX will likely be much simpler and more intuitive.

Since I’ve started focusing on doing things that way, I rarely have to venture into complex DAX in my own reports. In fact, one of the reasons I enjoy the forum so much is that it helps me keep my DAX skills sharp, since in my own reports most of the DAX is pretty plain vanilla, because I’m letting the analysis planning, Power Query and the data modeling carry the bulk of the load. DAX is used primarily for supporting the UX, conditional formatting, and anythiing that needs to be dynamic within the course of a reporting session.

Hope this is helpful.

  • Brian