Retail:Developers Guide/How-to/Adapt Retail Modules To Work On Top Of Mobile Core
Contents
|
Introduction
With Openbravo MP22 a new module called Mobile Core Infrastructure has been released. This module allows to create mobile applications on top of Openbravo 3.
Because of this new module, Openbravo Web POS published with RMP22 has changed in order to work taking advantage of this base module.
This change has induced some incompatibilities in the modules which extend Openbravo Web POS. This document will help you to address this case and to make your module ready to work with the new versions of Openbravo Web POS.
Summary of main changes
The main thing that has changed is the moment when JS resources are loaded. Using Mobile Core Infrastructure JS resources are loaded (and executed) when the login page is loaded. It means that the code inserted by modules (via Component Provider) is executed in this moment. This is important because in this moment the user is not yet logged into Openbravo and the request to the backend will be denied because of that.
Also the behavior of labels has changed. Now labels are loaded after the JS resources. Because of that is not allowed to get labels in the definition of the components. Find below list of actions we need to do to solve this.
Working with labels
Before explain how to work with Labels, you should know that many labels (messages) have been moved from Web POS (org.openbravo.retail.posterminal) to mobile core module (org.openbravo.mobile.core). It will share this labels along every mobile applications. As you know, the search key of the message is used to get the label. It has changed because the DB Prefix of mobile core (OBMOBC) is different of the web POS (OBPOS).
OBPOS_LblApply -> OBMOBC_LblApply.
Now is the moment to explain the correct way to work with labels. The main reason of these changes is that the components are created before the labels are received from server, so we cannot use OB.I18N.getLabel() in the component definition.
Bellow you can find different scenarios:
Setting the content directly in the component
wrong
enyo.kind({ name: 'GCNV.UI.AcceptMessageButton', kind: 'OB.UI.ModalDialogButton', content: OB.I18N.getLabel('OBPOS_LblOk'), //Wrong classes: 'btnlink btnlink-gray modal-dialog-button', tap: function () { this.doAcceptButton(); } });
correct
enyo.kind({ name: 'GCNV.UI.AcceptMessageButton', kind: 'OB.UI.ModalDialogButton', content: '', //This line could be removed classes: 'btnlink btnlink-gray modal-dialog-button', tap: function () { this.doAcceptButton(); }, initComponents: function () { this.inherited(arguments); this.setContent(OB.I18N.getLabel('OBMOBC_LblOk')); } });
Setting properties of the component using i18nLabel
Major part of the components which defines properties to be set by labels has included a new property called i18nLabel. In this case is easy to solve:
wrong
enyo.kind({ name: 'GCNV.UI.MenuPaidReceipts', kind: 'OB.UI.MenuAction', permission: 'GCNV_PaymentGiftCard', label: OB.I18N.getLabel('GCNV_LblGiftCards') //wrong });
correct
enyo.kind({ name: 'GCNV.UI.MenuPaidReceipts', kind: 'OB.UI.MenuAction', permission: 'GCNV_PaymentGiftCard', i18nLabel: 'GCNV_LblGiftCards' //correct });
Setting properties of the component using initComponents
If the previous case doesen't works, you should overwrite initComponents and set the value for this property there. Remind to call this.inherited(arguments) after set the property.
wrong
enyo.kind({ name: 'GCNV.UI.MenuPaidReceipts', kind: 'OB.UI.MenuAction', permission: 'GCNV_PaymentGiftCard', label: OB.I18N.getLabel('GCNV_LblGiftCards') //wrong });
correct
enyo.kind({ name: 'GCNV.UI.MenuPaidReceipts', kind: 'OB.UI.MenuAction', permission: 'GCNV_PaymentGiftCard', initComponents: function () { this.label = OB.I18N.getLabel('GCNV_LblGiftCards'); //correct this.inherited(arguments); } });
Getting data from backend
Before using mobile core, the modules can inject code to call to backend directly. This is wrong now, because in this moment we are not authenticated.
wrong
OBPOSSV.stockValidationPropertiesProcess = new OB.DS.Process('org.openbravo.retail.stockvalidation.ModulePropertiesServlet'); OBPOSSV.stockValidationPropertiesProcess.exec({}, function(data, message) { OBPOSSV.Settings = OBPOSSV.Settings || {}; OBPOSSV.Settings.negativeStockAllowed = data; window.localStorage.setItem('OBPOSSV.Settings.negativeStockAllowed', data); });
To solve this problem we will use a property loader. It allows us to load data from backend and store it as a terminal property or in desired place.
correct
OB.MobileApp.model.addPropertiesLoader({ properties: ['obpossv_negativeStockAllowed'], loadFunction: function (terminalModel) { var me = this; console.log('loading...', this.properties); OBPOSSV.stockValidationPropertiesProcess = new OB.DS.Process('org.openbravo.retail.stockvalidation.ModulePropertiesServlet'); OBPOSSV.stockValidationPropertiesProcess.exec({}, function (data, message) { terminalModel.set(me.properties[0], data); terminalModel.propertiesReady(me.properties); }); }
Session info and parameters
In general situations, servlets shouldn't receive terminalId, terminal search key, or organization as parameters. These data should be get from session or from context.
wrong
String terminalId = jsonData.getJSONObject("terminal"); String orgId = jsonData.getJSONObject("terminal");
correct
String terminalId = RequestContext.get().getSessionAttribute("POSTerminal").toString(); String orgId = OBContext.getOBContext().getCurrentOrganization().getId();
Adding security in server processes
Mobile core has included some mechanism to guarantee the security in the server side processes.
You should override some methods in your server side components (jsonProcess and ProcessHQLQuery) to avoid security problems.
If the permission to execute some server is connected with one preference, you should override this method. Using it, your class will be executed only if this preference is allowing to do it.
@Override protected String getProperty() { return "OBPOS_retail.layaways"; }
If you servlet doesn't need any special permission to work, you should override this method.
@Override protected boolean bypassPreferenceCheck() { return true; }
Adding items to the Menu
The API to add items to the menu has changed. Now, this code should be executed in order to add items to the menu.
To close the menu when the action is selected, we should call to this.inherited(arguments). It happens because the base object OB.UI.MenuAction do it automatically.
(function () { enyo.kind({ name: 'GCNV.UI.MenuPaidReceipts', kind: 'OB.UI.MenuAction', permission: 'GCNV_PaymentGiftCard', i18nLabel: 'GCNV_LblGiftCards', events: { onShowPopup: '' }, tap: function () { this.inherited(arguments); // auto close the menu this.doShowPopup({ popup: 'GCNV_UI_SearchDialog' }); } }); // Register the menu... OB.OBPOSPointOfSale.UI.LeftToolbarImpl.prototype.menuEntries.push({ kind: 'GCNV.UI.MenuPaidReceipts' }); }());
Adding a new model to be loaded by a window
To add a model to the list of models to be used by a window, just execute this code:
// add the model to the window. OB.OBPOSPointOfSale.Model.PointOfSale.prototype.models.push(OB.Model.GiftCard);
The model will be loaded before load the window.
New popups utility for messages and confirms
This change is not needed but is strongly recommended to use this tool to show messages or confirm dialogs.
Here you can see how works this new tool.
Module versions and dependencies
Because of the significant API change in Openbravo Web POS to support smartphones we released it as a new major version. Modules that depend on Web POS have to
- Be adapted to use new API
- Change the dependency to the new major version of Web POS
- Increase the major version of the module itself.
In this article you can find more information about module“s versions and dependencies.
Example
To explain this concept we will use the module Gift Cards and Vouchers. This module adds gift cards and vouchers functionality to Web POS and has a dependency to it.
The version of this module (before the refactor) was 1.0.500 and it was dependant on 1.1.2600 version of Openbravo Web POS. The dependency enforcement was MAJOR (the default dependency enforcement).
This version of the module could not be installed in an instance which has the RMP22 version of Web POS because the major version of the Web POS in RMP22 has changed. So to make Gift Cards and Vouchers module 'RMP22 ready' Openbravo:
- Updated its logic to work based on the guidelines explained in this document
- Changed the dependency to Web POS (1.2.210) maintaining major enforcement
- Released new major version of the module (1.1.100).