Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Description

Excerpt

Add a new Unplanned Function as action on Pick Lines

This example gives you

  • An new Unplanned function as action in Pick Lines
  • Three
    • Location
    • Bin
    • Item
  • Three Steps

The workflow

Make sure the unplanned workflow suits your requirement.

Step 1: Defining a new Unplanned function 

This part requires you to edit the Mobile Configuration Files

Add this section in the <pages> tag.

Code Block
languagexml
themeEclipse
<!-- Custom -->
  <page id="MyUnplanned" type="UnplannedItemRegistration">
    <title defaultValue="Titletext"/>
    <unplannedItemRegistrationConfiguration type="MyUnplanned" useRegistrationCollector="false">
      <header configurationKey="MyHeader" automaticAcceptOnOpen="true"/>
    </unplannedItemRegistrationConfiguration>
  </page>
<!-- Custom -->

Do you want this to be accesible from an existing page in the Action Menus

Then add this section to the <actions> tag.

Code Block
languagexml
themeEclipse
<...>
<actions>
  <!-- Custom -->
  <open icon="mainmenusettings" id="MyUnplanned" title="My Unplanned">
    <returnTransfer property="UnplannedItemRegistrationCompleted" to="RefreshOnResume"/>
  </open>
  <!-- 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

OnGetReferenceData_OnAddHeaderConfigurations

    // Step 2: Define Header and headerFields

Description

Excerpt

Add a new Unplanned Function as action on Pick Lines. 

Use case

This example shows you how to transfer values from an Order Line to a new unplanned function.

Calculating the remaining quanity of the line and presenting this to the user, for them to change.

Note: The example has no logic to save the collected quanity in the database


This example gives you

  • An new Unplanned function as action in Pick Lines
  • Three
    That transfers Location, Bin and Item from the Order lines
  • One decimal step to collect a value from the user 

The unplanned workflow

Make sure the unplanned workflow suits your requirement.

Step 1: Defining a new Unplanned function 

This part requires you to edit the Mobile Configuration Files


Add this section in the <pages> tag.

Code Block
languagexml
themeEclipse
<!-- Custom -->
<page id="UnableToPick" type="UnplannedItemRegistration" icon="mainmenunegativeadjustment">
    <title defaultValue="Unable To Pick"/>
    <unplannedItemRegistrationConfiguration type="UnableToPick">
    <header configurationKey="UnableToPick" automaticAcceptOnOpen="true"/>
  </unplannedItemRegistrationConfiguration>
</page>
<!-- Custom -->


We want to add this to the existing Pick Lines page in the Action Menus 

Then add this section to the <actions> tag of Pick Lines page:

Code Block
languagexml
themeEclipse
<page id=Picklines...>
<...>
<actions>
  <!-- Custom --> 
    <open id="UnableToPick" icon="mainmenunegativeadjustment" title="Unable To Pick"/>
  <!-- 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

OnGetReferenceData_OnAddHeaderConfigurations


 [EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Reference Data", 'OnGetReferenceData_OnAddHeaderConfigurations', '', true, true)]
    localprocedure MynGetReferenceData_OnAddHeaderConfigurations(var _HeaderFields: Record "MOB HeaderField Element")
    begin
        _HeaderFields.InitConfigurationKey('UnableToPick'); // Name of Header

        // Add Header fields
        // Using pre-defined helper-functions makes it easy to transfer values as field names match 100%
        _HeaderFields.Create_ListField_Location(10);    // 'Location' is a known field on OrderLines response
        _HeaderFields.Set_locked(true);

        _HeaderFields.Create_TextField_FromBin(20);     // 'FromBin' is a known field on OrderLines response
        _HeaderFields.Set_locked(true);

        _HeaderFields.Create_TextField_ItemNumber(30);  // 'ItemNumber' is a known field on OrderLines response
        _HeaderFields.Set_locked(true);
    end;


Step 3: Return Steps to collect

When the header is accepted a new request is made for which Steps to collect, called  "GetRegistrationConfiguration".

Subscribe to this event

OnGetRegistrationConfiguration_OnAddSteps

    [EventSubscriber(ObjectType::Codeunit,  Codeunit::"MOB WMS Reference DataMOB WMS Adhoc Registr.",  'OnGetReferenceDataOnGetRegistrationConfiguration_OnAddHeaderConfigurationsOnAddSteps',  '',  truetrue,  truetrue)]
    local procedure MynGetReferenceData_OnAddHeaderConfigurations(var _HeaderFields: Record "MOB HeaderField Element")
    begin
        _HeaderFields.InitConfigurationKey('MyHeader')// Identifier for new Header - replace by your own name        // Add Header fields here
        _HeaderFields.Create_DateField(10'MyDate''Select date');
        _HeaderFields.Create_TextField(20'MyText''Enter text');
        _HeaderFields.Set_optional(true);
        _HeaderFields.Create_DecimalField(30'MyDecimal''Enter decimal');
    end;

Step 3: Return Steps to collect (Optional)

When the header is accepted a new request is made for which Steps to collect, called  "GetRegistrationConfiguration".

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

If you want to collect steps you must set useRegistrationCollector="true" in Mobile Configuration Files.

Code Block
languagexml
themeEclipse
<page>
  <unplannedItemRegistrationConfiguration type="MyUnplanned" useRegistrationCollector="true"> 
<..>

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

        // Step 3: Define Steps (optional)

        [EventSubscriber(ObjectType::CodeunitCodeunit::"MOB WMS Adhoc Registr.", 'OnGetRegistrationConfiguration_OnAddSteps''', true, true)]
        local 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
            _Steps.Create_DateStep(10'MyDateStep');
            _Steps.Set_header('MyDateStep');
            _Steps.Set_defaultValue(MyDate);
            _Steps.Create_TextStep(20'MyTextStep');
            _Steps.Set_defaultValue(MyText);
            _Steps.Set_header('MyTextStep');
            _Steps.Create_DecimalStep(30'MyDecimalStep');
            _Steps.Set_defaultValue(MyDecimal);
            _Steps.Set_header('MyDecimalStep');
        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.

    Run your function fra Mobile and 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. Image Removed

    Code Block
    languagexml
    themeEclipse
    titlePost 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>

    Subscribe to OnPostAdhocRegistrationOnCustomRegistrationType

    • Both Header values and Steps values are available.
    • The values are extracted from the _RequestValues parameter using "GetValue "functions.

        [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;
            localprocedure CollectFailedQty(_RegistrationType: Text; var _HeaderFieldValues: Record "MOB NS Request Element"; var _Steps: Record "MOB Steps Element"; var _RegistrationTypeTracking: Text)
        var
            UnableToPickQuantity: Decimal;
        begin
            // Handle only this type
            if _RegistrationType <> 'UnableToPick'then
                exit;

            // Reading Header values (not needed in this example)
            // _HeaderFieldValues.Get_Location();                      // Helper functions exists for common names
            // _HeaderFieldValues.GetValue('AnyField');             // Any custom name
            // _HeaderFieldValues.GetValueAsDecimal('AnyField');   // Get a value as decimal

            // Reading context values inherited from Order Lines
            // Calculate suggested quantity that was unable to be picked
            UnableToPickQuantity := _HeaderFieldValues.GetContextValueAsDecimal('Quantity') -           // The remaining quantity to be picked
                                    _HeaderFieldValues.GetContextValueAsDecimal('RegisteredQuantity');  // Subtract the currently registered quantity, not-yet-posted  (if any)


            // Create "Decimal Step" to collect the failed quantity
            _Steps.Create_DecimalStep(10, 'UnableToPickQuantity', false);
            _Steps.Set_header('Unable to pick');
            _Steps.Set_label('Quantity:');
            _Steps.Set_helpLabel('Please input the quantity you were unable to pick');

            _Steps.Set_defaultValue(UnableToPickQuantity);          // Suggest our calculated value as DefaultValue
            _Steps.Set_minValue(0.0000000001);                            // Must be a positive number
            _Steps.Set_eanAi(MobToolbox.GetQuantityGS1Ai());        // Set AI to quantity (310,30,37) so GS1 barcodes scans directly into the step

            // (Create more steps here)
        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.


    Run your function fra Mobile and 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. Image Added


    Code Block
    languagexml
    themeEclipse
    titlePost 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>


    Subscribe to OnPostAdhocRegistrationOnCustomRegistrationType

    • Both Header values and Steps values are available.
    • The values are extracted from the _RequestValues parameter using "GetValue "functions.


        [EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Adhoc Registr.", 'OnPostAdhocRegistrationOnCustomRegistrationType', '', true, true)]
        localprocedure MyOnPostAdhocRegistrationOnCustomRegistrationType(_RegistrationType: Text; var _RequestValues: Record "MOB NS Request Element"; var _CurrentRegistrations: Record "MOB WMS Registration"; var _SuccessMessage: Text; var _RegistrationTypeTracking: Text; var _IsHandled: Boolean)
        begin
            // Handle only this type
            if _RegistrationType <> 'UnableToPick'then
                exit;


            if _IsHandled then
                exit;

            // << Perform your own logic here >>

            _SuccessMessage := StrSubstNo('Document %1 Line %2 failed to pick %3', // Display the collected values
                                                                                _RequestValues.GetValueOrContextValue('OrderBackendId'),    // Order Mo.
                                                                                _RequestValues.GetValueOrContextValue('LineNumber'),        // LineNumber
                                                                                _RequestValues.GetValueAsDecimal('UnableToPickQuantity'));  // The collected value

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


    For illustration, the steps-values are used in the success-messageImage Removed

    Step 5: 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 Accepting the header.

    Solution

    No steps are returned.

    See Step 3.


    "No document handler is available for GetRegistrationConfiguration:XXX/XmlSteps"

    Solution

    No steps are returned.

    See Step 3.


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

    Error occurs when posting.

    Solution

    Posting is not handled.

    See step 4


    Filter by label (Content by label)
    showLabelsfalse
    showSpacefalse
    sorttitle
    titleMore examples
    excerptTypesimple
    cqllabel = "bc" and label = "example" and label = "unplanned"


    Icon

    Pick in Main menu

    Image Removed

    "MyUnplanned" is shown on the main main.Image Added

    Unplanned function Header

    Header fields


    The action on Pick Lines

    Image Added

    Unplanned function Steps

    Image Removed

    First step

    Image Removed

    Second step.

    Image Removed

    3rd and final step.Image Added

    Posting

    Image RemovedImage Added

    Posting completed.
    Message is displayed.