Archive

Archive for the ‘Tips & Tricks’ Category

Expense Report for Employees or how to extend a Core report

October 26, 2009 7 comments

Hi all, this is the first post of the Tips & Tricks category. In the articles of this category we will share with all of you the tricks that we have learned over the years working in Openbravo and we’ll give you tips that might make your life easier working with Openbravo ERP.

Lets start with the case that opens this category. Recently we received an improvement request for the instance of Openbravo ERP that we use internally to manage Openbravo.

In the 2.50 version in the Project & Service Management module we can find the Expense Report. Openbravo employees log the time sheet to track the time spent on each project and the expenses that might have had in the Expense Sheet window. The Expense Report is very useful to review this data for each customer’s project. It is also possible to filter by employee so you can view the projects that the employee has work on during the time.

In our internal instance we were asked to give access to employees to this report to view our own expenses. But, we had to somehow force to filter the results by the logged employee. So an employee won’t see the expenses and time sheets of other employees.

As this report belongs to Core we cannot modify it. The usual solution in 2.50 is to duplicate it in a module and give access to the employees to the new one. This also means that we are forced to maintain a new report. And that we’d have to manually apply to the duplicated one in the module the improvements and fixes done to the Core report. But this particular feature request only needed a minor change in the filter window, so we thought on a different approach to don’t have to duplicate the whole report.

The solution that we have chosen is to extend the Core report. This is, in the customizations module that we are using we have added a new report Report Expense for Employee. The servlet of this report instead of extend HttpSecureAppServlet is extending the Core report.

public class ReportExpenseForEmployee extends ReportExpense {

Using this approach the doPost method of the new report only checks the DEFAULT commandIn while all other options are treated by the doPost method of the core report. Below is an extract of the doPost method of the ReportExpenseForEmployee class:

public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
  ...
  if (vars.commandIn("DEFAULT")) {
    ...
    printPageDataSheet(response, vars, strDateFrom, strDateTo, strcBpartnerId, strProject,
    strExpense, strCurrencyId);
  } else {
    ...
    super.doPost(request, response);
  }
}

So we have only developed the new filter template that it is a copy of the Core one removing the employee combo and defaulting its value to the employee id of the logged users in a hidden input. Each employee of Openbravo has its own user linked to a Business Partner that has the employee flag checked.

We still had a security issue to resolve, to ensure that nobody is able to call the report with a different employee id. To solve this problem, before calling the parent doPost method we check that the given employee id is correct.

// Check given c_bpartner_id is logged employee's one
 OBContext.setOBContext("0");
 User user = OBDal.getInstance().get(User.class, vars.getUser());
 String strBpartner = (user.getBusinessPartner() != null ? user.getBusinessPartner().getId()
 : "");
 OBContext.setOBContext(user.getId());
 if (!vars.getGlobalVariable("inpUser", "ReportExpenseForEmployee|employee", "").equals(
 strBpartner))
   pageError(response);
 super.doPost(request, response);

And that’s all. We have given access to the employees to this new Report Expense for Employee report and removed the access to the Core report. At this moment employees are able to check its own reported expenses and time sheets. While managers have access to the Core report to review the expenses and time sheets of other employees.  All of this having to maintain only the filter window in the module. Getting advantage without any extra work of all the improvements and fixes done in the Core’s report template and queries.

NOTE (added 2009-10-28)

As Stefan Huehner has point me, the security issue can be solved in a better way in newer 2.50 mps. To get the business partner associated using DAL we need to have access to the user entity. But in our instance the Employee role doesn’t, so it only can get the user_id and its name. To ensure that we can query that we have to enter in administration mode.

When we did this extension we were using a 2.50MP1, so this was achieved changing the OBContext to the user “0”. And once we have the business partner id the OBContext is set back to the logged user.

In newer MPs a new method has been created to manage these cases. The code (not tested) would be something like:

// Check given c_bpartner_id is logged employee's one
 boolean previousAdminMode = OBContext.getOBContext().setInAdministratorMode(true);
 try {
   User user = OBDal.getInstance().get(User.class, vars.getUser());
   String strBpartner = (user.getBusinessPartner() != null ? user.getBusinessPartner().getId() : "");
 } finally {
   boolean adminMode = OBContext.getOBContext().setInAdministratorMode(previousAdminMode);
 }
 if (!vars.getGlobalVariable("inpUser", "ReportExpenseForEmployee|employee", "").equals(
 strBpartner))
   pageError(response);
 super.doPost(request, response);