Create elements in the below enums. -> WHSWorkActivity -> WHSWorkExecuteMode --------------------------------------------------------------------------------------------------- Enable Work Activity [ExtensionOf(tableStr(WHSRFMenuItemTable))] public final class CPLDevWHSRFMenuItemTable_Extension { protected boolean workActivityMustUseProcessGuideFramework() { boolean ret = next workActivityMustUseProcessGuideFramework(); if (this.WorkActivity == WHSWorkActivity::CPLProductionStatusChange || this.WorkActivity == WHSWorkActivity::SONEmptyLoc) { ret = true; } return ret; } } ------------------------------------------------------------------------------------------------- Create Required Fields and its control [WHSFieldEDT(extendedTypeStr(Location))] public class CPLDev_WhsFieldCPLLocation extends WHSField { private const WHSFieldName Name = "CPL Location"; private const WHSFieldDisplayPriority Priority = 10; private const WHSFieldDisplayPriority SubPriority = 20; private const WHSFieldInputMode InputMode = WHSFieldInputMode::Manual; private const WHSFieldInputType InputType = WHSFieldInputType::Alpha; protected void initValues() { this.defaultName = Name; this.defaultPriority = Priority; this.defaultSubPriority = SubPriority; this.defaultInputMode = InputMode; this.defaultInputType = InputType; } } ...................................................... [WhsControlFactory('CPLLocation')] Public class CPLDev_WhsControlCPLLocation extends WhsControl { public boolean process() { if (!super()) { return false; } fieldValues.insert(CPLDev_conWHSControls::CPLLocation, this.data); return true; } public boolean canProcessDefaultValue() { if (this.parmData()) { return true; } return false; } protected boolean defaultValueToBlank() { return true; } public void populate() { { fieldValues.insert(this.parmName(), ''); } } } --------------------------------------------------------------------------------------------------- Create Required Controls class CPLDev_conWHSControls { //[pavanKini]- Combining SP Pick RM and Rm capture Packaging details -15-feb-2023 public static const str SalesID = "SalesId"; public static const str CPLLoadID = "CPLLoadId";//added by manju Y //[PavanKini]AGV-Int-WorkPriority changes 09-june-2023 public static const str WorkPriority = "WorkPriority"; public static const str CPLLocation = "CPLLocation"; //added by Manju Y 9/25/2024 } --------------------------------------------------------------------------------------------------- Create Controller class [WHSWorkExecuteMode(WHSWorkExecuteMode::CPLEmptyLocation), WHSWorkExecuteMode(WHSWorkExecuteMode::CPLFilledLocation)] class CPLDev_WHSProcessGuideEmptyLocationDetailsController extends ProcessGuideController { protected ProcessGuideStepName initialStepName() { return classStr(CPLDev_WHSProcessGuidInquiryLocationProfileStep); } protected ProcessGuideNavigationAgentAbstractFactory navigationAgentFactory() { return new CPLDev_InventProcessGuideLocationDetailsNavigationAgentFactory(); } } ------------------------------------------------------------------------------------------------- Create Navigation agent factory or define navigation on the controller class class CPLDev_InventProcessGuideLocationDetailsNavigationAgentFactory extends ProcessGuideNavigationAgentAbstractFactory { #define.LocId('Location Profile Id') public final ProcessGuideNavigationAgent createNavigationAgent(ProcessGuideINavigationAgentCreationParameters _parameters) { ProcessGuideNavigationAgentCreationParameters creationParameters = _parameters as ProcessGuideNavigationAgentCreationParameters; if (!creationParameters) { throw error(Error::wrongUseOfFunction(funcName())); } WhsrfPassthrough pass = creationParameters.controller.parmSessionState().parmPass(); return this.initializeNavigationAgent(creationParameters.stepName, pass); } private ProcessGuideNavigationAgent initializeNavigationAgent(ProcessGuideStepName _currentStep, WhsrfPassthrough _pass) { str menuitemname = _pass.lookupStr(ProcessGuideDataTypeNames::MenuItem); WHSLocProfileId profileId; WHSLoadId loadid ; Location _Location; switch (_currentStep) { case classStr(CPLDev_WHSProcessGuidInquiryLocationProfileStep) : profileId = _pass.lookupStr(#LocId); if(WHSLocationProfile::find(profileId)) return new CPLDev_InventProcessGuideLocDetailsNavigationAgent(); else return new CPLDev_InventProcessGuideLocationProfileNavigationAgent(); case classStr(CPLDev_WHSProcessGuidEmptyLocationDetailsDStep) : _Location=_pass.lookup(ProcessGuideDataTypeNames::LocOrLP); if(_Location) return new CPLDev_WHSProcessGuideSelectedEmptyLocNavigationAgent(); else return new CPLDev_InventProcessGuideLocDetailsNavigationAgent(); break; default : return new CPLDev_InventProcessGuideLocationProfileNavigationAgent(); } } } ------------ class CPLDev_WHSProcessGuideSelectedEmptyLocNavigationAgent extends ProcessGuideNavigationAgent { protected ProcessGuideStepName calculateNextStepName() { return classStr(CPLDev_WHSProcessGuideSelectedEmptyLocStep); } } -------------------------------------------------------------------------------------------------- Create Step and Pagebuilder Step 1. Page Builder---------> [ProcessGuidePageBuilderName(classStr(CPLDev_WHSProcessGuideLocationProfilePageBuilder))] class CPLDev_WHSProcessGuideLocationProfilePageBuilder extends ProcessGuidePageBuilder { public static const str OR = '||'; public static const str WHSLocationProfileID = 'Location Profile Id'; protected final void addDataControls(ProcessGuidePage _page) { WHSLocProfileId profileId; _page.addComboBox( WHSLocationProfileID, "Location profile Id", extendedTypeNum(WHSLocProfileId),this.getLocationProfileID(), true); } protected final void addActionControls(ProcessGuidePage _page) { #ProcessGuideActionNames _page.addButton(step.createAction(#ActionOK), true); _page.addButton(step.createAction(#ActionCancelExitProcess)); } public str getLocationProfileID() { str elements; boolean first = true; WHSLOCATIONPROFILE WHSLOCATIONPROFILE; while select * from WHSLOCATIONPROFILE where WHSLOCATIONPROFILE.CPLDisplayLocation == NoYes::Yes { if (!first) { elements += OR ; } elements += WHSLOCATIONPROFILE.LocProfileId; first = false; } return elements; } } Step calss----------> [ProcessGuideStepName(classStr(CPLDev_WHSProcessGuidInquiryLocationProfileStep))] class CPLDev_WHSProcessGuidInquiryLocationProfileStep extends ProcessGuideStep { protected final ProcessGuidePageBuilderName pageBuilderName() { return classStr(CPLDev_WHSProcessGuideLocationProfilePageBuilder); } } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Step 2. Page Builder--------------> [ProcessGuidePageBuilderName(classStr(CPLDev_WHSProcessGuideEmptyLocDetailsPageBuilder))] class CPLDev_WHSProcessGuideEmptyLocDetailsPageBuilder extends ProcessGuidePageBuilder { #define.LocId('Location Profile Id') protected final void addDataControls(ProcessGuidePage _page) { WhsrfPassthrough pass = controller.parmSessionState().parmPass(); WHSMenuItemName menuitems = pass.lookupStr(ProcessGuideDataTypeNames::MenuItem); WMSLocationId locationID = pass.lookupStr(#LocId); InventLocationId inventLocationId = WHSWorkUserSession::find(pass.lookupstr(ProcessGuideDataTypeNames::UserId)).InventLocationId; _page.addLabel(ProcessGuideDataTypeNames::InventLocation, strFmt("@WAX1112", inventLocationId), extendedTypeNum(WHSRFUndefinedDataType)); if(menuitems == "Empty Locations") { this.BuildEmptyLocation(_page,pass, inventLocationId,locationID); } else { this.BuildFilledLocation(_page,pass, inventLocationId,locationID); } } protected final void addActionControls(ProcessGuidePage _page) { #ProcessGuideActionNames _page.addButton(step.createAction(#ActionOK), true); _page.addButton(step.createAction(#ActionCancelExitProcess)); } private void BuildFilledLocation(ProcessGuidePage _page, WhsrfPassthrough _pass, InventLocationId inventLocationId, WMSLocationId locationID) { WMSLocation WmsLocation; int labelCounter; InventSum inventSum; InventDim inventdim; #ProcessGuideActionNames while select * from WmsLocation where WmsLocation.LocProfileId == locationID { select count(RecId),Sum(Received),Sum(postedQty) ,Sum(DEDUCTED),sum(registered), sum(picked) from inventSum join inventdim where inventSum.InventDimId == inventdim.inventDimId && inventdim.wMSLocationId == WmsLocation.wMSLocationId; { if( (inventSum.PostedQty + inventSum.Received - inventSum.Deducted + inventSum.Registered - inventSum.Picked) > 0) { _page.CPLAddMultiActionButton(step.createAction(#ActionOK),extendedTypeNum(WMSLocationId),WmsLocation.wMSLocationId); //_page.addLabel(int2str(labelCounter), WmsLocation.wMSLocationId , extendedTypeNum(WMSLocationId)); ++labelCounter; } } } } private void BuildEmptyLocation(ProcessGuidePage _page, WhsrfPassthrough _pass, InventLocationId inventLocationId, WMSLocationId locationID) { WMSLocation WmsLocation; int labelCounter; InventSum inventSum; InventDim inventdim; #ProcessGuideActionNames while select * from WmsLocation where WmsLocation.LocProfileId == locationID { select count(RecId),Sum(Received),Sum(postedQty) ,Sum(DEDUCTED),sum(registered), sum(picked) from inventSum join inventdim where inventSum.InventDimId == inventdim.inventDimId && inventdim.wMSLocationId == WmsLocation.wMSLocationId; { if( (inventSum.PostedQty + inventSum.Received - inventSum.Deducted + inventSum.Registered - inventSum.Picked) <= 0) { //_page.addLabel(int2str(labelCounter), WmsLocation.wMSLocationId , extendedTypeNum(WMSLocationId)); _page.CPLAddMultiActionButton(step.createAction(#ActionOK),extendedTypeNum(WMSLocationId),WmsLocation.wMSLocationId); ++labelCounter; } } } } } Step class -----------------> [ProcessGuideStepName(classStr(CPLDev_WHSProcessGuidEmptyLocationDetailsDStep))] class CPLDev_WHSProcessGuidEmptyLocationDetailsDStep extends ProcessGuideStep { protected final ProcessGuidePageBuilderName pageBuilderName() { return classStr(CPLDev_WHSProcessGuideEmptyLocDetailsPageBuilder); } public void doExecute() { #ProcessGuideActionNames str value; ProcessGuidePage pages; value = controller.parmClickedData(); WhsrfPassthrough pass = controller.parmSessionState().parmPass(); pass.insert(ProcessGuideDataTypeNames::LocOrLP,value); super(); } } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Step 3. Page builder ---------------> [ProcessGuidePageBuilderName(classstr(CPLDev_WHSProcessGuideSelectedLocPageBuilder))] class CPLDev_WHSProcessGuideSelectedLocPageBuilder extends ProcessGuidePageBuilder { #ProcessGuideActionNames protected final void addDataControls(ProcessGuidePage _page) { int labelCounter; SalesId salesId; WhsrfPassthrough pass = controller.parmSessionState().parmPass(); str locations= pass.lookup(ProcessGuideDataTypeNames::LocOrLP); if(locations !="" ) { _page.addLabel(ProcessGuideDataTypeNames::RFTitle,"Confirm Selected location",extendedTypeNum(WHSRFTitle)); _page.addTextBox(CPLDev_conWHSControls::CPLLocation,'',extendedTypeNum(Location),false,locations); // _page.addLabel(int2str(labelCounter),locations,extendedTypeNum(SalesId)); labelCounter++; } else { _page.addLabel(ProcessGuideDataTypeNames::Error,"No location selected",extendedTypeNum(WHSRFUndefinedDataType)); } } protected final void addActionControls(ProcessGuidePage _page) { #ProcessGuideActionNames if(this.isInDetourSession()) { _page.addButton(step.createAction(#ActionCancelExitProcess),true,'Confirm'); } else { _page.addButton(step.createAction(#ActionOK), true); _page.addButton(step.createAction(#ActionCancelExitProcess)); } } } Step class ---------------------> [ProcessGuideStepName(classStr(CPLDev_WHSProcessGuideSelectedEmptyLocStep))] class CPLDev_WHSProcessGuideSelectedEmptyLocStep extends ProcessGuideStep { protected final ProcessGuidePageBuilderName pageBuilderName() { return classStr(CPLDev_WHSProcessGuideSelectedLocPageBuilder); } } ------------------------------------------------------------------------------------------------- xml decorator class [WHSWorkExecuteMode(WHSWorkExecuteMode::CPLEmptyLocation), WHSWorkExecuteMode(WHSWorkExecuteMode::CPLFilledLocation)] class CPLDev_WHSMobileAppServiceXMLDecoratorFactoryLocationDetails implements WHSIMobileAppServiceXMLDecoratorFactory { public WHSMobileAppServiceXMLDecorator getDecorator(container _con) { if (this.inputInquiryScreen(_con)) { return new WHSMobileAppServiceXMLDecoratorInquiryInput(); } else if(this.getCurrentStep(_con) == this.emptyLocationSelectedStep()) { return new WHSMobileAppServiceXMLDecoratorInquiryInput(); } return new CPLDev_WHSMobileAppServiceXMLDecoratorLocationDetails(); } private boolean inputInquiryScreen(container _con) { str currentStep = this.getCurrentStep(_con); return (currentStep == this.inputLocationProfileStepName()); } private str getCurrentStep(container _con) { container subCon = conPeek(_con, 2); for (int i = 1; i <= conLen(subCon); i++) { if (conPeek(subCon, i - 1) == "CurrentStep") { return conPeek(subCon, i); } } //Default behavior. return conPeek(subCon, 8); } delegate void inquiryLocationProfileDelegate(EventHandlerResult _result) { } private str inputLocationProfileStepName() { EventHandlerResult result = new EventHandlerResult(); this.inquiryLocationProfileDelegate(result); str inputStep; if (result.result() != null) { inputStep = result.result(); } return inputStep; } delegate void inquiryLocationDetailsDelegate(EventHandlerResult _result) { } private str inputLocationDetails() { EventHandlerResult result = new EventHandlerResult(); this.inquiryLocationDetailsDelegate(result); str inputStep; if (result.result() != null) { inputStep = result.result(); } return inputStep; } private str emptyLocationSelectedStep() { return "CPLDev_WHSProcessGuideSelectedEmptyLocStep"; } } ----------- class CPLDev_WHSMobileAppServiceXMLDecoratorLocationDetails extends WHSMobileAppServiceXMLDecorator { protected void registerRules() { rulesList.addEnd(CPLDev_WHSMobileAppServiceDecoratorRuleInquiryLocationDisplayArea::construct()); } public WHSMobileAppPagePattern requestedPattern() { return WHSMobileAppPagePattern::InquiryWithNavigation; } } ++++++++++++++++++++++++++++++++ Display Area class CPLDev_WHSMobileAppServiceDecoratorRuleInquiryLocationDisplayArea implements WHSIMobileAppServiceXMLDecoratorRule { #WHSRF #WHSWorkExecuteControlElements #XmlDocumentation private const str Footer1 = 'Qty'; private const str Footer2 = 'Inventory status'; private const str newLine = '\n'; private str prevLPLabel; private const ExtendedTypeId LPExtendedType = extendedTypeNum(WHSLicensePlateId); private const ExtendedTypeId LocationExtendedType = extendedTypeNum(WMSLocationId); private const ExtendedTypeId ItemInfoExtendedType = extendedTypeNum(WHSRFItemInformation); private const ExtendedTypeId QuantityInfoExtendedType = extendedTypeNum(WHSRFQuantityInformation); protected void new() { } public static CPLDev_WHSMobileAppServiceDecoratorRuleInquiryLocationDisplayArea construct() { return new CPLDev_WHSMobileAppServiceDecoratorRuleInquiryLocationDisplayArea(); } private boolean mustSetFooters(ExtendedTypeId _controlInputType) { switch (_controlInputType) { case ItemInfoExtendedType: return false;//todo } return false; } private boolean isNewLPHeaderGroup(str _currentLabel) { if (prevLPLabel != _currentLabel) { prevLPLabel = _currentLabel; return true; } return false; } private str getDisplayArea(ExtendedTypeId _controlInputType, str _currentLabel) { switch (_controlInputType) { case LPExtendedType: return WHSMobileAppXMLDisplayArea::BodyArea; break; case LocationExtendedType: return WHSMobileAppXMLDisplayArea::BodyArea;//GroupHeaderArea; case ItemInfoExtendedType, QuantityInfoExtendedType: return WHSMobileAppXMLDisplayArea::BodyArea; default: return WHSMobileAppXMLDisplayArea::SubHeaderArea; } return ''; } public void run(WHSMobileAppPageInfo _pageInfo) { ListEnumerator le = _pageInfo.parmControlsEnumerator(); while (le.moveNext()) { Map controlMap = le.current(); if (this.mustDecorateControl(controlMap)) { this.decorateControl(controlMap); } } } private void decorateControl(Map _controlMap) { ExtendedTypeId controlInputType = _controlMap.lookup(#XMLControlInputType); str currentLabel = _controlMap.lookup(#XMLControlLabel); if(currentLabel !='OK' && currentLabel !='Cancel') { str displayArea = this.getDisplayArea(controlInputType, currentLabel); if (displayArea) { this.setDisplayArea(_controlMap, displayArea); } if (this.mustSetFooters(controlInputType)) { this.setFooters(_controlMap); } } } private boolean mustDecorateControl(Map _controlMap) { //return _controlMap.lookup(#XMLControlCtrlType) == #RFLabel && // !this.newLineControl(_controlMap.lookup(#XMLControlLabel)); return true; } private void setDisplayArea(Map _controlMap, str _displayArea) { //_controlMap.insert(#XMLControlDisplayArea, _displayArea); str currentLabelBuildId = ''; currentLabelBuildId = _controlMap.lookup(#XMLControlName); _controlMap.insert(#XMLControlAttachedTo, currentLabelBuildId); } private void setFooters(Map _controlMap) { _controlMap.insert(#XMLControlFooter1, Footer1); _controlMap.insert(#XMLControlFooter2, Footer2); } private boolean newLineControl(str _controlLabel) { return _controlLabel == newLine; } } ---------------------------------------------------------------------------------------------- Create MobileAppFlow for detour use before that create fields mobile app fields [WHSWorkExecuteMode(WHSWorkExecuteMode::CPLEmptyLocation)] final class CPLDev_WHSMobileAppFlowEmptyLocation extends WHSMobileAppFlow { protected void initValues() { #WHSRF this.addStep('CPLLocation'); this.addAvailableField(extendedTypeNum(Location)); } }