Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

Version requirement

This article requires Mobile WMS Extension version 5.14 (or newer).


Description

The most common control for customization. Adding a new function with "Header fields" and optional "Steps" to collect info based on the header request.Note: "Unplanned Item Registration" is also known as "Adhoc". In the following, we will refer to it as "Unplanned".

Prerequisites

Please read up Unplanned Functions to ensure this flow suits your requirement.


This example

  • Will result in an Unplanned function accessible by an icon on the Main Menu.
  • Three : A date, a text and a decimal.
  • And three similar Steps.



Step 1: Defining a new page for the Custom Lookup function 

This part requires you to edit the Mobile Configuration File


Add this section in the <pages> tag.

<!-- Custom -->
<page id="WorkDescription" type="Lookup" icon="stopwatch">
  <title defaultValue="Work Description"/>
  <lookupConfiguration type="WorkDescription" useRegistrationCollector="false">
    <header configurationKey="WorkDescriptionHeader" automaticAcceptOnOpen="true" hideAfterAccept="true"/>        
    <list listId="Lookup"/>       
  </lookupConfiguration>      
</page>
<!-- Custom -->


Add this section to the <actions> tag on the Pick page.

<!-- Custom -->
<open id="WorkDescription" icon="stopwatch" title="Work Description"/>
<!-- Custom -->




Step 2: Define Header and header fields

Unplanned functions uses to determine which Steps to collect.

In this step you must define which header fields you want the user to see.


Subscribe to this event


// >> DEMO CODE


// [Example] : Change Displayline1
    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Pick", 'OnGetPickOrders_OnAfterSetFromWarehouseActivityHeader''', true, true)]
    local procedure OnGetPickOrders_OnAfterSetFromWarehouseActivityHeader(_WhseActHeader: Record "Warehouse Activity Header"; var _BaseOrderElement: Record "MOB NS BaseDataModel Element")
    var
        WorkInfo: text;
    begin
        WorkInfo := GetWorkInfo(_BaseOrderElement.Get_BackendID());
        if WorkInfo <> '' then
            _BaseOrderElement.Set_DisplayLine1(_BaseOrderElement.Get_DisplayLine1() ' (Info)');
    end;



    // [Example 02]  Confirmation message when attempting specific lock type
    // https://docs.taskletfactory.com/display/TFSK/OnLockOrder_OnBeforeLockOrder

    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Order Locking", 'OnLockOrder_OnBeforeLockOrder''', true, true)]
    local procedure ShowConfirmBox_OnBeforeLockOrder(_MobDocumentQueue: Record "MOB Document Queue"; var _RequestValues: Record "MOB NS Request Element"; var _IsHandled: Boolean)
    var
        MobToolbox: Codeunit "MOB Toolbox";
        WorkInfo: Text;
    begin
        if _RequestValues.GetValue('Type''Pick' then begin
            WorkInfo := GetWorkInfo(_RequestValues.Get_BackendID());

            if WorkInfo <> '' then
                MobToolbox.ErrorIfNotConfirm(_RequestValues, WorkInfo);
        end;
    end;

    //https://docs.taskletfactory.com/display/TFSK/OnGetReferenceData_OnAddHeaderConfigurations
    // [Example] 01 - Create new custom ConfigurationKey
    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Reference Data", 'OnGetReferenceData_OnAddHeaderConfigurations''', true, true)]
    local procedure OnGetReferenceData_OnAddHeaderConfigurations(var _HeaderFields: Record "MOB HeaderField Element")
    begin
        // Identifier for new ConfigurationKey - replace by your own key name
        _HeaderFields.InitConfigurationKey('WorkInfoHeader');

        // Add headerConfiguration elements here                
        _HeaderFields.Create_TextField(1'BackendID');
    end;

    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Lookup", 'OnLookupOnCustomLookupType''', true, true)]
    local procedure OnLookup_OnCustomLookupType(_MessageId: Guid; _LookupType: Textvar _RequestValues: Record "MOB NS Request Element"; var _XmlResultDoc: XmlDocumentvar _RegistrationTypeTracking: Textvar _IsHandled: Boolean)
    begin
        if _LookupType = 'WorkInfo' then begin

            if _IsHandled then
                exit;

            WorkInfoLookup(_LookupType, _RequestValues, _XmlResultDoc);

            _IsHandled := true;
        end;
    end;

    local procedure WorkInfoLookup(var _LookupType: Textvar _RequestValues: Record "MOB NS Request Element"; var _XmlResultDoc: XmlDocument)
    var
        TempLookupResponseElement: Record "MOB NS WhseInquery Element" temporary;
        MobWmsLookup: Codeunit "MOB WMS Lookup";
        MobToolbox: Codeunit "MOB Toolbox";
        MobXmlMgt: Codeunit "MOB Xml Management";
        XmlResponseData: XmlNode;
        BackendId: Code[20];
    begin

        // Read Request        
        BackendId := _RequestValues.Get_BackendID();

        // Initialize the response xml
        MobToolbox.InitializeResponseDocWithNS(_XmlResultDoc, XmlResponseData, CopyStr(MobXmlMgt.NS_WHSEMODEL()11024));

        // Create new Response Element
        TempLookupResponseElement.Create();

        // Add info to Response Element
        AddWorkInfo(BackendId, TempLookupResponseElement);

        // Save new Response Element
        TempLookupResponseElement.Save();

        // Add Response Element to Look Response
        MobWmsLookup.AddLookupResponseElements(_LookupType, XmlResponseData, TempLookupResponseElement);
    end;

    local procedure AddWorkInfo(_BackendId: Code[20]; var _LookupResponseElement: Record "MOB NS WhseInquery Element")
    begin
        _LookupResponseElement.Init();
        _LookupResponseElement.Set_DisplayLine1(GetWorkInfo(_BackendId));
    end;

    local procedure GetWorkInfo(_BackendId: Code[20])Text
    var
        WhseActHeader: Record "Warehouse Activity Header";
        SalesHeader: Record "Sales header";
    begin
        if WhseActHeader.get(WhseActHeader.Type::"Invt. Pick", _BackendIdthen
            if SalesHeader.get(SalesHeader."Document Type"::Order, WhseActHeader."Source No."then
                exit(SalesHeader.GetWorkDescription());
    end;

//<< DEMO CODE



Step 3: Read Header and Define Steps (Optional)

When the header is completed/accepted a new request is made for which Steps to collect . ("GetRegistrationConfiguration")

In this step you must read the values header fields and define the subsequent steps.

You can choose to not collect any steps by setting useRegistrationCollector="false" in Mobile Configuration File.


You can use the already collected header fields values for:

  • - defining the steps still needed to be collected
  • - setting useful default-values on the steps 

Subscribe to this event

OnGetRegistrationConfiguration_OnAddSteps


    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Adhoc Registr.", 'OnGetRegistrationConfiguration_OnAddSteps''', true, true)]
    procedure MyOnGetRegistrationConfiguration_OnAddSteps(_RegistrationType: Textvar _HeaderFieldValues: Record "MOB NS Request Element"; var _Steps: Record "MOB Steps Element"; var _RegistrationTypeTracking: Text)
    var
        MyDate: Date;
        MyText: Text;
        MyDecimal: Decimal;
    begin
        // Handle only your own Header name
        if _RegistrationType <> 'MyUnplanned' then
            exit;



        // Read the headerFields
        MyDate := _HeaderFieldValues.GetValueAsDate('MyDate');
        MyText := _HeaderFieldValues.GetValue('MyText');
        MyDecimal := _HeaderFieldValues.GetValueAsDecimal('MyDecimal');


        // Add steps
        // For illustration, re-use the headerField value as default values on the steps
        with _Steps do begin
            Create_DateStep(10'MyDateStep');
            Set_header('MyDateStep');
            Set_defaultValue(MyDate);

            Create_TextStep(20'MyTextStep');
            Set_defaultValue(MyText);
            Set_header('MyTextStep');

            Create_DecimalStep(30'MyDecimalStep');
            Set_defaultValue(MyDecimal);
            Set_header('MyDecimalStep');
        end;
    end;



Step 4: Handle posting

When the Header has been accepted and Steps collected, a final request is made to "Post" the information ("PostAdhocRegistration")

In this step you must read the collected values and post them to the database.




Which fields do I have access to?

By simply running your function, you can inspect the Post Request directly.

See How-to: Inspect Request and Response XML documents

You might receive an error if your subscriber is not running.


Now you have an overview of which values are available to you.

Post Request
<?xml version="1.0" encoding="utf-8"?>
<request name="PostAdhocRegistration" created="2020-02-14T15:24:24+01:00" xmlns="http://schemas.microsoft.com/Dynamics/Mobile/2007/04/Documents/Request">
  <requestData name="PostAdhocRegistration">
    <MyDate>14-02-2020</MyDate>
    <MyText>2</MyText>
    <MyDecimal>4</MyDecimal>
    <MyDateStep>14-02-2020</MyDateStep>
    <MyTextStep>2</MyTextStep>
    <MyDecimalStep>4</MyDecimalStep>
    <RegistrationType>MyUnplanned</RegistrationType>
  </requestData>
</request>


Posting the Header/Steps values


Subscribe to this event: OnPostAdhocRegistrationOnCustomRegistrationType
  • Both Header values and Steps values are available.
  • The values are extracted from the _RequestValues parameter using "GetValue "functions.


    // Step 3: Handle posting
    [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Adhoc Registr.", 'OnPostAdhocRegistrationOnCustomRegistrationType''', true, true)]
    local procedure MyOnPostAdhocRegistrationOnCustomRegistrationType(_RegistrationType: Textvar _RequestValues: Record "MOB NS Request Element"; var _CurrentRegistrations: Record "MOB WMS Registration"; var _SuccessMessage: Textvar _RegistrationTypeTracking: Textvar _IsHandled: Boolean)
    var
        MyDate: Date;
        MyText: Text;
        MyDecimal: Decimal;
    begin
        if _RegistrationType <> 'MyUnplanned' then
            exit;


        if _IsHandled then
            exit;

        // Read _RequestValues
        MyDate := _RequestValues.GetValueAsDate('MyDateStep');
        MyText := _RequestValues.GetValue('MyTextStep');
        MyDecimal := _RequestValues.GetValueAsDecimal('MyDecimalStep');

        _SuccessMessage := StrSubstNo('Success %1 %2 %3', MyDate, MyText, MyDecimal);

        _RegistrationTypeTracking := 'Tracking info for the Document queue.';

        _IsHandled := true;
    end;

Display a success-message

For illustration, the steps-values are used in the message.


Set tracking info (optional)

The parameter _RegistrationTypeTracking can be used to make the Document Queue display additional information about your process.





Common error messages



"No document handler is available for GetRegistrationConfiguration::XYZ"

Error occurs when entering a Unplanned page.

Solution

You do not handle the definition (Header fields).

Add an event of GetRegistrationConfiguration with RegistrationType "XYZ"


"No document handler is available for PostAdhocRegistrationConfiguration::XYZ"

Error occurs when calling an Unplanned or Accepting the header.


Solution

You do not handle the posting.

Add an event of PostAdhocRegistration with RegistrationType "XYZ"

New menu item

"Work Description"" is shown in the context menu on the Pick Orders list.

Display Custom Look page


Message is displayed.

  • No labels