View source | Discuss this page | Page history | Printable version   

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

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:

Retrieved from "http://wiki.openbravo.com/wiki/Retail:Developers_Guide/How-to/Adapt_Retail_Modules_To_Work_On_Top_Of_Mobile_Core"

This page has been accessed 7,870 times. This page was last modified on 19 July 2013, at 10:37. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.