View source | Discuss this page | Page history | Printable version   
Toolbox
Main Page
Upload file
What links here
Recent changes
Help

PDF Books
Show collection (0 pages)
Collections help

Search

Retail:How to create new actions

Contents

Introduction

The new functionality Customizing UI through Touchpoint UI Configuration allows to configure the action buttons that appear in the defined button areas of the POS terminal main window. With this configuration all main actions of the POS terminal can be quickly reachable depending on the terminal type or business requirements.

New actions or existing actions of the POS application can be refactored in order to allow the POS application user to configure where the button that starts the action goes. This way, actions can be executed not only where the developer of the action designs. It can be placed in any of the button areas provided by the application or even hidden if needed.

This new functionality to define actions its not only intended to allow the POS application user to configure where the button that starts the action goes. It also allows the developer to start the action in the required place and share all the code, and definition of the action. To refactor or define new actions you need to be familiar with the Openbravo Modularity_Concepts and with the Openbravo Category:Retail_Developers_Guide.

Dictionary declaration

Sample mobile action declaration
List of available windows


The first step is to add to the dictionary the declaration of the new action. This is done as Openbravo System Administration in the window Mobile Actions. In this window are defined all the available actions. This definition is needed for the UI Configuration windows to allow to select the new action you create and place it in any of the button areas of the application.

To declare a new action fill in the following fields of the header tab:

Then in the child tab you define the Action Component that can be used in the configuration window to start this action and what is the default Action Component. The Action Component is basically the UI element that is used to start the action. The available options are:


Once the action is declared you can export the data to generate the XML source files for your module. To export the data use the same build command used for other dictionary declarations like, tables, windows, messages etc.. Open a terminal window and execute from the root folder of the Openbravo sources the following command:

ant export.database 

To verify the declaration of the action has been properly exported to the dictionary, check the following files in your module folder have been created and contains the data of your action.

src-db/database/sourcedata/OBMOBC_ACTION.xml
src-db/database/sourcedata/OBMOBC_ACTION_CTYPE.xml

Javascript implementation

Action definition, window and name

After the action is declared in the dictionary you can start with the implementation of the action. As explained before, the implementation must be done in the same module the action is declared.

This is the most simple action that can be implemented. This action just displays an alert when clicking on the button that fires it.

 
  OB.MobileApp.actionsRegistry.register(
    new OB.Actions.CommandAction({
      window: 'retail.pointofsale',
      name: 'myNewAction',
      command: function(view) {
        alert('My new action is executed');
      }
    })
  );


The field window is the Search Key of the window Main Web POS and the field name is the Search Key of the Mobile Action. And command() is the function executed.

More fields, permission and properties

Now we have defined a basic action we can add more functionality to the action. Like the permission the logged user must have to be able to execute the action. And in case the user does not have this permission. The Action Button that starts it will be disabled.

 
  OB.MobileApp.actionsRegistry.register(
    new OB.Actions.CommandAction({
      window: 'retail.pointofsale',
      name: 'myNewAction',
      permission: 'OBPOS_print.receipt',
      ...
    })
  );

In the previous example the Action Button that executes myNewAction will be disabled if the user logged in does not have permissions for the preference </code>OBPOS_print.receipt</code> that corresponds to the permission Web POS action Print receipt.

To define the the localized label of the Action Button that fires the action use the field properties. For example:

 
  OB.MobileApp.actionsRegistry.register(
    new OB.Actions.CommandAction({
      window: 'retail.pointofsale',
      name: 'myNewAction',
      properties: {
        i18nContent: 'OBPOS_LblPrintReceipt'
      }
      ...
    })
  );

This defines the localized label OPBPOS_LblPrintReceipt that in English is defined as Print this Receipt.

Implementing the command() function

As you can observe the command function has a parameter named view. This parameter is the instance of the mobile window currently in execution. It is always an enyo kind that inherits OB.UI.WindowView, that in the case of the Main Web POS window is an instance of the enyo kind OB.OBPOSPointOfSale.UI.PointOfSale implemented in the module org.openbravo.retail.posterminal.

Starting from the view parameter you can access the model of the view, functions, etc... to implement your action. You can find different implementations of actions for the Main Web POS window you can use as a model for your action in the following folder of the module org.openbravo.retail.posterminal https://code.openbravo.com/erp/pmods/org.openbravo.retail.posterminal/file/tip/web/org.openbravo.retail.posterminal/js/actions

One important field of the view parameter is state. This field has been created to manage the state of the window and other parameters that has been decided to set at this level for better access when executing actions. From an action command() the following methods of the state field can be invoked:

Except very special cases use always view.state.readcommandstate({state}) because invoking this function will evaluate also the handlers associated to the state.

This is an example of reading the state that defines whether the current receipt is editable or not:

 
const isEditable = view.state.readCommandState({
  name: 'receipt.isEditable'
});

Implementing the isActive() function

Depending on the state of the application it can be defined whether an action can be invoked or not. For example you cannot change the price of a line in a receipt that is already paid, so you want that the Action Button that changes the price to be disabled. To do this all you have to do is to implement the isActive() in your action and return true or false depending on the states of the application.

Because whether the action is active or not depends on the state of the application the isActive() is invoked every time any state changes. This function is also synchronous so in the case you need to do any asynchronous call for example to do a remote request you must declare a new application state. Invoke the asynchronous request outside the isActive code and change the new state value when you get the response.

This is a simple example of the isActive() action function that declares the action as active if and only if the receipt is editable:

 
isActive: function(view) {
  return view.state.readCommandState({
    name: 'receipt.isEditable'
  });
}

Defined states

Module org.openbravo.retail.posterminal

There are already a list of states defined by default in the module org.openbravo.retail.posterminal for the Main Web POS window that are linked to the current receipt attributes:

One other linked with the current view attributes:

And other with the current user selection:

Module org.openbravo.mobile.core

There is one state defined in the module org.openbravo.mobile.core

This state is linked to the user input. This state is used for example in actions to change the price, change the quantity or to scan a barcode.

States

States are very important in actions because are used as the main parameters for actions as they are very easy to access from view.state in the functions command() and isactive() and because every time any of the defined states is modified, the status active / inactive of all actions is reevaluated.

Declare an state as an attribute of a Backbone object

This is the easiest way to define a new state as the state it is automatically changed when the Backbone attribute is changed. This is an example to link the isEditable attribute of the receipt Backbone model.

 
OB.MobileApp.statesRegistry.register(
  new OB.State.BackboneProperty({
    window: 'retail.pointofsale',
    name: 'receipt.isEditable',
    object: function(view) {
      return view.model.get('order');
    },
    property: 'isEditable'
  })
);

Managing states from an enyo object

You can always read the state, write a new state value and subscribe to the changes of an state from an enyo object using the enyo events defined in the mobile view onReadState, onWriteState and onSubscribeAction. This enyo object must hang from a mobile view to properly handle the event for example to read an state value:

 
enyo.kind({
  name: 'OB.UI.MyEnyoKind',
  events: {
    onReadState: ''
  },
  myMethodThatReadsState: function () {
    const stateevent = {
      name: 'myStateName'
    };
    this.doReadState(stateevent);
    if (stateevent.value...) {
      ...
    }
  }
});

You can also write the value of an state this way:

 
enyo.kind({
  name: 'OB.UI.MyEnyoKind',
  events: {
    onWriteState: ''
  },
  myMethodThatChangesState: function () {
    this.doWriteState({
      name: 'myStateName',
      value: 'myStateValue'
    });
  }
});

And to subscribe to the changes of an state value. Note that you can subscribe to one or more states just adding more states names to the names array.

 
enyo.kind({
  name: 'OB.UI.MyEnyoKind',
  events: {
    onSubscribeAction: ''
  },
  initComponents: function() {
    this.doSubscribeAction({
      names: ['myStateName']
    });
  },
  actionNotify: function(view) {
    const value = view.state.readState({
      name: 'myStateName'
    });
  }
});

Calling an action

Actions can be used not only to be executed from buttons configured, but also can be executed directly from javascript. The case can be of one action that has to go in the menu but you want also offer the user that configures the application to call the action from one of the action button areas defined in the application. The Action Components can be used as plain enyo objects from any place you want. For example to add a new menu entry that invokes an action use the enyo kind OB.UI.ActionMenuAction

.
  OB.OBPOSPointOfSale.UI.LeftToolbarImpl.prototype.menuEntries.push({
    kind: 'OB.UI.ActionMenuAction',
    action: {
      window: 'retail.pointofsale',
      name: 'verifiedReturn'
    }
  });

Or if you want to execute the action from any other place of the application using a regular button use the enyo kind OB.UI.ActionButton. In the following example you can see how to create an Action Button component that calls the action verifiedReturn that is created inside another enyo component:

 
enyo.kind({
  name: 'OB.UI.MyActionsContainer',
  components: [
    {
      kind: 'OB.UI.ActionButton',
      name: 'verifiedReturn',
      classes: 'btnlink btnlink-small',
      action: {
        window: 'retail.pointofsale',
        name: 'verifiedReturn'
      }
    }
  ]
});

You can also invoke actions without using any of the Action Components already defined. Using the actions registry you can access all actions registered, check whether is active or inactive and execute it. Remember that you can only execute actions if the application is located in the same window of the registered action, otherwise an exception will be raised. As an example, the following code checks first if the verifiedReturn action is active and then executes it.

 
const actioncommand = OB.MobileApp.actionsRegistry.getActionCommand({
  window: 'retail.pointofsale',
  name: 'verifiedReturn'
});
if (actioncommand.canExecute()) {
  const result = actioncommand.execute();
} else {
  ...
}

Or you can also directly execute the action if you are already sure is active:

 
OB.MobileApp.actionsRegistry.execute({
  window: 'retail.pointofsale',
  name: 'verifiedReturn'
});

Retrieved from "http://wiki.openbravo.com/wiki/Retail:How_to_create_new_actions"

This page has been accessed 478 times. This page was last modified on 9 July 2019, at 07:46. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.