Retail:Developers Guide/How-to/Add Mobile Process
How to add new mobile process and subscribe components to it
Contents |
Introduction
Mobile Process is a process in the client side and it's start and finish is defined by the developer. For example, calculateReceipt is a Mobile Process defined in the code which starts when the order is changed. We calculate discounts, gross, taxes... inside the process and when all ticket values are calculated we mark as finished this process.
Process Controller is an API which allow us to define Mobile Processes and subscribe components to these processes.
How it works
First of all, we need to define a Mobile Process in the ERP and then set in the code where the process starts and where finishes. Then, we need to think which components(buttons, popups, labels...) should listen what we defined previously and subscribe it into the process. Finally, we will be able to implement what we want to do when the process starts and what we want to do when the process finishes.
Process Controller, when a process starts (where developer decided) goes through the subscribed components and in order of subscription (FIFO) the API will execute the processStarted code implemented for each component in the list. When the process finishes Process Controller will do the same but executing processFinished function.
Add a Mobile Process and subscribe a component to it
There are several steps than need to be done and pay attention to the notes or suggestions.
Define a Mobile Process in the ERP
As System Administrator go to Mobile Process window and create one:
- Searchkey: The unique name that will be used in the code to refer the process.
- Name: A short clear name to identify the process.
- Description: An explanation of what the process does.
- Scrim type for the process: The scrim type which will be shown during the process execution. By default 'No scrim' is set.
- Process scrim main message: Only available for Loading and Processing scrim type. Define the main message for the scrim.
- Process scrim main message: Only available for Loading scrim type. define a secondary message for the scrim
Set the start/finish of the Process
We need to define where the process starts/finishes.
Defining starting point, we will call var execution = OB.UTIL.ProcessController.start('searchKey') using the searchKey defined previously in Mobile Processes window and we will save it in a variable because its execution has a unique id to differentiate each execution of the same process.
Defining finishing point, we will call OB.UTIL.ProcessController.finish('searchKey', execution); passing the previous saved var to finish that execution.
See below an example of the implementation:
... clearWith: function (_order) { var execution = OB.UTIL.ProcessController.start('clearWith'); // verify that the clearWith is not used for any other purpose than to update and fire the events of the UI receipt OB.UTIL.Debug.execute(function () { var isTheUIReceipt = this.cid === OB.MobileApp.model.receipt.cid; if (!isTheUIReceipt) { OB.error("The target of the clearWith should only be the UI receipt. Use OB.UTIL.clone instead"); } }, this); ... this.unset('idExecution'); } //Enable recalculating service relations after cloning this.unset('preventServicesUpdate'); this.set('isEditable', _order.get('isEditable')); this.trigger('change'); this.trigger('clear'); OB.UTIL.ProcessController.finish('clearWith', execution); }, ...
Process controller scrim behavior
From now on, the way to block the UI in WebPOS is using Process Controller's scrims.
A process controller's scrim is defined within the Process Controller definition itself. The available scrims are:
- No scrim: (By default) The process will not block the UI
- Transparent scrim: The process will block the UI with a transparent scrim on top of WebPOS.
- Opaque scrim: The process will block the UI with an opaque scrim on top of WebPOS.
- Processing scrim: The process will block the UI showing a processing scrim with a message.
- Loading scrim: The process will hide webPOS UI and show a loading scrim with a main message and a secondary message.
At the start of a process, the logic will check if it is necessary to show the scrim (i.e. it is the first process with that scrim type defined) or not.
At the end of a process, the logic will check if the scrim should be hidden (i.e. there is no other processes with the same scrim) or not.
Subscribe a component to the Process
To know when a process starts/finishes we need to subscribe the component to it in order to get that information from Process Controller API.
It is simple, we just need to to subscribe the component inside initComoponents of our button and unsubscribe it in destroyComponents (we need to unsubscribe also because we do not want destroyed components registered). As parameter we will pass an array of the searchKeys of the processes to listen to.
See an example:
processesToListen: ['searchKey1', 'searchKey2'] , initComponents: function () { this.inherited(arguments); OB.UTIL.ProcessController.subscribe(this.processesToListen, this); }, destroyComponents: function () { this.inherited(arguments); OB.UTIL.ProcessController.unSubscribe(this.processesToListen, this); }
![]() | If your component extends from OB.UI.Button or OB.UI.Modal you only need to define processesToListen array |
Implement functions of process start/finish for the component
Finally, we need to implement what we want to do before and after the process. We can disable a button while the process is executing or show 'Loading...' screen or hide a component...
Defined these two functions:
* processStarted: function (process, execution, processesInExec) * processFinished: function (process, execution, processesInExec)
We will receive some information that would help us in our implementation. process is the event that starts/finishes and inside it has lists of components subscribed to it and executions in progress. execution will give us the id of the current execution and finally processesInExec will be a list of processes in execution for this component.
See an example:
processStarted: function (process, execution, processesInExec) { if (processesInExec.models.length === 1 && process.get('executions').models.length === 1) { if (this.disableButton) { this.disableButton(); } } }, processFinished: function (process, execution, processesInExec) { if (processesInExec.models.length === 0) { if (this.enableButton) { this.enableButton(); } } },