Description
Online Validation on Steps can instantly validate the user data, with a call to BC.
Use cases
- Tell the user instantly whether an input value is correct
- Return more additional steps
- Return value(s) to other existing steps
See also
- Built-in validation options: Standard Online Validation
- More background information: Online Validation
Overview
Tip
- Use Mobile Doc. Queue to inspect the request XML available for validation
Example 1: Online Validation on Package Number during Picking
Requirement
Android app v.1.9.1
In this example, two existing steps (FromBin and Quantity) are updated, when the user enters a Package Number on the order line.
- Before you continue, you must Enable the Mobile WMS standard implementation for Package Numbers
Step 1: Enable Online Validation
- Since Package Number is an additional step, as opposed to the Standard Workflow, we an simply catch it and modify it.
- Setting Onlinevalidation to use a document type named "PackageNumberValidation".
Step 2: Create new DocumentType
- "PackageNumberValidation" needs to be added and point the codeunit that handles online validation.
Step 3: Write your validation code
- In this example two steps are being updated, when the user enters a Package Number on the order line.
Example 2: Online Validation on Receiving or Picking
In this example we will add all the available online validations to the Receive or Pick function. But you can do this for other Planned functions i.e. Put-away, Ship, Move, Count, Assembly or Production.
Step 1: Enable Online Validation
Receive: Add <validation> to Receive Service.
<service id="Receive" type="Order" orderType="Receive"> <requests> <..> </requests> <validation> <lotNumberValidation online="true" documentName="ValidateMyLotNumber" includeCollectedValues="true"/> <serialNumberValidation online="true" documentName="ValidateMySerial" validationLevel="Item" includeCollectedValues="true"/> <toBinValidation online="true" documentName="ValidateMyToBin" includeCollectedValues="true"/> <quantityValidation online="true" documentName="ValidateMyQuantity" includeCollectedValues="true"/> </validation> </service>
or Pick: Add <validation> to Pick Service:
<service id="Pick" type="Order" orderType="Pick"> <requests> <..> </requests> <validation> <lotNumberValidation online="true" documentName="ValidateMyLotNumber" includeCollectedValues="true"/> <serialNumberValidation online="true" documentName="ValidateMySerial" validationLevel="Item" includeCollectedValues="true"/> <fromBinValidation online="true" documentName="ValidateMyFromBin" includeCollectedValues="true"/> <toteValidation online="true" documentName="ValidateMyTote" includeCollectedValues="true"/> <quantityValidation online="true" documentName="ValidateMyQuantity" includeCollectedValues="true"/> </validation> </service>
See Mobile Configuration Files for how to edit application.cfg and training on https://university.taskletfactory.com/
Step 2: Add "Mobile Document Type" and add it to "Mobile Group"
The system needs to know which codeunit will process the validations. You could set up this manually using "Mobile Document Types".
But you should use OnAfterCreateDefaultDocumentTypes event
// Add Mobile Document Types
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Setup Doc. Types", 'OnAfterCreateDefaultDocumentTypes', '', true, true)]
local procedure My01OnAfterCreateDefaultDocumentTypes()
var
MobWmsSetupDocTypes: Codeunit "MOB WMS Setup Doc. Types";
begin
// Create and name document types
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyLotNumber', '', Codeunit::"MOB WMS Whse. Inquiry");
MobWmsSetupDocTypes.CreateDocumentType('ValidateMySerial', '', Codeunit::"MOB WMS Whse. Inquiry");
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyToBin', '', Codeunit::"MOB WMS Whse. Inquiry");
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyFromBin', '', Codeunit::"MOB WMS Whse. Inquiry");
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyTote', '', Codeunit::"MOB WMS Whse. Inquiry");
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyQuantity', '', Codeunit::"MOB WMS Whse. Inquiry");
end;
Failing to do so will result in the following error:
Step 3: Write your validation code
Using OnWhseInquiryOnCustomDocumentType
// Write validation code
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Whse. Inquiry", 'OnWhseInquiryOnCustomDocumentType', '', true, true)]
local procedure My01OnWhseInquiryOnCustomDocumentType(_DocumentType: Text; var _RequestValues: Record "MOB NS Request Element"; var _ResponseElement: Record "MOB NS Resp Element"; var _RegistrationTypeTracking: Text; var _IsHandled: Boolean)
begin
if _IsHandled then
exit;
// Using ERROR() is the correct way to fail the validation, otherwise the validation was OK
case _DocumentType of
// These examples displays misc. request values for illustration purposes
'ValidateMyLotNumber':
Error('OrderNo: %1\ LineNo: %2\ LineItem: %3\ LotStep: %4\ ExpDateStep: %5',
_RequestValues.Get_OrderBackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(), // Currently Not Supported by Android App 1.8.0.1
_RequestValues.Get_LotNumber(),
_RequestValues.Get_ExpirationDate()); // ExpirationDate-step will not trigger validation itself. But it is included when Lot-step is validated
'ValidateMySerial':
Error('OrderNo: %1\ LineNo:%2\ LineItem: %3\ SerialStep: %4',
_RequestValues.Get_BackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(),
_RequestValues.Get_SerialNumber());
// Note: ToBin validation on receive must typically be enabled using "OnGetReceiveOrderLines_OnAfterSetFrom.." events
'ValidateMyToBin':
Error('OrderNo: %1\ LineNo:%2\ LineItem: %3\ BinStep: %4',
_RequestValues.Get_OrderBackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(),
_RequestValues.Get_Bin());
'ValidateMyFromBin':
Error('OrderNo: %1\ LineNo:%2\ LineItem: %3\ BinStep: %4',
_RequestValues.Get_OrderBackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(),
_RequestValues.Get_Bin());
// Note: Tote is typically only used on Picking
'ValidateMyTote':
Error('OrderNo: %1\ LineNo: %2\ LineItem: %3\ ToteStep: %4',
_RequestValues.Get_OrderBackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(), // Currently Not Supported by Android App 1.8.0.1
_RequestValues.Get_ToteID());
'ValidateMyQuantity':
Error('OrderNo: %1\ LineNo: %2\ LineItem: %3\ QuantityStep: %4',
_RequestValues.Get_OrderBackendID(),
_RequestValues.Get_LineNumber(),
_RequestValues.Get_ItemNumber(),
_RequestValues.Get_Quantity());
end;
// Validation was OK
_IsHandled := true;
end;
Viewing the result
Mobile will display a message to the mobile user that online validation has failed, including the error message.
Example 3: Online Validation on Custom Workflow
In this example we will add onlinevalidation on a custom Planned functions /wiki/spaces/SD/pages/78939861
Step 1: Define Line Step(s)
Define a new Workflow step in application.cfg
<..> <workflow> <configuration> <steps> <..leave existing steps here..> <text id="1" name="MyTextStep" header="Scan text" helpLabel="Please scan" autoForwardAfterScan="true" eanAi="00" optional="false" primaryInputMethod="Scan"> <onlineValidation online="true" documentName="ValidateMyCustomWorkflowStep" includeCollectedValues="true"/> </text>
Step 2: Create new DocumentType
See example one for details.
// Add Mobile DocumentType to handle validation code
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Setup Doc. Types", 'OnAfterCreateDefaultDocumentTypes', '', true, true)]
local procedure My02OnAfterCreateDefaultDocumentTypes()
var
MobWmsSetupDocTypes: Codeunit "MOB WMS Setup Doc. Types";
begin
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyWorkflowStep', '', Codeunit::"MOB WMS Whse. Inquiry");
end;
Step 3: Write your validation code
Using OnWhseInquiryOnCustomDocumentType
// Implement DocumentType
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Whse. Inquiry", 'OnWhseInquiryOnCustomDocumentType', '', true, true)]
local procedure My02OnWhseInquiryOnCustomDocumentType(_DocumentType: Text; var _RequestValues: Record "MOB NS Request Element"; var _ResponseElement: Record "MOB NS Resp Element"; var _RegistrationTypeTracking: Text; var _IsHandled: Boolean)
begin
if _IsHandled then
exit;
if _DocumentType = 'ValidateMyWorkflowStep' then
Error('MyTextStep: %1\ OrderNo: %2\ LineNo: %3',
_RequestValues.GetValue('MyTextStep'),
_RequestValues.Get_BackendID(),
_RequestValues.Get_LineNumber());
_IsHandled := true;
end;
Example 4: Online Validation on Custom Line Step
In this example, we will add online validation to a Line step we ourselves have added to an existing Planned Functions e.g. Receive, Pick, Put-away etc.
Step 1: Define Line Step(s)
Using OnGetReferenceData_OnAddRegistrationCollectorConfigurations
// Define step
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Reference Data", 'OnGetReferenceData_OnAddRegistrationCollectorConfigurations', '', true, true)]
local procedure My03OnGetReferenceData_OnAddRegistrationCollectorConfigurations(var _Steps: Record "MOB Steps Element")
begin
// Define a key to hold the step
_Steps.InitConfigurationKey('MyPickStep');
// Define a text step
_Steps.Create_TextStep(10, 'MyTextStep');
_Steps.Set_header('Header text');
_Steps.Set_label('Label text');
_Steps.Set_helpLabel('Help text');
// Enabled Online Validation and setting a DocumentType
_Steps.Set_onlineValidation('ValidateMyPickStep', true);
end;
Step 2: Add steps to Pick-function
Using OnGetPickOrderLines_OnAddStepsToAnyLine
// Add steps Pick Lines
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Pick", 'OnGetPickOrderLines_OnAddStepsToAnyLine', '', true, true)]
local procedure My03OnGetPickOrderLines_OnAddStepsToAnyLine(_RecRef: RecordRef; var _BaseOrderLineElement: Record "MOB NS BaseDataModel Element")
begin
_BaseOrderLineElement.Create_StepsByReferenceDataKey('MyPickStep', true);
end;
Step 3: Create new DocumentType
// Add Mobile DocumentType to handle validation code
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Setup Doc. Types", 'OnAfterCreateDefaultDocumentTypes', '', true, true)]
local procedure My03OnAfterCreateDefaultDocumentTypes()
var
MobWmsSetupDocTypes: Codeunit "MOB WMS Setup Doc. Types";
begin
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyPickStep', '', Codeunit::"MOB WMS Whse. Inquiry");
end;
Step 4: Write your validation code
// Implement DocumentType
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Whse. Inquiry", 'OnWhseInquiryOnCustomDocumentType', '', true, true)]
local procedure My03OnWhseInquiryOnCustomDocumentType(_DocumentType: Text; var _RequestValues: Record "MOB NS Request Element"; var _ResponseElement: Record "MOB NS Resp Element"; var _RegistrationTypeTracking: Text; var _IsHandled: Boolean)
begin
if _IsHandled then
exit;
if _DocumentType = 'ValidateMyPickStep' then
Error('MyTextStep: %1\ OrderNo: %2\ LineNo: %3',
_RequestValues.GetValue('MyTextStep'),
_RequestValues.Get_BackendID(),
_RequestValues.Get_LineNumber());
_IsHandled := true;
end;
Example 5: Online Validation with confirm-dialog on receive quantity step
Requirement
Android app version 1.5.11.1
In this example we will add onlinevalidation to the standard Quantity Line step and ask the user to confirm if the quantity exceeds the expected.
See also: How-to: Add Line Step
This is how the process looks from mobile
Step 1: Enable Online Validation
Add <validation> tag to Receive:
<service id="Receive" type="Order" orderType="Receive"> <requests> <..> </requests> <validation> <quantityValidation online="true" documentName="ValidateMyQuantity" includeCollectedValues="true"/> </validation> </service>
See Mobile Configuration Files for how to edit application.cfg and training on https://university.taskletfactory.com/
Step 2: Turn off OverDeliveryValidation
To allow for greater quantity than expected. See more Register unexpected Quantity (overDeliveryValidation / underDeliveryValidation)
Using OnGetReceiveOrderLines_OnAfterSetFromAnyLine
// Turn off OverDeliveryValidation warning
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Receive", 'OnGetReceiveOrderLines_OnAfterSetFromAnyLine', '', true, true)]
local procedure My04OnGetReceiveOrderLines_OnAfterSetFromAnyLine(_RecRef: RecordRef; var _BaseOrderLineElement: Record "MOB NS BaseDataModel Element")
begin
_BaseOrderLineElement.Set_OverDeliveryValidation('None');
end;
Step 3: Create new DocumentType
// Add Mobile Document Types
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Setup Doc. Types", 'OnAfterCreateDefaultDocumentTypes', '', true, true)]
local procedure My04OnAfterCreateDefaultDocumentTypes()
var
MobWmsSetupDocTypes: Codeunit "MOB WMS Setup Doc. Types";
begin
// Create and name relevant validation document
MobWmsSetupDocTypes.CreateDocumentType('ValidateMyQuantity', '', Codeunit::"MOB WMS Whse. Inquiry");
end;
Step 4: Write your validation code
// Implement DocumentType
[EventSubscriber(ObjectType::Codeunit, Codeunit::"MOB WMS Whse. Inquiry", 'OnWhseInquiryOnCustomDocumentType', '', true, true)]
local procedure My04OnWhseInquiryOnCustomDocumentType(_DocumentType: Text; var _RequestValues: Record "MOB NS Request Element"; var _ResponseElement: Record "MOB NS Resp Element"; var _RegistrationTypeTracking: Text; var _IsHandled: Boolean)
var
WarehouseReceiptLine: Record "Warehouse Receipt Line";
PerformValidation: Boolean;
begin
if _IsHandled then
exit;
if _DocumentType <> 'ValidateMyQuantity' then // DocumentType is derived from <validation> node in application.cfg
exit;
// This code is only for Receive-service. Could be Pick, PutAway, Ship, Move etc.
if _RequestValues.Get_OrderType() <> 'Receive' then // Ordertype is derived from <Service> node in application.cfg
exit;
// "Force" is only present when a dialog was Confirmed OK by user
PerformValidation := (not _RequestValues.Get_Force()) and
// Get source document line being registered
WarehouseReceiptLine.Get(_RequestValues.Get_OrderBackendID(), _RequestValues.Get_LineNumber());
if PerformValidation then
if _RequestValues.Get_Quantity() > WarehouseReceiptLine."Qty. Outstanding (Base)" then
// "ForceWarning:" will trigger the confirm dialog
Error('ForceWarning:%1 is more than %2.\\Is this correct?', _RequestValues.Get_Quantity(), WarehouseReceiptLine."Qty. Outstanding (Base)");
_IsHandled := true;
end;