Code highlighting

Showing posts with label Wave processing. Show all posts
Showing posts with label Wave processing. Show all posts

Sunday, December 02, 2018

[Tutorial] Automating Release to Warehouse process through Wave Template configuration

Introduction

Currently many companies resort to manually choosing which shipments need to be added to a wave we are about to process, which is slow and error prone, as the user needs to check up on each of the shipments, understand where it is headed, what types of items are on it, which mode of delivery is used, etc.

Today I would like to show a demo example of how to configure wave templates, as to allow a more optimal distribution of orders, based on, say, delivery mode, or some other cut-off criteria. Automatically, without any user interaction.

Disclaimer

I will not be talking about Automatic release of sales/transfer orders to warehouse in this post. We'll discuss that at a later point in time. Today it is only about making sure certain orders are grouped on a single wave automatically, based on defined criteria, so that they can be processed in the warehouse at the same time. This of course comes hand in hand with automatic release, which would enable a pretty much automatic operation for certain orders

Wave template configuration

Imagine that I would like to accumulate and then process all 2-day shipping orders at once, every second day, so I have the picking done before 4 pm that day when the UPS (or other 3PL) truck arrives to pick them up.
For these orders I want to pick as fast as possible, and the inventory is typically already at the locations and does not need special packaging, so I will not include replenishment and containerization steps into it, and will configure my work template to take the goods straight to the bay doors. 
I would also like to limit the number of shipments on each of the waves to 10, so as to not overwhelm my workers. Instead, I'll release another wave later in the day if necessary.
Generally, I'd like the wave to be processed automatically as soon as 10 shipments have accumulated, but throughout the day my Wave planner might process another wave, depending on the situation.

Here's how my wave template would look for this case:

2 day shipping wave template configuration for warehouse 24

Here's how I have configured the corresponding query:
Note. No need to add any filters on Site or Warehouse, as these will be automatically added.

I want to only look at shipments for Sales orders, and only those that have a 2 DAY shipping mode of delivery. Pretty simple. If I wanted, I could make this much more granular, by adding additional table joins and adding filters on them.

2 day shipping wave template query

Sales orders

Now let's create a couple sales orders, set the Mode of delivery correctly, reserve the inventory and release the orders to the warehouse.

Note. The field that is transferred to the shipment is taken from one of two:

  • Mode field on the sales order, if the Mode of delivery is not filled in.
  • Mode set on the Carrier associated with the specified Mode of delivery.
Mode of delivery specified on Sales order 000910
I only added one simple line for the example, on both sales orders.

Sales line for Sales order 000910

Release to warehouse

When we release the first order to the warehouse, we will create a new shipment, which will have the correct Mode of delivery. We will then proceed to search for a wave template that matches it, based on Site, Warehouse, as well as the defined query. Our newly created wave template should succeed here.
We will not however be able to find an existing Wave in status Created, that would match the Site and Warehouse for the shipment that is also using the same wave template. Which means we will go and create a new Wave
Note. A new wave is created because of the Wave template setting Automate wave creation

When we release the second order to the warehouse though, we will find the wave created above, and because the conditions for adding to the same wave are met, and the wave template has Assign to open waves marked as Yes, we will add the shipment to the found wave instead of creating a new one.

Here's how the resulting wave looks:

Wave created based on the two sales orders


FAQ

Q: What if there is more than one wave in status Created, that was created based on the "right" wave template, and is for the same Site and Warehouse as the newly created shipment? Which wave will the shipment get assigned to?
A: The first of the waves that matches all of the criteria which also does not exceed the thresholds.

Q: Can I use fields directly from the sales order in the wave template query?
A: Yes, but you will need to join to get them. The right way would be to first join the load lines for the shipment, then the order lines related to the load lines, and then the sales order headers related to the sales lines. (Not directly from the shipment, even thought that will work just fine for certain businesses that always have only 1 shipment per 1 order)

Conclusion

As you can see, setting up a wave template that will group multiple shipments and create a new wave if necessary is relatively simple - you just need to get a few of the specifics correct in the setup, and then everything will work like a charm.

In one of the next posts we will combine this configuration with automatic release of sales orders, to achieve full automation of sales order release process, where no user interaction is necessary at all past the sales order creation and confirmation step.

Monday, October 15, 2018

Telemetry as part of the Dynamics 365 Finance and Operations life-cycle

How much telemetry are we collecting?

A lot, like, really a lot!

That includes kernel level information, like an online user session requesting web access to a particular AOS to perform business operations through the web UI, a web service request to handle a mobile device operation, an OData request for exporting or importing data, exceptions and other infolog messages displayed to the user, etc.

It also includes specific application-level information, like details about each step during an inventory update, or information about the different wave processing steps, the specific flow happening on the warehouse mobile device, etc.

And we keep adding to it to have more and more granular information about what exactly is happening in the system at any particular point in time.

How can I access all this telemetry?

You can find it under "View Raw Logs" under Environment Monitoring in LCS.
It's very well described in the following two articles, so please read through those at this point:
You can then use the different search options described above to query out the specific events you are interested in.

What about Warehouse - specific telemetry, say, Wave processing?

Depending on the version of the product you are running, it differs slightly. 

Here's how you would search for wave processing events on releases before Fall release of 2018:


Raw logs search criteria

Note The above query options is a preview feature, so is most probably not visible to you yet.

If you then wanted to filter on a specific wave, for example, you could add that to the search criteria as well. 
Note that due to compliance, all of the information is not exposed directly, but rather RecIds are used. So you'd need to retrieve the RecId of the wave you wanted to investigate.

Here's some of the fields you should take note of:
  • The TIMESTAMP column would tell you when exactly the event occurred
  • RoleInstance would show, which AOS the activity happened on. This could be useful when troubleshooting caching and other cross-AOS issues
  • ActivityId is a way for you to limit to only a specific smaller process (for example, a specific allocation thread), and dig deeper, for example, to analyze the slow queries that happened as part of that activity
  •  infoMessage would contain information about the actual wave step performed, as well as specific details about the step, like how many load lines were processed, how long it took, etc.
TaskName: WhsPerformanceTaskStop, ruleName: waveProcessing, actionPerformed: runWaveStep, durationInMilliSeconds: 0, details: {"allocatedLoadLines":"500","custom":"no","waveId":"5637815827","waveStep":"WhsPostEngineBase.allocateWave"}

From Fall release onward

You could search for WHSPerformanceTaskStart/Stop directly in the TaskName instead of as part of infoMessage. The rest still applies.

What about mobile device telemetry - do we capture that?

Of course we do :)

Just search for TaskName == WhsUserActivityEvent
This event contains the same basic information as mentioned above, as well as stuff specific to the mobile flow:
  • Company, Site and Warehouse, where the warehouse user is operating. (RecIds)
  • WorkExecuteMode and step for the specific flow. You'll need to lookup the actual step in code
  • GUID of the mobile device user session
  • WorkTransType, as well as WorkTable and WorkLine RecIds being processed
  • RequestXML - this is the actual request, except all the data and labels are scrubbed, so it shows just what controls are shown on the screen
This event, if you search for it in code, is invoked at the very end of processing the user input from the mobile app.

You can correlate these events with those of TaskName == RequestContext, where the url of the request contains "/api/services/WHSMobileAppServices/WHSMobileAppService/getNextFormHandHeld" - this is the actual web service call as it arrives at the AOS, so the point in time when the AOS starts handling the mobile app flow step. 

Everything that happens in between with the same ActivityID is part of the flow, whether that is slow queries, error messages or other relevant events.

I don't see these events - what should I do?

We have back-ported a lot of the telemetry through hotfixes. Search for it on LCS for your specific release. 
But I would also like to take this opportunity and move up to the latest release. There is soo much goodness in there!

Should partners be adding telemetry?

ABSOLUTELY!
  • If you are a client, I suggest that you start insisting your partners adds telemetry with any new code the push into production.
  • If you are a partner, I suggest you start adding it asap - you'll save yourself a lot of time going forward, if the customer has an issue with your code. Since you cannot just debug in production any longer, you'll need to rely much more on alternative ways of telling you what exactly happened. Telemetry is the solution.

Where do we start? Do we have some examples?

We are working on the guidance for this and will share this out very soon.


Yes, all of the application telemetry is added directly as part of the application code, so should not be too difficult to find.
I suggest that you rely on the same event "InfoLogMark" as shown below as well.
Consider adding a using statement to reduce the invocation.

Microsoft.Dynamics.ApplicationPlatform.XppServices.Instrumentation.XppRuntimeEventSource::EventWriteInfoLogMark(
                                      Exception::Info, strFmt('TaskName: , etc.', );

What else should be captured out of the box that is critical for you?

Let me know in the comments!
Thanks