AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX Blogs
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 09.07.2024, 18:12   #1  
Blog bot is offline
Blog bot
Участник
 
25,584 / 848 (80) +++++++
Регистрация: 28.10.2006
a33ik: WHS Mobile Device Development – Process Guide Framework
Источник: http://daxonline.org/1952-whs-mobile...framework.html
==============

Process Guide Framework - new WHS Mobile Device Process Development.

Extend standard functionality

The following enums should be extended:WHSWorkExecuteMode and WHSWorkCreationProcess for work-related processes or WHSWorkActivityfor indirect.


To automatically enable process guide functionality for new process:
/// /// Class extension for WHSRFMenuItemTable table./// [ExtensionOf(tableStr(WHSRFMenuItemTable))]final class VKWHSRFMenuItemTableTbl_Extension{ /// /// Checks if the work activity is required to use process guide framework. /// /// true if process guide framework must be used; otherwise, false protected boolean workActivityMustUseProcessGuideFramework() { boolean ret = next workActivityMustUseProcessGuideFramework(); // or this.WorkCreationProcess == WHSWorkCreationProcess::NewValue if (!ret && this.WorkActivity == WHSWorkActivity::VKPrintShippingLabel) { ret = true; } return ret; }}

Controller


The main entry point for the process. Controller class linked with the process by WHSWorkExecuteMode attribute and the value it provides. The controller class indicates the initial step class (initialStepNamemethod) and defines the step sequence.
In this case, the process is circular, after successful step execution we again ask for a license place to print another label. In the usual multi-step (multiple screens) guide process case, the second parameter of navigationRoute.addFollowingStep method should identify the next step and there should be several navigationRoute.addFollowingStep calls for each separate step. The last step (last navigationRoute.addFollowingStep call) should reference the first step. For the process to begin from scratch.


/// /// Pring shipping label process guide controller/// [WHSWorkExecuteMode(WHSWorkExecuteMode::VKPrintShippingLabel)]public class VKProcessGuidePrintShippingLabelController extends ProcessGuideController{ protected ProcessGuideStepName initialStepName() { return classStr(VKProcessGuidePrintShippingLabelLPStep); } protected ProcessGuideNavigationRoute initializeNavigationRoute() { ProcessGuideNavigationRoute navigationRoute = new ProcessGuideNavigationRoute(); // In this case, the process is circular, after successful step execution we again ask for a license place to print another label navigationRoute.addFollowingStep(classStr(VKProcessGuidePrintShippingLabelLPStep), classStr(VKProcessGuidePrintShippingLabelLPStep)); return navigationRoute; }}
In case of complex navigation instead of the initializeNavigationRoute method, you can use the navigationAgentFactory method. Please see WHSProcessGuideSortPutawayController as an example:

protected ProcessGuideNavigationAgentAbstractFactory navigationAgentFactory() { return new WHSProcessGuideSortPutawayNavigationAgentFactory(); }

If you experience issues with controller class initialization you can flush the cache using the browser and the following URL (add in front the host):
/?cmp=dat&mi=SysClassRunner&cls=SysFlushAOD
Or from the main menu: System administration / Setup / Refresh elements



Step creation: general information


Each step consists of the PageBuilder class, which defines available controls and the Step class, which is responsible for the logic. Also, the NavigationAgentFactory and NavigationAgent classes might be engaged to indicate the next step (if your step navigation is complex and for example from the current step, you can jump to several different steps depending on the data entered by the user)
  • PageBuilder extends ProcessGuidePageBuilder
    See as an example:
    WHSProcessGuidePopulateLPAndSortPositionPageBuilder
    WHSProcessGuideSortPutawayPromptItemPageBuilder
  • Step extends ProcessGuideStep
    See as an example:
    WHSProcessGuidePopulateLPAndSortPositionStep
    WHSProcessGuideSortPutawayPromptItemStep
  • NavigationAgent extends ProcessGuideNavigationAgent
    See as an example:
    WHSProcessGuideSortPutawayPopulateLPAndSortPositionNavigationAgent
    WHSProcessGuideSortPutawayPromptSortPositionIdNavigationAgent
  • NavigationAgentFactory extends ProcessGuideNavigationAgentAbstractFactory
    See as an example:
    WHSProcessGuideSortPutawayNavigationAgentFactory
Step creation: PageBuilder class


PageBuilder has two main methods:

  • addDataControls() to add fields
  • addActionControls() to add buttons
You can overwrite base addControls methods (which calls those two) and structure the page more thoroughly like for the cases where the lists are used. In the standard example for the WHSProcessGuidePromptWaveLabelSeriesPageBuilder class where buildHeader / buildTableContents / buildPagingControls are used:
protected void addControls(ProcessGuidePage _page) { super(_page); WhsrfPassthrough pass = controller.parmSessionState().parmPass(); WHSRFMenuItemTable menuItemTable = WHSRFMenuItemTable::find(pass.lookup(ProcessGuideDataTypeNames::MenuItem)); this.buildHeader(_page, menuItemTable, this.defaultFilter(pass)); this.buildTableContents(_page, menuItemTable, pass); this.buildPagingControls(_page, menuItemTable); }WHSProcessGuidePromptWaveLabelSeriesStep step class where you can find what item the user is clicked on controller.parmClickedData().
Metadata search: "type:class,method name:buildTableContents"


Our example PageBuilder class content:
/// /// Builder page class for Print shippint label / Container ID step/// [ProcessGuidePageBuilderName(classStr(VKProcessGuidePrintShippingLabelContainerIdPageBuilder))]public class VKProcessGuidePrintShippingLabelContainerIdPageBuilder extends ProcessGuidePageBuilder{ protected WhsrfPassthrough pass; protected void addDataControls(ProcessGuidePage _page) { // to access information in the pass if you need to display something pass = controller.parmSessionState().parmPass(); str successMessage = pass.lookupStr(VKProcessGuideDataTypeNamesPrintShippingLabel::VKSuccessMessage); if (successMessage) { _page.addLabel(VKProcessGuideDataTypeNamesPrintShippingLabel::VKSuccessMessage, successMessage, #WHSRFUndefinedDataType); pass.remove(VKProcessGuideDataTypeNamesPrintShippingLabel::VKSuccessMessage); } _page.addTextBox(ProcessGuideDataTypeNames::ContainerId, "@WAX1422", extendedTypeNum(WHSContainerId)); // Use to identify that process is in detour session if (this.isInDetourSession()) { } } protected void addActionControls(ProcessGuidePage _page) { _page.addButton(step.createAction(ProcessGuideActionNames::ActionOk), true); _page.addButton(step.createAction(ProcessGuideActionNames::ActionCancelExitProcess)); }}
Step creation: Step class



Step class has following main methods:
  • validateControls() - validate input from the user. Here you need to use processingResult.fieldValues as pass (controller.parmSessionState().parmPass()) is not yet updated.
  • isComplete() - idientifies if the step process sucessfully completed. It true - will mark the step as completed (same as this.markAsCompleted() in the step class)
  • doExecute() - main logic execution method. Not each step need to have it. If the step is used only to collect data from the user - you can ommit this method implementation.
  • pageBuilderName() - links step class with page builder
Execution sequence (in case of clicking standard OK button):
  • validateControls()
  • isComplete()
  • doExecute()
However sequence depends where you call super() in your doExecute() method. The sequence above is valid only if the super() call is called first, which you should normally do.
  • ProcessGuideStep.doExecute().processData().validateControls()
  • ProcessGuideStep.doExecute().saveProcessedDataToSessionState() - saves data from processingResult.fieldValues to pass (WhsrfPassthrough: controller.parmSessionState().parmPass())
  • ProcessGuideStep.doExecute().isComplete()
  • ProcessGuideStep.doExecute().markAsCompleted() - if isComplete() = true
Our example Step class content:

/// /// The VKProcessGuidePrintShippingLabelContainerIdStep represents a step that prompts the user for container id information/// [ProcessGuideStepName(classStr(VKProcessGuidePrintShippingLabelContainerIdStep))]public class VKProcessGuidePrintShippingLabelContainerIdStep extends ProcessGuideStep{ WhsrfPassthrough pass; WHSContainerTable containerTable; TMSRouteSegmentContainer routeSegmentContainer; WHSPrinterName printerName; protected boolean isComplete() { pass = controller.parmSessionState().parmPass(); boolean complete = true; if (complete && !containerTable.ShipCarrierTrackingNum) { this.addError("@TRX:NoShippingTrackingNumberFound"); complete = false; } else { routeSegmentContainer = containerTable.findRouteSegmentContainerVK(); } if (complete && !routeSegmentContainer.ContainerShippingLabel) { this.addError("@TRX:NoContainerShippingLabelFound"); complete = false; } if (complete) { printerName = this.identifyPrinterName(); if (!printerName) { this.addError("Unable to identify printer name."); complete = false; } } return complete; } protected void validateControls() { if (controller.parmClickedAction() == ProcessGuideActionNames::ActionOK) { this.validateContainerId(); } } private void validateContainerId() { WHSContainerId containerId = processingResult.fieldValues.lookupStr(ProcessGuideDataTypeNames::ContainerId); containerTable = WHSContainerTable::findByContainerId(containerId); if (!containerTable) { throw error(strFmt("@WAX:WHSProcessGuideScanParametersToPrintContainerLabelStep_ContNotExistError", containerId)); } } protected void doExecute() { super(); if (!processingResult.isErrorState && containerTable && routeSegmentContainer.ContainerShippingLabel) { TMSPrintContainerShippingLabel printShippingContainerLabel = TMSPrintContainerShippingLabel::createInstanceVK(routeSegmentContainer.ContainerShippingLabelType); printShippingContainerLabel.printLabel(printerName, routeSegmentContainer.ContainerShippingLabel); pass.insert(VKProcessGuideDataTypeNamesPrintShippingLabel::VKSuccessMessage, strFmt("@Nexer:ShippingLabelPrinted", containerTable.ContainerId, printerName)); pass.remove(ProcessGuideDataTypeNames::ContainerId); printerName = ''; containerTable.clear(); routeSegmentContainer.clear(); } } protected ProcessGuidePageBuilderName pageBuilderName() { return classStr(VKProcessGuidePrintShippingLabelContainerIdPageBuilder); } /// /// Identifies printer name by mobile device user and warehouse /// /// Printer name protected WHSPrinterName identifyPrinterName() { WHSWorkUserDefaultLabelPrinterTable workUserDefaultLabelPrinterTable; InventLocationId inventLocationId = InventDim::find(containerTable.InventDimId).InventLocationId; if (inventLocationId) { select firstonly RecId, PrinterName from workUserDefaultLabelPrinterTable where workUserDefaultLabelPrinterTable.UserId == pass.parmUserId() &&workUserDefaultLabelPrinterTable.InventLocationId == InventLocationId; } if (!workUserDefaultLabelPrinterTable) { select firstonly RecId, PrinterName from workUserDefaultLabelPrinterTable where workUserDefaultLabelPrinterTable.UserId == pass.parmUserId(); } return workUserDefaultLabelPrinterTable.PrinterName; }}



Helper classes


For convenience, you can create parm methods as an extension to WhsrfPassthrough:
/// /// CoC extension for WhsrfPassthrough class/// WhsrfPassthrough "parm" extensions/// WHSRFPassthrough_Extension - standard/// WhsrfPassthroughProcessGuide_Extension - internal (why?)/// [ExtensionOf(classStr(WhsrfPassthrough))]final class VKWhsrfPassthrough_Extension{ internal WHSContainerId parmContainerIdVK(WHSContainerId _containerId = '') { if (!prmIsDefault(_containerId)) { this.insert(ProcessGuideDataTypeNames::ContainerId, _containerId); } return this.lookupStr(ProcessGuideDataTypeNames::ContainerId); }}Helper methods as an extension to ProcessGuideStep to conveniently add different types of messages:
/// /// CoC for ProcessGuideStep class/// [ExtensionOf(classstr(ProcessGuideStep))]final class VKProcessGuideStepCls_Extension{ public void addError(str _error) { ProcessGuideMessageData processGuideMessageData = ProcessGuideMessageData::construct(); processGuideMessageData.message = _error; processGuideMessageData.level = WHSRFColorText::Error; processingResult.messageData = processGuideMessageData; processingResult.isErrorState = true; } public void addWarning(str _warning) { ProcessGuideMessageData processGuideMessageData = ProcessGuideMessageData::construct(); processGuideMessageData.message = _warning; processGuideMessageData.level = WHSRFColorText::Warning; processingResult.messageData = processGuideMessageData; } public void addMessage(str _message) { ProcessGuideMessageData processGuideMessageData = ProcessGuideMessageData::construct(); processGuideMessageData.message = _message; processGuideMessageData.level = WHSRFColorText::Success; processingResult.messageData = processGuideMessageData; }}Objects

  • ProcessGuideDataTypeNames - contains constants representing logical data type names used for controls (pass names)
  • WhsrfPassthrough - used to store form state during processing RF controls
Additional links







Источник: http://daxonline.org/1952-whs-mobile...framework.html
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
erconsult: Print a custom product label: a Template solution in Process Guide Framework, with detours Blog bot DAX Blogs 0 07.06.2024 15:14
erconsult: Input validation and messaging in the Process Guide Framework Blog bot DAX Blogs 0 06.11.2019 13:11
DynamicsAxSCM: Warehouse Mobile Device Portal Blog bot DAX Blogs 0 23.02.2015 22:12
german_nav_developer: Buildnummern-Übersicht Microsoft Dynamics NAV 2009 SP1 Blog bot Dynamics CRM: Blogs 0 11.06.2010 16:33
german_nav_developer: Buildnummern-Übersicht Microsoft Dynamics NAV 2009 Blog bot Dynamics CRM: Blogs 0 04.06.2010 13:21

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 10:56.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.