Adding a conditional step to a flow

Problem

The traditional way an unplanned registration flow works in Mobile WMS, is that info is entered on the page header. This info is sent to the backend Mobile WMS installation as a request.

The backend responds with a set of registration collectors generated to correspond to the information entered in the header. An example could be, that an Item ID is entered in the header, and the backend responds with registration collectors, to send the user into a flow, where the user must fill out the active dimensions for that particular item.

When the user has entered the last information in the flow, the info is sent to the Mobile WMS backend, and posted.

But what if one of the steps/Registration Collectors in the flow, has content that is conditional on the information entered in the previous steps? Or if during the posting, an additional information is needed?

In that case you need to put an additional step in the flow on the fly.

Solution

With a recent update it is now possible for the posting process, to send back additional steps to the mobile device if it is needed.

In the standard Mobile WMS solution for Dynamics AX or 365FO, the Unplanned Count has a flow, where you enter the Item ID, and the backend sends back steps to prompt the user for the relevant dimensions plus the counted quantity for the item on the given location with the given dimansions.

Sometimes there is a need for this quantity to be prefilled with on hand quantity.

In the standard flow, this is not possible, as the dimensions and the quantity are sent out in the same group of steps/registration collectors. In this case the class must be changed to send out the quantity step after the dimensions have been posted.

The first thing, that needs to be changed, is to make sure the quantity step is not sent out with the dimensions.

To do this, the changes must be made to the class MobDocUnplannedCount, and the method createUnplannedCountConfiguration() which is the method generating steps to be collected from the user.


createUnplannedCountConfiguration()
/// <summary>
/// Method to create an unplanned count configuration.
/// </summary>    
[MobCollectorMap(classStr(MobGetRegistrationConfiguration),staticMethodStr(MobConstants,UnplannedCount))]
public Map createUnplannedCountConfiguration()
{
    Map returnMap;// = new Map(Types::Integer, Types::Class);
    MobRequestItemAndDimensionElement postRequest = request;
    //SysDictType dictType;
    int add = 10;
    InventDimParm parm;
    parm =  InventDimParm::activeDimFlag(InventDimGroupSetup::newInventTable(postRequest.parmInventTable()));
    //if (dimLocked)
    if (request.parmRawItemId() != request.parmItemId())
    {
        Parm.clearProductDimensions();            
    }
        
    parm.InventSiteIdFlag = NoYes::No;
    parm.InventLocationIdFlag = NoYes::No;
        
    #if.isAX6
    parm.WMSPalletIdFlag = mobInventDimSetup.registerWMSPallet();
    parm.WMSLocationIdFlag = !mobInventDimSetup.registerWMSPallet();
    #endif
                
    //Ensure, that if item is not serialnumber controlled, ask for Qty instead
    //parm.InventSerialIdFlag = NoYes::Yes;

    returnMap = MobInventDimHelper::GetInventDimCollectors(add,MobInventDimSetup::Construct(postRequest.parmInventTable()),parm);
        
    return returnMap;
}

In the above code, line 28 has been disabled, thereby telling the GetInventDimCollectors method, to not add quantity to non-serialnumber controlled items.

This effectively makes sure the quantity is never asked for.

Next step is to change the posting method to handle, that no quantity has been entered, and prompt for it. This is handled in the method postUnplannedCount()

postUnplannedCount
[MobPostMethod(tableStr(inventJournalTable)), MobDocumentType(classStr(MobPostAdhocRegistration), staticMethodStr(MobConstants,UnplannedCount))]
public void postUnplannedCount()
{
    //XmlNode     requestDataNode = requestXml.root().getNamedElement(#requestData);
     MobRequestItemAndDimensionElement postRequest = request;
    InventDim   inventDimIssue = postRequest.parmInventDim();
    ItemId      itemId          = postRequest.parmItemId();//MobHelper::ExtractItemId(inventDimIssue, requestDataNode, #ItemNumber);
    Qty         qty;
    //MobHelper::ExtractInventDim(inventDimIssue, ItemId, requestDataNode);
    inventDimIssue = InventDim::findOrCreate(/*dimLocked ? inventDim : */postRequest.createToInventDim(inventDimIssue));

 	if (!postRequest.getFieldValue(MobConstants::Quantity())) //Check if a quantity step was returned
    {
        this.addFunctionCollectors(methodStr(MobDocUnplannedCount,createQuantityFollowup));
        str xml = this.getResult();
        resultXml = new XmlDocument();
        resultXml.loadXml(xml);
        resultStr = 'additional info needed';
        return;
    }        

    qty = postRequest.parmQuantity();
        
    inventJournalTable = MobPostHelper::PostUnplannedCount(itemId,inventDimIssue,qty);
    resultStr = SysLabel::labelId2String2("@MobileWMS:CountingPosted");
}

The added functionality here is from line 12 to 20, where it checks whether a quantity step has been returned, otherwise, it will add the prompt for it.

In line 14 a new method is referenced. This is the method returning the quantity step, which can be seen below:

createQuantityFollowup()
public Map createQuantityFollowup()
{
    MobRequestItemAndDimensionElement postRequest = request;
    Map             returnMap = new Map(Types::String, Types::Class);
    InventOnhand    inventOnhand;
    InventDim       inventDimOnHand = postRequest.createToInventDim(postRequest.parmInventDim());
    InventDimParm   inventDimParm;
    int				add =1000;

    inventDimParm.initFromInventDim(inventDim);
    inventOnhand = InventOnhand::newParameters(postRequest.parmItemId(), inventDim, inventDimParm);
        
    // Add the step to register the Quantity     
	returnMap.insert(MobConstants::Quantity(),MobRegistrationCollectorDecimal::DecimalStepMap(add,MobConstants::Quantity(),"@SYS130676",new SysDictType(extendedTypeNum(Qty)).label(),'',false,strFmt('%1',inventOnhand.availPhysical()),0,10000000,14,MobConstants::GS1_QTY()));               
	return returnMap;
}


See also