Modularity naming rules adjustments

This message is VERY IMPORTANT for all of you developing and maintaining modules. Please read it carefully to adapt your modules to the new rules.

Recently some adjustments in modularity naming rules have been performed in order to prevent possible naming clashes between different modules. These changes have been now applied in pi mercurial repository and they will be released in next Openbravo ERP 2.50MP10 version. Before this, it is recommendable to adapt modules to this adjustments.

Existent modules that do not fit the new rules will raise warning when compiling but they will continue working, anyway it will not be possible to package these modules as obx files till they are fixed.

Below it is listed the complete changes and what is the action to be taken to fix modules in each case.

  • Mapping for WAD code
    • Rule: Mapping for WAD windows contains now the module’s mapping for tabs not in core. As this is automatically generated and shouldn’t be manually edited class and mapping tabs in Windows and Tabs window has been set as non editable.
    • Consequence: When updating to the new core version mappings in modules will be automatically updated to the new rule.
    • Action: Export the module with the new automatically generated mapping.
  • Mapping for manual code.
    • Rule: HTML mapping for all manual objects (forms, searchs, reports and processes) must start now with the module’s package. For example, the mapping for a report in a module with package (org.myCompany.moduleTest) could be /org.myCompany.moduleTesr.reports/MyReport.html.
    • Consequence: Old modules not following this rule will still work, but a warning will be displayed whenever the code is compiled. These modules will not be allowed to be packaged in obx files till they are not fixed.
    • Action: The action to be taken to fix modules is to detect the incorrect mappings (it will be shown as a warning when compiling) and adapt them to the new rule.
  • Column.name value
    • Rule: Name attribute in column must follow now the same rules as Database name (columnname) had. This is, when the column is in the same module as its table, no special rule required; if it is in another module, it must start by EM_ + the module’s db_prefix.
    • Consequence: This rule has been enforced in through database triggers, making not possible to create or modify existent objects if the mapping is not correct. Anyway, old modules not following this rule will still work, but a warning will be displayed whenever the code is compiled. These modules will not be allowed to be packaged in obx files till they are not fixed.
    • Action: Locate columns not following the naming and change it. Note that this will cause a change in the module’s API, because this value is used by DAL to generate the property in Java. Therefore it will be necessary also to change the Java processes accessing the column with DAL.
  • Database indexes and constraints
    • Rule: Indexes and constraints now must start with the module’s db_prefix if they are in the same module as their table. If they are in a different one, the rule is the same as it was (start by EM_ + db_prefix).
    • Consequence. Now when exporting database (if validate.model property is set to true) a warning will be raised if there are indexes or constraints not following the rule. It will not be allowed to package modules in obx files if they do not follow the rule.
    • Action: Rename indexes and constraints to adapt them to the new rule. Note that it is possible to define messages for constraints, in this way it is possible to display a customized message when the constraint is not satisfied. These message have as Search key value the constraint name, therefore it will be necessary to change them if exist.
  • Reference name
    • Rule: In this case a restriction has been removed. Prior to this change, reference name was unique in the whole database, thus it was possible two different module adding two reference with same name and it was not possible to install both in the same instance. Now, reference name is unique per module, so there is no problem with several modules defining the same name for different references.
    • Consequence: Now name cannot be used to identify references. Therefore constructor for TableComboData shouldn’t be used passing as parameter the reference name, but its ID. This constructor has been changed and when passing name the reference is always looked within core but not in other modules.
    • Action: Review module’s manual code to ensure all TableComboData constructors are called using ID when the reference is not in core.

As addition, all default messages used to be displayed when a constraint is not satisfied have been removed from database as they are automatically managed. This means that hundreds of messages have disappear and it is recommended for those of you maintaining a translation to repackage it again without  all of these messages.

Sorry for all inconveniences this might carry.

Advertisements

Single Record UI pattern

Single record UI pattern has been recently added to Openbravo ERP r2.50 development branch (pi). This new pattern allows to define a tab as update only not allowing new record insertions nor deletions. This is useful for some special tabs that show information which the user can edit but not modify or create new records, usually the number of record is fixed or it is created by a process but not directly in the tab. An example for this is the System Information tab, which shows global information for the system, therefore it makes sense to change some of its values but never to create a new record; a different case where this pattern is now used is in the Business Partner > Customer sub tab, when the Business Partner is a customer this tab contains the information related to this customer, records in this tab shouldn’t be directly created because they must be created in the parent one.

To implement this pattern a new concept has been added to the tab definition: UI Pattern. Each tab has a single UI pattern that can be selected among the values in a new drop down list.

Currently there are three patterns:

  • Standard. It is the usual representation that allows creating, modifying and deleting records.
  • Read Only. It only allows to view the information but not to modify it. This pattern is not new in Openbravo ERP, but it has changed the way to define it. Previously there was a boolean value that set the tab to be read only, now that field has been deprecated and it is defined as a pattern in a new drop down list of values.
  • Single Record.Which is the one described in this post.

Update: This feature will be included within Openbravo ERP 2.50 MP3

New document: database model

Currently we are working on the Developers Guide for Openbravo ERP r2.50. Within these efforts, last week we have published the database model documentation. This documentation is automatically generated from the application’s on line help, and consists in the description for all tables in database and their columns. It is structured in Database_Model/Package/Table, so each table is included in its package chapter, the information for the columns in the table is included as sections in the table’s page.

The aim for all this, is not to have a readable document from head to bottom but to have a easily maintainable reference to be linked from any other document in the wiki, our goal is also to improve on line help and thus, enhance in parallel this document.

If you have any comment on this document: what you like/dislike, what would you include or improve, etc. please let me know and we’ll try to add this feedback.

EDITED on 4-7: This document replaces the Openbravo ERP ER published for previous releases.

New build process: keep it simple

(Old) Problems

For Openbravo ERP developers (specially for newcomers) it has always been difficult to decide which of the available build tasks was the best election to build the system after any development they had done. We had to take into account what modifications were done to know which ant task we should run. For example if we had modified a window we would use ant compile -Dtab=myWindow to generate the code just for that window and not for the rest of them.  It was even worse when working with subversion, each time we updated our working copy we had to look which were the files that had been updated to know if it was necessary to run update.database to synchronize Openbravo model database(database schema objects and applicatoin dictionary data) from XML files. And in case there were modifications there it was worth re-generate all the WAD windows because it was difficult to know which ones had been modified. So many times compile.complete was the “safe” but slow choice.

Upadate.database task had two more inconvenients: the first one was that in case Openbravo model was modified locally and not exported (ant export.database), when executing this task we would lose all the changes done in database for application dictionary. This annoying behavior had been reported as a bug. The other inconvenient was that during the r2.50 development cycle, specially because of the usage of DAL as part of the update process, this task was pretty unstable, making people not to be very confident about using it. As result people felt safer by recreating the whole system  (ant install.source) instead of executing a much faster incremental build (ant update.database compile.complete).

New task: smartbuild

For Openbravo ERP r2.50 we have resolved these problems by simplifying the build process with a new incremental build task: smartbuild, which is currently available in trunk (r12753) and will be release in the next alpha (aplha r11). This task performs all the required processes to build your  system but only the required ones, with a huge improvement in performance. It checks whether the database needs to be updated from xml sources and performs the update only if needed, generates the code that needs to be regenerated, compiles and deploys it.

The goal of this smartbuild is to replace most of the rest of tasks, making life a little simpler for developers. So now it is only needed to use two tasks: smartbuild for all the builds and export.database to export database to xml files. export.database is now smart to export only if needed, skipping the process if no changes have happened in the local Openbravo model.

Moreover update.database ensures before updating that no local changes have occured in Openbravo model since the last synchronization (export.database or update.database) to prevent people loosing their changes. In case of changes, people will be required to export their database before updating it.

How it works

  • Determine if database needs to be updated. To do this smartbuild generates a checksum for the xml files and compares it with an existent one. This one is generated each time database is synchronized from xml files or to xml files. If the two checksums are different it means that xml files are different so database is updated.
  • Decide which code needs to be re-generated. Whenever a build process is done a timestamp with the current time is stored in database. This timestamp is compared with the audit info for the application dictionary objects that participate in the code generation so now WAD is able to generate code only for those elements that have been created or modified after the last build. Additionally when exporting database to xml files the audit info is not longer exported and when updating the audit info is recalculated for the current time, thus it also works in case the modifications in application dictionary came from an update.database. There’s only one case when this check doesn’t work: it is when application dictionary elements are modified directly in databse through insert/update SQL statements without updating audit info. In this case the developer will have to generate the code in the old way (using compile -Dtab=modifiedWindows).
  • Check if database has been changed. This check allows to export only if there’re changes in database and prevents data loses when updating database. To check this it is used the same timestamp as in the first point. Modifications in data are calculeted by DAL and modifications in database structure are queried directly to database. The query for database structure last modification has no problem in Oracle becuase User_Objects table stores the last physical change for each database object, but in PostgreSQL that information is not stored in database. This has been solved for PostgreSQL generating a checksum in database from all the elements in database that can be exported to xml files, that’s the reason why in PostgreSQL this check takes longer than in Oracle.

New stuff for Openbravo ERP developers

Recently modularity project has been merged back to Openbravo ERP 2.50 trunk. Apart from the features described within the project, some other useful utilities have been developed, these features are usable from r2.50 by any development. Some of them are:

GenericTree

GenericTree

GenericTree allows to represent an ajax tree for any tree data structure in Openbravo ERP. It draws the user interface for the tree and manages the ajax calls for opening and closing nodes.

GenericTree is an abstract Java class that can be extended by other classes to implement different trees. These subclasses just need to populate a FieldProvider object with the information for the concrete tree. Once this is done in order to show an ajax tree it is only needed to instantiate a subclass.

Let’s see some code:

This is the Java piece of code

ModuleTree tree = new ModuleTree(this);
tree.setLanguage(vars.getLanguage());
//Obtains a tree for the installed modules
xmlDocument.setParameter("moduleTree", tree.toHtml());
//Obtains a box for display the modules descriptions
xmlDocument.setParameter("moduleTreeDescription", tree.descriptionToHtml());

And here is the HTML side


<tr>
<PARAMETER_TMP id="
moduleTree"/> <!-- Prints module tree 4 cols -->
<td/>
<td/>
<tr>

<tr>
<PARAMETER_TMP id="moduleTreeDescription"/> <!-- Prints module tree desc  4 cols -->
<td/>
<td/>
<tr>

In this example ModuleTree class is a GenericTree’s subclass which implements the queries for the tree of modules, creating a new instance of this class and setting the toHTML() in the HTML template will display the User Interface and manage all the ajax requests.

FieldProviderFactory

This class allows to transform any object with setter methods into a FieldProvider object. This is useful to represent this non-FieldProvider object within a structure inside a xmlEngine template.

Here’s the code:


WebServiceImplServiceLocator loc = new WebServiceImplServiceLocator();
WebServiceImpl ws = (WebServiceImpl) loc.getWebService();
Module module = ws.moduleDetail(recordId);
ModuleDependency[] dependencies = module.getDependencies();
xmlDocument.setData("dependencies", FieldProviderFactory.getFieldProviderArray(dependencies));

In this example ModuleDependency is a class that has setter methods, so to use it to fill a HTML template it is possible to convert it into a FieldProvider using FieldProviderFactory class.

AntExecutor

AntExecutor is able to execute any ant task from any build.xml file. It is also possible to set different loggers, for example a file log or an OBPrintStream which can be used to display the generated log in real time.

This is a basic example that just creates a new AntExecutor for a buil.xml file, adds a task and a property and executes the task.


AntExecutor ant=new AntExecutor("/path/to/build.xml");
Vector tasks = new Vector();
tasks.add("apply.modules");
ant.setProperty("module", "test1");
ant.runTask(tasks);

Zip

Zip class zips and unzips files.

It is easy to use:


Zip.zip("/path/to/zip/", "/file/to.zip");
Zip.unzip("/file/to/un.zip", "/path/to/unzip");

New column in Openbravo ERP prone to merge conflicts

Recently I’ve added to AD_Column table in Openbravo ERP database the Position column and I’ve commited it to trunk (r8191). This new column stores the physical database order for the columns which will be required by Data Access Layer Project.

This column is mandatory, so when mergeing trunk to project branches it will cause problems in case these projects add new columns. Here I will try to explain who to deal with these problems:

  • First of all resolve the conflicts as usual in the xml files.
  • If you have created new columns in your project you will not be able to update your database, so before updating let’s put the new column as not mandatory open src-db/database/model/tables/AD_COLUMN.xml file and change the line <column name="POSITION" primaryKey="false" required="true" type="DECIMAL" autoIncrement="false"> to <column name="POSITION" primaryKey="false" required="false" type="DECIMAL" autoIncrement="false">. Now you should be able to update your database.
  • Your database now contains the columns you’ve added to your project with the position value as null, now you have to populate this value to do it execute:

UPDATE AD_COLUMN C
SET POSITION=(SELECT COLUMN_ID FROM USER_TAB_COLUMNS U, AD_TABLE T
WHERE T.AD_TABLE_ID = C.AD_TABLE_ID
AND TABLE_NAME = UPPER(T.TABLENAME)
AND COLUMN_NAME = UPPER(C.COLUMNNAME))
WHERE POSITION IS NULL;

  • Export now your database to xml files.
  • Revert the previous modification in src-db/database/model/tables/AD_COLUMN.xml file.
  • And now you are ready to commit

First modularity merge to trunk

I have merged the first part of modularity project into trunk. This does no add any new functionality, it just contains the new database infrastructure to manage modules which includes a table (AD_Module) to maintain the installed modules in the instance and a reference to this table in many application dictionary tables (you can see the complete list of the affected tables here).

The purpose of this early merge is to try to affect other projects for r2.50 as llittle as possible but, in any case, it would be advisable to synchronize these projects with trunk as soon as possible in order to minimize the risk of conflicts.