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

ERP 2.50:Developers Guide/How To Create a Manual Window

ERP 2.50:Developers Guide




The objective of this howto is to give you a well documented example of how a manual window is developed and the individual elements of the MVC framework it consists of.

To reach the objective a specific example will be used. The requirement we have is a window with a list of products where we can select multiple ones and then change their Product Category to a new one using a button. In other words, we need to batch set the product category of several products at once.

What the Result Should Be

No window like this exists within the core Openbravo ERP and the automatically generated windows do not support custom processing of multiply selected items. Hence, a manual window needs to be developed to support this process.

Let us start with a screenshot of the final window we will develop:


The specs of this window are:


Advantages of manual windows (and generally of manually developed code) are:


With power and control comes responsibility. Therefore, there are many downsides to manual code that suggest us to avoid manual code at all cost unless really necessary:

Theory of Manual Code

Openbravo ERP framework is based on the MVC (Model-View-Controller) architecture approach. This decouples the three areas of development:

When developing Openbravo ERP code, we should follow this approach which reflects in development of the following files:

Normally, the development is done iteratively in the following sequence:

We suggest you develop the code incrementally, i.e. start with very basic UI (no parameters or processing features yet) and only some of the data operations (usually select) and then incrementally add functionality.

As with any new developments starting with version 2.50 and later, these must be part of a module.

More information on manual code can be found here .

Implementing the Solution

Since this is one of the most complex topics, the solution files are provided to you here. the following files are included:


Before we can deploy the solution given, you probably know by now that any new development starting with version 2.50 and later must be part of a module. Please follow the How to create and package a module section to create a new module.

Bulbgraph.png   This article will assume that you have created such as module accordingly. Moreover, the DB Prefix defined there is HT which is also important for custom messages thrown since their keys will have to be prefixed by it.

Placing the Code

Before the four solution source files can be saved within Openbravo ERP, the module's structure needs to be created. Create the following structure $OPENBRAVO_HOME/modules/org.openbravo.howtos/src/org/openbravo/howtos/ad_forms/.

This structure derives from:

Now, put the four source files inside the $OPENBRAVO_HOME/modules/org.openbravo.howtos/src/org/openbravo/howtos/ad_forms/ folder.

Creating a Form inside the Application Dictionary

Now you need to tell Openbravo ERP about the new form (manual window) so use the Application Dictionary || Form window to enter it:


The Form Class and Mapping tabs get entered automatically as soon as you save the header definition of a Form. However, in order to make sure they follow modularity rules, you MUST doublecheck them and correct them accordingly:



Finaly, do not forget to create a new menu item that points to the newly defined Form.

Creating the Custom Messages

Since hardcoding messages into the Java Servlet is a bad practice which also does not allow for translations on top of it, we use Utility.messageBD() method to retrieve the actual messages (or their translation depending on the user language) from the database.

Of course, they need to be entered there first. Use the Application Dictionary || Messages window to enter the following messages:

You can use the following texts:

For example, entering a message would be:


Now, enter all the other ones too.

Compiling the application

If using Eclipse, recompilation is not necessary if you have the "Build Automatically" option enabled. One only needs to make sure that the modules/org.openbravo.howtos/src folder is added to the Java Build Path of the main openbravo project.

If using the command line compilation, use the ant smartbuild or ant compile.development -Dtab=xxx to compile the application's manual code.

Restart Tomcat.

Solution Explained

Since all source files are too long to be listed here, we have included lots of comments inside the sample code.

Still, here's a quick overview on what to pay special attention to with individual elements.

Model - BatchSetProductCategory_data.xsql

This file is used to describe all data operations required by the controller (select, update, delete or insert). At compile time, this file is read and a class is automatically generated with the static methods that correspond to the ones defined here. By having it in the same package as the controller (see first line , the methods can be directly called from the servlet.

In the future, the DAL (Data Access Layer) should replace the need for this method of performing database operations since it makes the code database dependant (Postgres/Oracle).

See inside of the file for comments on what each individual method does.

View - BatchSetProductCategory.html and BatchSetProductCategory.xml

Openbravo main UI window is structured in the following way:

The editing window (appFrame) is usually divided into 4 main columns in order for the elements such as separators and toolbar to be aligned and another sublevel of 6 for the labels and input boxes to be aligned.


The top of the editing window (3) contains the:


See the following article for more details on the UI Fundamentals:

Controller -

ComboTableData Class

When dropdowns are required on a manual window, ComboTableData class should be used. Here's a quick syntax overview of the constrctor:

public ComboTableData(VariablesSecureApp _vars, ConnectionProvider _conn, String _referenceType, String _name, String _objectReference, String _validation, String _orgList, String _clientList, int _index) throws Exception

To set _orgList and _clientList, we normally use the getContext() methods of the Utility class.

Utility.getContext(this, vars, "#User_Org", "--WINDOW NAME--");

This method lists all organizations the current user has access to

Utility.getContext(this, vars, "#User_Client", "--WINDOW NAME--");

Lists all clients current user has access to.

Because certain extra parameters might need to be taken from the session (such as field values stored for a validation, eg.C_REGION.C_COUNTRY = @TO_COUNTRY@) and the default selected value needs to be set, we need to use the fillSQLParameters method of the Utility class to set these. The constructor of this class looks like this:

public static void fillSQLParameters(ConnectionProvider conn, VariablesSecureApp vars, FieldProvider data, ComboTableData cmb, String window, String actual_value) throws ServletException {

Finally, using the select(false) method of the ComboTableData class, the corresponding HTML is generated that contains all <OPTION /> elements for each item of the listbox and the result is set as the data of the listbox's subreport. For example:


The Result

To test the new manual window, select a few products, the destination product category and hit the Set button:


Completing the Module

Even though the majority of work for a manual window is done by coding the source files, there are a few definitions inside the application dictionary that tell Openbravo ERP exactly of the existence of the sources. These definitions need to be exported from the database to be included with the module.

To export them, use the following command:

ant export.database

Now, the OpenbravoERP/modules/org.openbravo.howtos contains all code required for someone else to install this module and use the new manual window alongside with other developments you might have done as part of that module.

Retrieved from ""

This page has been accessed 30,100 times. This page was last modified on 14 June 2011, at 11:04. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.