Dynamics 365 SCM Warehouse app pop-up windows

Dynamics 365 SCM Warehouse app pop-up windows

We faced an issue with pop-up windows in our current WHS App version. (2.0.11.0)

The issue is: Even if the default field values for the mobile device flow are specified users should confirm default values. 

In our case, we used a warehouse transfer flow with the various default values setups. For instance, one of the setup options is presented on the screenshots below:




However, a pop-up window appears and the user should select the value from the lookup:


But all field values are defined by default based on the default values of the menu item:


From a user perspective, it’s not really convenient to confirm default values after every step since users can make errors because of additional unnecessary confirmation steps. Additionally, it may be quite annoying to have an extra pop-up window where it should not appear. 

It seems there are two options to solve this issue:

1. Upgrading whs app to 2.0.19.0 version. We tested it, there is no such behavior. On the other hand, there is a guarantee that the app will not broke again.
2. It seems possible to change the whs mobile device app behavior via code. This option can be useful if there are some modifications that should be aligned.

Let’s discuss the second option if it is applicable for you.

If we take a look at the user session XML we will see that the Inventory status and To warehouse controls have the DisplayArea tag value - PrimaryInputArea :

<Control InputType="5760" Footer2="" Footer1="" InstructionControl="" AttachedTo="" DataSequence="5" DisplaySubPriority="81" DisplayPriority="90" PreferredInputType="Selection" PreferredInputMode="Manual" DisplayArea="PrimaryInputArea" NumDecimals="-1" Status="1" color="#0076E5" selected="Available" enabled="1" defaultButton="0" error="0" length="-1" type="Undefined" data="||Available||Blocking||Not avail||Rejected" newLine="1" label="Inventory status" name="InventStatusId" controlType="combobox"/>

<Control InputType="9259" Footer2="" Footer1="" InstructionControl="" AttachedTo="" DataSequence="6" DisplaySubPriority="0" DisplayPriority="0" PreferredInputType="Alpha" PreferredInputMode="Scanning" DisplayArea="PrimaryInputArea" NumDecimals="-1" Status="1" color="#0076E5" selected="25" enabled="1" defaultButton="0" error="0" length="-1" type="Undefined" data="15||25" newLine="1" label="To warehouse" name="ToWarehouse" controlType="combobox"/>

The rule seems to be: If the combo box control is in the primary area, a pop-up window will appear.

In order to change the DisplayArea tag we need to create an extension for the WHSMobileAppServiceDecoratorRuleDefaultDisplayArea class. It has some methods and delegates in order to define the control area, for instance:

• isComboboxInPrimaryInputArea and isComboboxInPrimaryInputAreaDelegate for Combobox controls (e.g. units, inventory status and others including developed combobox controls)

• isTextInPrimaryInputArea and isTextInPrimaryInputAreaDelegateisTextInPrimaryInputAreaDelegate for Text controls (e.g. batch number, sales order id and others developed added text controls)

In our case, we need to hide the pop-up windows for the Inventory status and To warehouse controls. In order to do it, the code as below can be written via extension:

protected boolean isComboboxInPrimaryInputArea(boolean             _enabled,

                                               Map                 _controlMap,
                                               str                 _data,
                                               WHSMenuItemName     _menuItemName)
{
    boolean ret;

    ret = next isComboboxInPrimaryInputArea(_enabled, _controlMap, _data, _menuItemName);

    if (_enabled
    &&  _controlMap.lookup(#XMLControlName) == #InventoryStatus)
    {
        return false;
    }

    if (_enabled
    &&  _controlMap.lookup(#XMLControlName) == #ToWarehouse)
    {
        return false;
    }

    return ret;
}

or via delegate:

[SubscribesTo(classStr(WHSMobileAppServiceDecoratorRuleDefaultDisplayArea),
staticDelegateStr(WHSMobileAppServiceDecoratorRuleDefaultDisplayArea,
isComboboxInPrimaryInputAreaDelegate))]
public static void WHSMobileAppServiceDecorator_isComboboxInPrimaryInputAreaDelegate(
                               boolean              _enabled,
                               Map                  _controlMap,
                               str                  _data,
                               WHSMenuItemName      _menuItemName,
                               EventHandlerResult   _result)
{    
    if (_enabled
    &&  _controlMap.lookup(#XMLControlName) == #InventoryStatus)
    {
        _result.result(false);
    }

    if (_enabled
    &&  _controlMap.lookup(#XMLControlName) == #ToWarehouse)
    {
        _result.result(false);
    }
}

NOTE: The code above is an example. The mobile device flow types, and other important conditions are not considered. Please, do not use this code in real implementation projects as it is. It must be adjusted for the real scenario.

After these changes we should not see pop-up window for the Inventory status and To warehouse controls anymore and the user session XML will change as follows:

<Control InputType="5760" Footer2="" Footer1="" InstructionControl="" AttachedTo="" DataSequence="5" DisplaySubPriority="81" DisplayPriority="90" PreferredInputType="Selection" PreferredInputMode="Scanning" DisplayArea="InfoAndSecondaryInputArea" NumDecimals="-1" Status="1" color="#0076E5" selected="Available" enabled="1" defaultButton="0" error="0" length="-1" type="Undefined" data="||Available||Blocking||Not avail||Rejected" newLine="1" label="Inventory status" name="InventStatusId" controlType="combobox"/>

<Control InputType="9259" Footer2="" Footer1="" InstructionControl="" AttachedTo="" DataSequence="6" DisplaySubPriority="0" DisplayPriority="0" PreferredInputType="Alpha" PreferredInputMode="Scanning" DisplayArea="InfoAndSecondaryInputArea" NumDecimals="-1" Status="1" color="#0076E5" selected="25" enabled="1" defaultButton="0" error="0" length="-1" type="Undefined" data="15||25" newLine="1" label="To warehouse" name="ToWarehouse" controlType="combobox"/>

I am glad if this finding can help someone to save their time.

Ax 2012. Automatic role assignment feature and deactivated users

Automatic role assignment feature and deactivated users

There is a brilliant Ax 2012 system feature - Automatic role assignment. Actually, there is the same feature in Dynamics 365 Finance and Operation as well but I have not tested it yet.

The standard Ax 2012 documentation can be found here:


The Automatic role assignment feature was used in one of our Ax 2012 projects and it worked perfectly fine. However, once we faced an issue that in some time after deactivating the user account all its roles were removed except standard one – System user. You can see the example of what we had after roles removing below:


It was really unexpected. Actually, we expected to see the same roles of the deactivated users as these users had had before deactivating their user accounts.

We investigated and discovered that the Automatic role assignment batch job (SysSecurityDynamicRoleAssignment class) removed/revoked all roles for deactivated users except the roles that had been assigned manually.

It seems that the Automatic role assignment feature has one special thing that was mentioned in the standard guide but it has not been explained for deactivated users clearly:
The user is either assigned to the role or removed from the role the next time that the rules for automatic role assignment run.

I would say that for deactivated users the following sentences can be added:

When the user is deactivated in the system, the Automatic role assignment feature will remove all automatic roles assignments except ones that have been done manually.

I am glad if this finding can help someone to save their time.



D365 SCM. Extension of promoted fields feature in the Warehouse Management mobile app

Extension of promoted fields feature in the Warehouse Management mobile app

Microsoft has recently introduced a promoted fields feature. It allows to promote and to highlight a specific information of each and any step in the task flows of the Warehouse Management mobile app. The setups are described here and a walkthrough demonstration is hereLet’s take a look at this feature from a technical perspective.

Overview

The key object is the WHSMobileAppFlow class. It is an abstract class that has a number of methods. We will take a look at the most important ones:

initValues              - it is an abstract method. It must be overridden when a new WHSMobileAppFlow derived class is created.

getAvailableFieldsit is used for default data created when the Create default setup button is hit on the Mobile device steps form.

addAvailableField - it is used for defining fields that should be available for promotion.

All other methods of  WHSMobileAppFlow class are either called up by the above-mentioned methods or they are internal and cannot be used in the code.

Promoted fields feature for new mobile device flows

For every mobile device flow, there is a derived class from the WHSMobileAppFlow object.
For example for the “UserDirected” flow:

[WHSWorkExecuteMode(WHSWorkExecuteMode::UserDirected)]
final class WHSMobileAppFlowUserDirected extends WHSMobileAppFlow
{
    protected void initValues()
    {
        this.addStep(WHSMobileAppStepIds::WorkId);
        this.addStep(WHSMobileAppStepIds::WHSWorkLicensePlateId);
        this.addWorkExecutionSteps();
 
        this.addWorkExecutionFields();
    }
}

So if we need to add the promoted fields feature for the custom developed WHS mobile app flow, we do the same – a new derived class from the WHSMobileAppFlow object.

[WHSWorkExecuteMode(WHSWorkExecuteMode::NewWorkExecuteMode)]
final class WHSMobileAppFlowNewWorkExecuteFlow extends WHSMobileAppFlow
{
    protected void initValues()
    {
        //adding necessary fields
        this.addAvailableField(extendedTypeNum(ItemId));
        this.addAvailableField(extendedTypeNum(Qty));
    }
}

After compilation and recreating the setups via the Create default setup button on the Mobile device steps form, the added fields should be available for the promoted fields feature:


Note: Please keep in mind, the addStep method cannot be used with WHSMobileAppStepIds::EnumValue since the WHSMobileAppStepIds class is marked as internal (10.0.24). Probably it can be changed in the future versions.

Promoted fields feature for new mobile device fields

Let's imagine there is a new field that we would like to use with this feature. For example, a new inventory dimension was added as described here.
In this case, we needed to add a new extension for the WHSMobileAppFlowUserDirected class, for instance:

[ExtensionOf(classStr(WHSMobileAppFlowUserDirected))]

final class WHSMobileAppFlowUserDirected_Extension
{
    protected void initValues()
    {
        next initValues();

        this.addAvailableField(extendedTypeNum(InventDimension1));

    }
}

After compilation and recreating the setups via the Create default setup button on the Mobile device steps form the added field should be available for the promoted fields feature:

Important:  For the mentioned extended data types (ItemId, InventDimension1) derived classes from the WHSField class should be developed as described here. Otherwise, it can be not really possible to add new fields.



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...