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

How to create a Module that Adds an Accounting Process


About this document

This document is part of the Localization Guide for Openbravo and describes the steps to create a module that extends the default accounting process, allowing to automatically run any code just after the document posting.

Take into account that the objective of this module is not to change the accounting entries generated by Openbravo, but to run any additional process at posting time. Please read the How to create a Module that Overrides Accounting behaviour in case you are interested in that functionality.

Recommended articles

Before reading this howto it is important to have a clear understanding about the Modularity Concepts, specially the process of  creating and packing modules.

During the development of this module it will be necessary to create a dataset that includes our accounting post-process configuration. In case you haven't created yet a  dataset, it is recommended to firstly read the How to create a Dataset article to get a general idea before moving forward.

From the functional side there is no special requirement for development this module. It is just recommended to understand the role of Accounting Schemas in the general accounting configuration for Openbravo.

The process that will be automatically launched when posting documents must be implemented using Java, so a good knowledge about this programming language is mandatory.

Finally it is highly recommended to use Eclipse IDE for developing this module. Please refer to the How to setup Eclipse IDE article if you haven't done it yet.

Estimated effort

The Openbravo accounting engine provides an infrastructure that easily allows the implementation of processes to be run just after the usual posting logic. The effort for developing this kind of modules highly depends on the complexity required for implementing the concrete code for that process.

As we will see later on, the strictly required effort from Openbravo's side (i.e. module definition, dataset, packaging, distributing, etc.) is quite simple and only requires a few hours for an average developer. So to calculate the global effort you just need to take into account the time is going to take the development of the Java code and add a few hours.


Flexibility and extensibility are two important features of the Openbravo. An example of them is the ability to run processes just after the posting logic for any document has been successfully completed. These kind of processes are called Accounting Post-Processes because they are executed after the normal accounting process.

From a development point of view, this feature gives us the possibility to fulfill any possible requirement specific for our country, like for example to keep an up-to-date log of the documents that have been posted, create some kind of official reports each time a document is posted, send data to a webservice, etc.

Notice that, depending on your country's requirements, these Accounting Post-Processes may not be necessary for you. This kind of modules are not part of the core for a localization, like translations, chart of accounts or taxes, and must be included into a localization pack just in case they are really needed.

Creating the module definition

Each time we plan to develop a new module, the first step must always be to create the module's definition and to register it in the Central Repository.

These are the special considerations for our module:

Now you should export the database to generate the file structure inside the module folder

ant export.database

Finally, inside the modules/<accounting post-process java package> directory create the src folder, where we will store the Java class that implements our accounting post-process code.

LocGuide acctProcess 20.png

Setting up Eclipse

In case you are using Eclipse, you must now add the modules' src directory in the Openbravo project Build path. Right click on the openbravo project and select Build Path > Configure Build Path

LocGuide Remittance 50.png

Now, inside the Source tab, press Add Folder... button and select your module src directory.

LocGuide acctProcess 30.png

In case the src directory is not shown, you may first need to refresh the openbravo project in Eclipse.

Creating the Accounting Post-Process Configuration

The Java class that implements the Accounting Post-Process logic is defined at the Accounting Process window. The definition is quite simple and only requires a name and the Java class name, which must be obviously inside the java package of our module.

LocGuide acctProcess 40.png

This Accounting Post-Process will be later on associated with an Accounting Schema. So in this step is important to define as many Java classes as Accounting Post-Processes we want to include in our module, although it is usually recommended to include just one process per module to keep the general rule of isolating feature in separate modules.

Dataset definition

Dataset definition is a key step in this process. A wrong dataset definition can waste all our previous work, so it is important to follow all these considerations:

LocGuide acctProcess 50.png

The dataset definition is ready, so we just need to export it to a file pressing the Export Reference Data button. This process queries the previous tables and gets all the records that fulfill the HQL/SQL Where clause, generating a XML file inside the module's referencedata/standard directory. As a fast check, you can open this file using any plain text editor and you can verify that it contains several lines.

In case the file is empty, you should double check the dataset definition, specially the HQL/SQL Where clause used for each table.

Testing the Dataset

The real test to ensure the taxes dataset is OK can be done inside our development instance. The test consists on creating a new client running the Initial Client Setup and select our new dummy accounting post-process dataset.

LocGuide acctProcess 60.png

If the data inside the dataset are consistent, the Initial Client Setup Process should be completed successfully, otherwise it will fail giving a description about the error.

After a successful Initial Client Setup, we just need to login into the new client, go to the Accounting Process window and check our record is there.

Implementing the post-process logic

Up to now we have just created the module definition and the required configuration that is included in a dataset. It is time now to develop the logic for our accounting post-process.

Dummy accounting post-process example

As an example for this article, we are going to develop a dummy accounting post-process that consists on creating a log inside a CSV file with data related to the posted document.

This CSV file, which will be saved in the attachments directory, will have the following structure:

posting date, accounting Schema name, document type, document no


"28-06-2012","My Accounting Schema","API","1000001"
"29-06-2012","My Accounting Schema","API","1000002"

Creating the Java Package

Inside the Creating the Accounting Post-Process Configuration chapter we set org.openbravo.localizationguide.dummyAccountingPostProcess.DummyProcess as the Java Class Name that will implement our new post-process.

Let's first create the org.openbravo.localizationguide.dummyAccountingPostProcess package inside our module src directory. If you are using Eclipse you can easily create (Ctrl-N) the new package inside the modules/<your module>/src folder

LocGuide acctProcess 70.png

Creating the Java Class

Inside this package, we must now create the Java Class where we are going to develop our process. This class, that in our example is called DummyProcess, must implement the org.openbravo.erpCommon.ad_forms.AcctProcessTemplate public interface:

LocGuide acctProcess 80.png

Implementing the AcctProcessTemplate interface implies we must override the execute() method.

package org.openbravo.localizationguide.dummyAccountingPostProcess;
import java.sql.Connection;
import javax.servlet.ServletException;
import org.openbravo.base.secureApp.VariablesSecureApp;
import org.openbravo.database.ConnectionProvider;
import org.openbravo.erpCommon.ad_forms.AcctProcessTemplate;
import org.openbravo.erpCommon.ad_forms.AcctSchema;
import org.openbravo.erpCommon.ad_forms.AcctServer;
public class DummyProcess implements AcctProcessTemplate {
  public boolean execute(AcctServer acctServer, AcctSchema as,
                         ConnectionProvider conn, Connection con, VariablesSecureApp vars) throws ServletException {

The most important parameter of this method is the acctServer object, which contains all the information related to the document we are posting. We can access to any of its public attributes or methods as usual, example: acctServer.documentNo, acctServer.DateDoc, etc.

The execute() method returns a boolean, representing whether the method execution has been completed successfully or not. In case of returning false, no accounting entries will be generated.

It is important to understand that the global posting logic is an atomic process; i.e. if something goes wrong in any of the steps of the accounting logic (from pressing the Post button, or alternatively when the accounting background process starts, to the end of the last accounting post-process execution), an automatic rollback will be run, which means no accounting entries will be inserted.

So please spend enough time to ensure your accounting post-process is bug free, otherwise the whole accounting process will fail.

Going back to the dummy example, let's see now how the implementation looks like:

public class DummyProcess implements AcctProcessTemplate {
  private static final String LOG_FILE = "myLogFile.txt";
  private static final String SEPARATOR = ",";
  private static final DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
  public boolean execute(AcctServer acctServer, AcctSchema as,
                         ConnectionProvider conn, Connection con, VariablesSecureApp vars) throws ServletException {
    String today = dateFormat.format(new Date());
    String acctSchemaName = as.m_Name;
    String documentType = acctServer.DocumentType;
    String documentNo = acctServer.DocumentNo;
    return appendToCSV(today, acctSchemaName, documentType, documentNo);
  boolean appendToCSV(String... params) {
    // Build the CSV line
    StringBuffer sb = new StringBuffer();
    for (String param : params) {
    sb.deleteCharAt(sb.length() - SEPARATOR.length());
    // Append to file
    try {
      File log = new File(OBPropertiesProvider.getInstance().getOpenbravoProperties().getProperty("attach.path"), LOG_FILE);
      FileWriter fstream = new FileWriter(log, true);
      BufferedWriter out = new BufferedWriter(fstream);
    } catch (Exception e) {
      //<manage exception>
      return false;
    return true;

The code is quite easy to understand: we get the document type and document number information from the acctServer parameter, and the Accounting Schema name from the as object. This information is appended to our log file that is stored in the attachments folder, inside the myLogFile.txt file.

Observe how in case of any exception we return false, which, as we have seen before, will automatically rollback the accounting entries.

Remember to compile and to restart tomcat after finishing the code development.

General Ledger configuration

The final step to be able to run our process is manually done at the General Ledger Configuration window, inside the Process tab. The end-user must specify the General Ledger(s) for which he wants to run the accounting post-process. Each time we post any document against these general ledgers, our process will be automatically executed just after the creation of the accounting entries.

More than one process can be configured for the same general ledger configuration. In this case, the processes will be executed in the order defined by the Sequence Number field.

In our example we will use any of the general ledgers available at the F&B sample client distributed with Openbravo, because it already contains documents ready to be posted. Remember to apply our configuration dataset to this client in case your Accounting Post-process is not available.


Important: Take into account that the end-user must manually perform this configuration in his instance. You should probably include this critical step into the manual configuration for your module. Alternatively, to make your end-user's life easier, you can develop a module script that transparently configures all the General Ledgers available in the instance.

Testing the code

After updating the General Ledger configuration everything is ready, so it's time to test it. The test is quite simple and consists on posting any document against the selected general ledger

For example, we go to the Purchase Invoice window, and create a new header and we add a line. We complete the invoice and after that we post it.

LocGuide acctProcess 100.png

If everything went well you will see the usual accounting entries.

Now browse to the attachments folder, which is defined at your, and you will see a file called myLogFile.txt. Inside it there should be a line with the information about this invoice:

"05-06-2012","F&B International Group US/A/US Dollar","API","10000214"

If you try now to post more documents, new lines will be appended to the end of this file.

Packaging the module

To generate the obx file we should follow the standard steps from the command line:

ant export.database
ant package.module -Dmodule=<accounting post-process module java package>

Retrieved from ""

This page has been accessed 10,630 times. This page was last modified on 16 November 2012, at 08:20. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.