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 | ||||
---|---|---|---|---|
| ||||
<!-- Custom -->
<page id="MyUnplanned" type="UnplannedItemRegistration">
<title defaultValue="Titletext"/>
<unplannedItemRegistrationConfiguration type="MyUnplanned" useRegistrationCollector="false">
<header configurationKey="MyHeader" automaticAcceptOnOpen="true"/>
</unplannedItemRegistrationConfiguration>
</page>
<!-- Custom --> |
Add this section to the <menuItems> tag.
Code Block | ||||
---|---|---|---|---|
| ||||
<!-- Custom -->
<menuItem id="MyUnplanned" displayName="MyUnplanned" icon="mainmenusettings" alwaysEnabled="true"/>
<!-- 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 | ||||
---|---|---|---|---|
| ||||
<...>
<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
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Reference Data", 'OnGetReferenceData_OnAddHeaderConfigurations', '', true, true)]
local procedure MynGetReferenceData_OnAddHeaderConfigurations(var _HeaderFields: Record "MOB HeaderField Element")
begin
_HeaderFields.InitConfigurationKey('MyHeader'); // Identifier for new Header - replace by your own name
_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.Description
Excerpt |
---|
Add a new Unplanned Function as action on Pick Lines. |
Use case
This example shows transfers values from an Order Line to a new unplanned function.
This example results in
- One new Unplanned Functions
- One action on "Pick Lines" to this function
- Three Header-fields
- That transfers Location, Bin and Item from the Order line
- A step to collect a decimal value from the user
Using the transferred values when adding the step
We use the transferred values when adding the decimal step:
- The registered (not yet posted) quantity is compared to the full line quantity
- The result is suggested as Default Value in the step
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 | ||||
---|---|---|---|---|
| ||||
<!-- 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 | ||||
---|---|---|---|---|
| ||||
<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 Header-fieldsto 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 Adhoc Registr.", 'OnGetRegistrationConfiguration_OnAddSteps', '', true, true)]
localprocedure CollectFailedQty(_RegistrationType: Text; var _HeaderFieldValues: Record "MOB NS Request Element"; var _Steps: Record "MOB Steps Element"; var _RegistrationTypeTracking: Text)
var
MobToolbox: Codeunit "MOB Toolbox";
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;
If you fail to perform this step, you will receive this error.
Image Added
Step 4: Handle posting
You can now run your function from Mobile.
- Steps has been collected and you press "Accept". Now request is made to "Post" the information ("PostAdhocRegistration")
- In this step you must read the collected values and post them to the database
Code Block | ||||
---|---|---|---|---|
| ||||
<page>
<unplannedItemRegistrationConfiguration type="MyUnplanned" useRegistrationCollector="true">
<..> |
You can use the already collected header fields values for:
Subscribe to this event
OnGetRegistrationConfiguration_OnAddSteps
// Step 3: Define Steps (optional)
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Adhoc Registr.", 'OnGetRegistrationConfiguration_OnAddSteps', '', true, true)]
local procedure MyOnGetRegistrationConfiguration_OnAddSteps(_RegistrationType: Text; var _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;
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 | ||||||
---|---|---|---|---|---|---|
| ||||||
<?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)]
local procedure 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)
var
MyDate: Date;
MyText: Text;
MyDecimal: Decimal;
begin
if _RegistrationType <> 'MyUnplanned' then
exit;
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;
For illustration, the steps-values are used in the success-message
Image Removed
| |||
<?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> |
Note how both Header values and Steps values are available. in the XML.
Subscribe to OnPostAdhocRegistrationOnCustomRegistrationType
- 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 >>
// To illustrate the values are collected in this example, the values are used in the success-message and thus displayed to the user
_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;
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) | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Pick in Main
menuImage Removed
"MyUnplanned" is shown on the main main.menu
Image Added
The action on Pick Lines
Image Added
Step 1 adds the action to Pick lines
Unplanned function Header
Header Step 2 adds header fields
Unplanned function Steps
Image Removed
First step
Image Removed
Second step.
Image Removed
3rd and final step.
Posting
Image Removed
Posting completed.
Message is displayed.Image Added
Step 3 add the steps
Posting
Image Added
Step 4 handles posting and displays message