Dynamics 365 Supply Chain Management WHS extending. Adding a new work type for "User directed" mobile device flows.

Introduction

I would like to share my experience with adding a completely new work type. In my case, I have added a new work type for "User directed" mobile device flows. My post is not a complete guide on how to do it. It is more about the main idea and some thoughts. 

Note: There is a post on how to work with the “Custom” work type. It is different.

Overview

WHSWorkType enum extending

First, it is necessary to extend the standard "WHSWorkType" enum in order to add a new work type.

Adding new mobile device step

Then, since it is a new work type it makes sense to add a new step so that the system can process the new work type. The new step should not have one of the existing numbers in the standard macro “WHSWorkExecuteDisplayCases”. 
We can create a new macro or use an existing one for this purpose and add a new step:

#define.NewWorkStep(10000)

Adding a new class handler for the new work 

After that, we need to create a new class handler for the new work type:

/// <summary>
/// The <c>WhsNewWorkTypeHandler</c> class handles new work type.
/// </summary>
[WhsWorkTypeFactory(WhsWorkType::NEWWorkType)]
class WHSNewWorkTypeHandler extends WhsWorkTypeHandler
{}

In this class, we need to implement the methods:

  • findWorkCreateLocationQty – sets the parameters of the processing.
  • determineStep – defines the first step of the flow for the work type. Also, you can add a mobile device screen to be shown for users.
  • executeWorkLine – defines the actions with the work line.

Note: In the system, there are “WhsWorkTypePrintHandler” and “WhsWorkTypeCustomHandler” classes that can be used for a better understanding of the work type handler classes.

Below is a mockup of the possible solution:

public WhsWorkCreateLocationQtyResult

    findWorkCreateLocationQty(WhsWorkCreateLocationQtyParameters _parameters)
{
   WhsWorkCreateLocationQtyResult result; 
   
   result = WhsWorkCreateLocationQtyResult::construct();

   result.locationId       = '';
   result.pickUnitId       = _parameters.unitId;
   result.pickQty          = _parameters.qtyWork;
   result.inventPickQty    = _parameters.inventQtyWork;

   return result;
}

public void determineStep(WhsWorkStepContext _context)

{
    WhsWorkExecuteDisplay   workExecuteDisplay = _context.workExecuteDisplay;
      
    //we can to go to the custom dialog if we would like to
    _context.nextForm   = workExecuteDisplay.DrawNewScreen();
    _context.step       = #NewWorkStep;
}

public WHSWorkLine executeWorkLine(WhsWorkExecute     _workExecute, 

                                   WHSWorkLine        _workLine, 
                                   WHSUserId          _userId)
{
    return _workExecute.processNewWorkType(_workLine.WorkId, 
                                           _workLine.LineNum, 
                                           _userId);
}

When we implement the handler class and the new step in the mobile device flow for the new work type we need to be able to process the new step correctly.


WhsWorkExecuteDisplay class extending

If we take a look at the "processWorkLine" method of the "WHSWorkExecuteDisplay" class we will see that there is a default section for new mobile device steps.

default:

   boolean finishedProcessing = this.processWorkLineForCustomStep(state);
   
   if (finishedProcessing)
   {
       return [state.nextForm, step, state.recall, pass.pack()];
   }
   break;

So, the next step is to create an extension of the WhsWorkExecuteDisplay class and implement the "processWorkLineForCustomStep" method. The "processWorkLineForCustomStep" method has the "Replaceable" attribute so in your extension you can write any business logic

Note: I would recommend using the “next” command in the “processWorkLineForCustomStep”, for instance:

protected boolean 

        processWorkLineForCustomStep(WhsWorkProcessWorkLineState _state)
{
    boolean    ret;
    ……………………………………
    switch (step)
    {
               case #NewWorkStep:
           //do something
           ret = true; //in case the step has been processed correctly
           break;

       default :
           ret = next processWorkLineForCustomStep(_state);
    }
   
    return ret;
}

In this case, if there is more than one extension of this method (for example, from multiple vendors) all of them will be called by the system. 

If you don’t call the “next” command, only your method extension will be called. All other method extensions can be ignored by the system.

If the new step has been processed correctly it is required to return the "True" value. In this case, the system returns the values from your method in the mobile device flow and the standard code after the "processWorkLineForCustomStep" is not executed.

When you jump into your new step you can develop your own mobile device screens and switch between them depending on the buttons and controls in use. When you are done with the new work type you need to "go back" to the standard mobile device steps.


Conclusion

For sure some code adjustments and extensions can be desirable in other objects too. It depends on the business logic that is planned to be implemented with a new work type. In my opinion, the text above can be used as a high-level guide.


No comments:

How to run batch tasks using the SysOperation framework

Overview As you may know, the system has batch tasks functionality . It can be used to create a chain of operations if you want to set an or...