[pi-code-cleaning] Merge with latest pi
authorNaroa Iriarte <naroa.iriarte@openbravo.com>
Mon, 09 May 2016 09:57:27 +0200
changeset 29489 1c0637886cfe
parent 29488 ae3288e7bc8a (current diff)
parent 29449 58bacde3f953 (diff)
child 29490 cdef8accca50
[pi-code-cleaning] Merge with latest pi
src-test/src/org/openbravo/test/datasource/TestInitializeAccess.java
src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java
--- a/.hgsigs	Fri Apr 29 14:59:04 2016 +0200
+++ b/.hgsigs	Mon May 09 09:57:27 2016 +0200
@@ -189,4 +189,6 @@
 24d2967df096de06913c9991553c1d84b07df9b6 0 iEYEABECAAYFAla9YYIACgkQCX/oGf+2qkNH7wCfV32iOyR/TQKzW/mH1iHTir6f6h4AoIlh4QBWIShpJqbJvx2IhfARpvUZ
 f016ea545c924ad099e9e402689035f1dd73baa2 0 iEYEABECAAYFAlbTzQoACgkQCX/oGf+2qkP28wCdFpNqpw+ODgF0p3cMJAbTZy1IPfoAoNEuRHkZIM5bNJMjwU0/GhjCtwah
 a53670f00eb6c9225829a660075fcfffa1109a1e 0 iEYEABECAAYFAlbqRpEACgkQCX/oGf+2qkN5qQCgsO1APX5AJ4cpb0oJX5vUQnvPMusAoPoDaQxGDihvsB4BSGW60RIxBdGC
+bdeb5a373f19eb7a144377621926d877ae2322f1 0 iEYEABECAAYFAlcgSPgACgkQCX/oGf+2qkMPLwCgzV//EHUa2bHmP8FA2IwnrFWB1X4AnjGHHjYKfSwiucQhltXR9POZXGaX
 38ef1dc10aa3d6fb8210b85beab370f62a4545ca 0 iEYEABECAAYFAlbiTM0ACgkQCX/oGf+2qkNBDwCfXmKXkqNGsAsfiofYOBBdvjA/XgkAoIwLK3DkmHeM71JihwfVOWyB4hmj
+265e8eccf704614fe88220026f2e2bafcebaaf00 0 iEYEABECAAYFAlcgZEQACgkQCX/oGf+2qkPuZgCcDPuB9d77M+51AglMvvmtpCDtnvoAnjqst7QgD6IP3Sv21+4vlqEjLVqU
--- a/.hgtags	Fri Apr 29 14:59:04 2016 +0200
+++ b/.hgtags	Mon May 09 09:57:27 2016 +0200
@@ -200,4 +200,6 @@
 9985680adffaf70ffcc1f560860feb10f0ee6b33 3.0PR15Q4.3
 70df4e4c5cab6d37f10eceee6b66be039c381556 3.0PR15Q4.4
 21c8ed48293c94cbe5875a8edef08aca0efd2bf4 3.0PR15Q4.5
+8828e6e8e071247f329320c63da66e30c357da9f 3.0PR15Q4.6
 ee5383e071318afe8eece515b4b264cfb46c1a84 3.0PR16Q1
+d386f41fa755d23e0e23f881aece691009051ebd 3.0PR16Q1.1
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddOrderOrInvoiceFilterExpression.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/filterexpression/AddOrderOrInvoiceFilterExpression.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -59,6 +59,7 @@
         }
       }
     } catch (Exception e) {
+      log.error("Error calculating filter expression", e);
       return "";
     }
     return "";
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/process/FIN_PaymentProcess.java	Mon May 09 09:57:27 2016 +0200
@@ -1057,7 +1057,8 @@
                   // Create merged Payment Schedule Detail with the pending to be paid amount
                   if (outStandingAmt.compareTo(BigDecimal.ZERO) != 0) {
                     final FIN_PaymentScheduleDetail mergedScheduleDetail = dao
-                        .getNewPaymentScheduleDetail(payment.getOrganization(), outStandingAmt);
+                        .getNewPaymentScheduleDetail(paymentScheduleDetail.getInvoicePaymentSchedule()
+                           .getInvoice().getOrganization(), outStandingAmt);
                     mergedScheduleDetail.setInvoicePaymentSchedule(paymentScheduleDetail
                         .getInvoicePaymentSchedule());
                     mergedScheduleDetail.setOrderPaymentSchedule(paymentScheduleDetail
@@ -1085,7 +1086,8 @@
                   // Create merged Payment Schedule Detail with the pending to be paid amount
                   if (outStandingAmt.compareTo(BigDecimal.ZERO) != 0) {
                     final FIN_PaymentScheduleDetail mergedScheduleDetail = dao
-                        .getNewPaymentScheduleDetail(payment.getOrganization(), outStandingAmt);
+                        .getNewPaymentScheduleDetail(paymentScheduleDetail.getOrderPaymentSchedule()
+                        	.getOrder().getOrganization(), outStandingAmt);
                     mergedScheduleDetail.setOrderPaymentSchedule(paymentScheduleDetail
                         .getOrderPaymentSchedule());
                     OBDal.getInstance().save(mergedScheduleDetail);
--- a/modules/org.openbravo.client.application/src/org/openbravo/client/application/process/DefaultsProcessActionHandler.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.application/src/org/openbravo/client/application/process/DefaultsProcessActionHandler.java	Mon May 09 09:57:27 2016 +0200
@@ -103,7 +103,8 @@
                 if (field.getObuiappDefaultExpression() != null) {
                   String rawDefaultExpression = field.getObuiappDefaultExpression();
                   Object defaultExpression;
-                  parameters.put("filterExpressionColumnName", field.getColumn().getDBColumnName());
+                  fixedParameters.put("filterExpressionColumnName", field.getColumn()
+                      .getDBColumnName());
                   defaultExpression = ParameterUtils.getJSExpressionResult(fixedParameters,
                       (HttpSession) parameters.get(KernelConstants.HTTP_SESSION),
                       rawDefaultExpression);
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-base-parameter-window-view.js	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-base-parameter-window-view.js	Mon May 09 09:57:27 2016 +0200
@@ -154,7 +154,7 @@
           // the default
           field.onChangeFunction.sort = 50;
 
-          OB.OnChangeRegistry.register(this.viewId, field.name, field.onChangeFunction, 'default');
+          OB.OnChangeRegistry.register(this.viewId || this.processId, field.name, field.onChangeFunction, 'default');
         }
 
         if (field.type === 'OBSectionItem' && !field.sectionExpanded) {
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-parameter-window-form.js	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-parameter-window-form.js	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2014 Openbravo SLU
+ * All portions are Copyright (C) 2014-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -55,10 +55,14 @@
   // this function is invoked on the blur action of the formitems
   // this is the proper place to execute the client-side callouts
   handleItemChange: function (item) {
-    var affectedParams, i, field, me = this;
+    var affectedParams, i, field, me = this,
+        registryId;
+
+    registryId = this.paramWindow.viewId || this.paramWindow.processId;
+
     // Execute onChangeFunctions if they exist
-    if (this && OB.OnChangeRegistry.hasOnChange(this.paramWindow.viewId, item)) {
-      OB.OnChangeRegistry.call(this.paramWindow.viewId, item, this.paramWindow, this, this.paramWindow.viewGrid);
+    if (OB.OnChangeRegistry.hasOnChange(registryId, item)) {
+      OB.OnChangeRegistry.call(registryId, item, this.paramWindow, this, this.paramWindow.viewGrid);
     }
     // Check validation rules (subordinated fields), when value of a
     // parent field is changed, all its subordinated are reset
--- a/modules/org.openbravo.client.kernel/jslint/jscheck	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.kernel/jslint/jscheck	Mon May 09 09:57:27 2016 +0200
@@ -6,7 +6,6 @@
 -and ! -path '*unittest*' \
 -and ! -path '*postest*' \
 -and ! -path '*xmla4js*' \
--and ! -path '*source*' \
 -and ! -path '*VAADIN*' \
 -and ! -path '*saiku*' \
 -and ! -path '*libs*' \
--- a/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.kernel/src/org/openbravo/client/kernel/reference/CharacteristicsUIDefinition.java	Mon May 09 09:57:27 2016 +0200
@@ -33,6 +33,7 @@
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.data.Sqlc;
 import org.openbravo.erpCommon.businessUtility.Preferences;
+import org.openbravo.erpCommon.utility.PropertyNotFoundException;
 import org.openbravo.model.ad.ui.Field;
 import org.openbravo.model.ad.utility.Tree;
 import org.openbravo.model.ad.utility.TreeNode;
@@ -128,6 +129,7 @@
               .getCurrentOrganization(), OBContext.getOBContext().getUser(), OBContext
               .getOBContext().getRole(), null);
       levels = Integer.parseInt(levelsPreference);
+    } catch (PropertyNotFoundException ignore) {
     } catch (Exception e) {
       if (e instanceof NumberFormatException) {
         log4j.error("ShowProductCharacteristicsParents preference is not a number", e);
--- a/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.client.querylist/src/org/openbravo/client/querylist/QueryListDataSource.java	Mon May 09 09:57:27 2016 +0200
@@ -90,36 +90,41 @@
   @Override
   public void checkFetchDatasourceAccess(Map<String, String> parameters) {
     // Check security: continue only if the widget instance is visible for current user/role
-    WidgetClass widgetClass = OBDal.getInstance()
-        .get(WidgetClass.class, parameters.get("widgetId"));
-    WidgetInstance wi = OBDal.getInstance().get(WidgetInstance.class,
-        parameters.get("widgetInstanceId"));
+    OBContext.setAdminMode(true);
+    try {
+      WidgetClass widgetClass = OBDal.getInstance().get(WidgetClass.class,
+          parameters.get("widgetId"));
+      WidgetInstance wi = OBDal.getInstance().get(WidgetInstance.class,
+          parameters.get("widgetInstanceId"));
 
-    boolean accessibleWidgetInForm = false;
-    if (wi == null) {
-      accessibleWidgetInForm = isAccessibleWidgetInForm(widgetClass);
-    }
-    if (!accessibleWidgetInForm
-        && (wi == null || wi.getWidgetClass().getId() != widgetClass.getId())) {
-      // weird stuff: widget class doesn't match widget instance's class, most probably URL is
-      // not generated by UI, but user is typing it
-      log.error("User " + OBContext.getOBContext().getUser() + " with role "
-          + OBContext.getOBContext().getRole() + " is trying to access widget '"
-          + widgetClass.getWidgetTitle() + "' but widget istance doesn't match with class");
-      throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
-          new String[] { widgetClass.getWidgetTitle() }));
-    }
+      boolean accessibleWidgetInForm = false;
+      if (wi == null) {
+        accessibleWidgetInForm = isAccessibleWidgetInForm(widgetClass);
+      }
+      if (!accessibleWidgetInForm
+          && (wi == null || !wi.getWidgetClass().getId().equals(widgetClass.getId()))) {
+        // weird stuff: widget class doesn't match widget instance's class, most probably URL is
+        // not generated by UI, but user is typing it
+        log.error("User " + OBContext.getOBContext().getUser() + " with role "
+            + OBContext.getOBContext().getRole() + " is trying to access widget '"
+            + widgetClass.getWidgetTitle() + "' but widget instance doesn't match with class");
+        throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
+            new String[] { widgetClass.getWidgetTitle() }));
+      }
 
-    if (!accessibleWidgetInForm
-        && (OBContext.getOBContext() != null
-            && ((wi.getVisibleAtUser() != null && !wi.getVisibleAtUser().getId()
-                .equals(OBContext.getOBContext().getUser().getId()))) || (wi.getVisibleAtRole() != null && !wi
-            .getVisibleAtRole().getId().equals(OBContext.getOBContext().getRole().getId())))) {
-      log.error("User " + OBContext.getOBContext().getUser() + " with role "
-          + OBContext.getOBContext().getRole() + " is trying to access widget '"
-          + widgetClass.getWidgetTitle() + "' which is not granted");
-      throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
-          new String[] { widgetClass.getWidgetTitle() }));
+      if (!accessibleWidgetInForm
+          && (OBContext.getOBContext() != null
+              && ((wi.getVisibleAtUser() != null && !wi.getVisibleAtUser().getId()
+                  .equals(OBContext.getOBContext().getUser().getId()))) || (wi.getVisibleAtRole() != null && !wi
+              .getVisibleAtRole().getId().equals(OBContext.getOBContext().getRole().getId())))) {
+        log.error("User " + OBContext.getOBContext().getUser() + " with role "
+            + OBContext.getOBContext().getRole() + " is trying to access widget '"
+            + widgetClass.getWidgetTitle() + "' which is not granted");
+        throw new OBSecurityException(OBMessageUtils.getI18NMessage("OBCQL_NoAccessToWidget",
+            new String[] { widgetClass.getWidgetTitle() }));
+      }
+    } finally {
+      OBContext.restorePreviousMode();
     }
   }
 
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/BaseDataSourceService.java	Mon May 09 09:57:27 2016 +0200
@@ -29,7 +29,6 @@
 import org.openbravo.base.exception.OBSecurityException;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
-import org.openbravo.base.model.Property;
 import org.openbravo.client.application.CachedPreference;
 import org.openbravo.client.application.window.ApplicationDictionaryCachedStructures;
 import org.openbravo.client.kernel.Template;
@@ -39,6 +38,7 @@
 import org.openbravo.model.ad.ui.Tab;
 import org.openbravo.model.common.order.Order;
 import org.openbravo.service.json.JsonConstants;
+import org.openbravo.userinterface.selector.Selector;
 import org.openbravo.userinterface.selector.SelectorConstants;
 
 /**
@@ -154,31 +154,21 @@
     String selectorId = parameters.get(SelectorConstants.DS_REQUEST_SELECTOR_ID_PARAMETER);
     if (StringUtils.isNotBlank(selectorId)) {
       // selectors
-      String processId = parameters.get(SelectorConstants.DS_REQUEST_PROCESS_DEFINITION_ID);
-      if (StringUtils.isNotBlank(processId)) {
-        // selectors defined in a process definition
-        if (entityToCheck != null) {
-          try {
-            obContext.getEntityAccessChecker().checkDerivedAccess(entityToCheck);
-          } catch (OBSecurityException e) {
-            handleExceptionUnsecuredDSAccess(e);
-          }
+      if (entityToCheck == null) {
+        OBContext.setAdminMode(true);
+        try {
+          Selector sel = OBDal.getInstance().get(Selector.class, selectorId);
+          entityToCheck = ModelProvider.getInstance().getEntityByTableId(
+              (String) DalUtil.getId(sel.getTable()));
+        } finally {
+          OBContext.restorePreviousMode();
         }
-      } else {
-        // rest of the selectors
-        String tableId = parameters.get("inpTableId");
-        String targetPropertyName = parameters.get(SelectorConstants.PARAM_TARGET_PROPERTY_NAME);
-        if (StringUtils.isNotBlank(targetPropertyName)) {
-          try {
-            Entity parentEntity = ModelProvider.getInstance().getEntityByTableId(tableId);
-            Property p = parentEntity.getProperty(targetPropertyName);
-            Entity entitySelector = p.getReferencedProperty().getEntity();
-            if (entitySelector != null) {
-              obContext.getEntityAccessChecker().checkDerivedAccess(entitySelector);
-            }
-          } catch (OBSecurityException e) {
-            handleExceptionUnsecuredDSAccess(e);
-          }
+      }
+      if (entityToCheck != null) {
+        try {
+          obContext.getEntityAccessChecker().checkDerivedAccess(entityToCheck);
+        } catch (OBSecurityException e) {
+          handleExceptionUnsecuredDSAccess(e);
         }
       }
     } else if (entityToCheck != null) {
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Mon May 09 09:57:27 2016 +0200
@@ -142,7 +142,7 @@
 
       SessionInfo.setModuleId(request.getParameter("moduleId"));
       SessionInfo.setCommand(request.getParameter(DataSourceConstants.OPERATION_TYPE_PARAM));
-      SessionInfo.setProcessId(request.getParameter("tabId"));
+      SessionInfo.setProcessId(request.getParameter(JsonConstants.TAB_PARAMETER));
       SessionInfo.setProcessType("W");
 
       super.service(request, response);
@@ -208,7 +208,7 @@
       getRequestContent(request);
     }
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -236,10 +236,9 @@
           try {
             OBContext.setAdminMode();
             try {
-              Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-                  || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-                  .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
-                  .getWindow();
+              Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+                  : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                      .getWindow();
               String encoding = Preferences.getPreferenceValue("OBSERDS_CSVTextEncoding", true,
                   OBContext.getOBContext().getCurrentClient(), OBContext.getOBContext()
                       .getCurrentOrganization(), OBContext.getOBContext().getUser(), OBContext
@@ -312,9 +311,9 @@
         response.setHeader("Content-Disposition", "attachment; filename=ExportedData.csv");
         writer = response.getWriter();
         VariablesSecureApp vars = new VariablesSecureApp(request);
-        Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-            || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-            .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER)).getWindow();
+        Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+            : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                .getWindow();
         try {
           prefDecimalSeparator = Preferences.getPreferenceValue("OBSERDS_CSVDecimalSeparator",
               true, OBContext.getOBContext().getCurrentClient(), OBContext.getOBContext()
@@ -370,8 +369,7 @@
         }
 
         fieldProperties = new ArrayList<String>();
-        if (parameters.get("viewState") != null
-            && !parameters.get("viewState").toString().equals("undefined")) {
+        if (!JsonUtils.isValueEmpty(parameters.get("viewState"))) {
           String viewStateO = parameters.get("viewState");
           String viewStateWithoutParenthesis = viewStateO.substring(1, viewStateO.length() - 1);
           JSONObject viewState = new JSONObject(viewStateWithoutParenthesis);
@@ -701,10 +699,9 @@
       try {
         String csvMessage = null;
         try {
-          Window window = parameters.get(JsonConstants.TAB_PARAMETER) == null
-              || parameters.get(JsonConstants.TAB_PARAMETER).equals("undefined") ? null : OBDal
-              .getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
-              .getWindow();
+          Window window = JsonUtils.isValueEmpty(parameters.get(JsonConstants.TAB_PARAMETER)) ? null
+              : OBDal.getInstance().get(Tab.class, parameters.get(JsonConstants.TAB_PARAMETER))
+                  .getWindow();
           csvMessage = Preferences.getPreferenceValue(property, true, OBContext.getOBContext()
               .getCurrentClient(), OBContext.getOBContext().getCurrentOrganization(), OBContext
               .getOBContext().getUser(), OBContext.getOBContext().getRole(), window);
@@ -764,7 +761,7 @@
     setSessionInfo();
 
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -797,7 +794,7 @@
       if (!checkSetParameters(request, response, parameters)) {
         return;
       }
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -836,7 +833,7 @@
     final Map<String, String> parameters = getParameterMap(request);
     setSessionInfo();
     try {
-      if (!hasAccess(request, parameters.get("tabId"))) {
+      if (!hasAccess(request, parameters.get(JsonConstants.TAB_PARAMETER))) {
         throw new OBUserException("AccessTableNoView");
       }
 
@@ -998,7 +995,7 @@
    */
   private boolean hasAccess(HttpServletRequest req, String tabId) {
     try {
-      if (tabId == null || tabId.isEmpty()) {
+      if (JsonUtils.isValueEmpty(tabId)) {
         return true;
       }
       VariablesSecureApp vars = new VariablesSecureApp(req);
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/TreeDatasourceService.java	Mon May 09 09:57:27 2016 +0200
@@ -139,9 +139,15 @@
 
   @Override
   public void checkEditDatasourceAccess(Map<String, String> parameter) {
-    Entity theEntity = getEntity();
-    if (!hasAccess(theEntity, null, false)) {
-      throw new OBException(OBMessageUtils.messageBD("AccessTableNoView"));
+    final OBContext obContext = OBContext.getOBContext();
+    String tableId = parameter.get("referencedTableId");
+    try {
+      Entity treeEntity = ModelProvider.getInstance().getEntityByTableId(tableId);
+      if (treeEntity != null) {
+        obContext.getEntityAccessChecker().checkWritableAccess(treeEntity);
+      }
+    } catch (OBSecurityException e) {
+      handleExceptionUnsecuredDSAccess(e);
     }
   }
 
--- a/modules/org.openbravo.service.json/src-test/org/openbravo/service/json/test/DataQueryServiceTest.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.json/src-test/org/openbravo/service/json/test/DataQueryServiceTest.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -44,7 +44,7 @@
 import org.openbravo.test.base.OBBaseTest;
 
 /**
- * Test the {@link DataEntityQueryService} and {@link QueryBuilder} classes.
+ * Test the {@link DataEntityQueryService} and {@link AdvancedQueryBuilder} classes.
  * 
  * @author mtaal
  */
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/DataEntityQueryService.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/DataEntityQueryService.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -51,8 +51,6 @@
  * 
  * This service class can not be used as a singleton.
  * 
- * It makes use of the {@link QueryBuilder} helper class to manage filter information.
- * 
  * @author mtaal
  */
 public class DataEntityQueryService {
@@ -280,8 +278,8 @@
   }
 
   /**
-   * Tells the {@link QueryBuilder} to use the {@link JsonConstants#MAIN_ALIAS} as the alias for
-   * prefixing all properties in the where clause and order by.
+   * Tells the query builder to use the {@link JsonConstants#MAIN_ALIAS} as the alias for prefixing
+   * all properties in the where clause and order by.
    */
   public void setUseAlias() {
     queryBuilder.setMainAlias(JsonConstants.MAIN_ALIAS);
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonConstants.java	Mon May 09 09:57:27 2016 +0200
@@ -128,4 +128,7 @@
   public static final String WHERE_CLAUSE_HAS_BEEN_CHECKED = "whereClauseHasBeenChecked";
   public static final String WINDOW_ID = "windowId";
   public static final String DATASOURCE_NAME = "dataSourceName";
+
+  public static final String UNDEFINED = "undefined";
+  public static final String NULL = "null";
 }
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonDataService.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonDataService.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2011 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -51,7 +51,6 @@
    *          the parameters driving the query, one parameter is mandatory:
    *          {@link JsonConstants#ENTITYNAME}
    * @return a json result string
-   * @see QueryBuilder
    */
   public abstract String fetch(Map<String, String> parameters);
 
--- a/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.service.json/src/org/openbravo/service/json/JsonUtils.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -25,6 +25,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
@@ -391,4 +392,18 @@
     }
   }
 
+  /**
+   * Returns whether a JSON value is empty. The following values are considered as empty:
+   * <ul>
+   * <li>An empty string
+   * <li>{@code null}
+   * <li>{@code "null"} literal
+   * <li>{@code "undefined"} literal
+   * </ul>
+   */
+  public static boolean isValueEmpty(String value) {
+    return StringUtils.isEmpty(value) || JsonConstants.UNDEFINED.equals(value)
+        || JsonConstants.NULL.equals(value);
+  }
+
 }
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorDataSourceFilter.java	Mon May 09 09:57:27 2016 +0200
@@ -370,11 +370,6 @@
           sb.append(" and ");
         }
 
-        // Code duplicated from org.openbravo.service.json.QueryBuilder
-        // Used to identify the type of property and modify the _where parameter
-        // If the this code change, make sure you check the getWhereClause method of the
-        // QueryBuilder. Check issue https://issues.openbravo.com/view.php?id=14239
-
         if (!property.isPrimitive()) {
           sb.append("e." + sf.getProperty() + ".id = '" + result.toString() + "'");
         } else if (String.class == property.getPrimitiveObjectType()) {
--- a/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Fri Apr 29 14:59:04 2016 +0200
+++ b/modules/org.openbravo.userinterface.selector/web/org.openbravo.userinterface.selector/js/ob-selector-item.js	Mon May 09 09:57:27 2016 +0200
@@ -1112,6 +1112,13 @@
   // Prepares requestProperties adding contextInfo, this is later used in backed
   // to prepare filters 
   prepareDSRequest: function (params, selector) {
+    function setOrgIdParam(params) {
+      if (!params.inpadOrgId) {
+        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
+        params.inpadOrgId = params.ad_org_id || params.AD_Org_ID || OB.User.organizationId;
+      }
+    }
+
     // on purpose not passing the third boolean param
     if (selector.form && selector.form.view && selector.form.view.getContextInfo) {
       // for table and table dir reference values needs to be transformed to classic (ex.: true -> Y)
@@ -1121,20 +1128,14 @@
       if (selector.form && selector.form.paramWindow && selector.form.paramWindow.getContextInfo) {
         isc.addProperties(params, selector.form.paramWindow.getContextInfo());
       }
-      if (!params.inpadOrgId) {
-        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
-        params.inpadOrgId = params.ad_org_id || OB.User.organizationId;
-      }
+      setOrgIdParam(params);
     } else if (selector.view && selector.view.sourceView && selector.view.sourceView.getContextInfo) {
       isc.addProperties(params, selector.view.sourceView.getContextInfo(false, true, null, selector.isComboReference));
     } else if (selector.grid && selector.grid.contentView && selector.grid.contentView.getContextInfo) {
       isc.addProperties(params, selector.grid.contentView.getContextInfo(false, true, null, selector.isComboReference));
     } else if (selector.form && selector.form.paramWindow && selector.form.paramWindow.getContextInfo) {
       isc.addProperties(params, selector.form.paramWindow.getContextInfo());
-      if (!params.inpadOrgId) {
-        // look for an ad_org_id parameter. If there is no such parameter or its value is empty, use the current user organization
-        params.inpadOrgId = params.ad_org_id || OB.User.organizationId;
-      }
+      setOrgIdParam(params);
     }
 
     // if the selector belongs to a P&E grid, include the info of the record being edited
--- a/src-db/database/model/functions/C_INVOICE_CREATE.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/model/functions/C_INVOICE_CREATE.xml	Mon May 09 09:57:27 2016 +0200
@@ -993,7 +993,7 @@
                 CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 2, 1))
                   WHEN '0'
                   THEN '0'
-                  ELSE sh.C_Order_ID
+                  ELSE COALESCE(sh.C_Order_ID, o.C_Order_ID)
                 END
                 ) ||'-'|| (
                 CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 3, 1))
@@ -1032,7 +1032,7 @@
                   ELSE COALESCE(o.C_PaymentTerm_ID, bp.C_PaymentTerm_ID)
                 END
                 ) ||'-'|| (
-                CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 8, 1))
+                CASE TO_CHAR(SUBSTR(RPAD(substr(bp.InvoiceGrouping, instr(bp.InvoiceGrouping, '_') + 1), 15, '0'), 9, 1))
                   WHEN '0'
                   THEN '0'
                   ELSE o.C_Currency_ID
--- a/src-db/database/model/functions/C_ORDER_POST1.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/model/functions/C_ORDER_POST1.xml	Mon May 09 09:57:27 2016 +0200
@@ -367,12 +367,25 @@
     */
     IF (v_DocAction = 'CO' OR v_DocAction = 'PR') THEN
       SELECT COUNT(*)
-        INTO v_Aux
-       FROM C_ORDERLINE
-       WHERE C_ORDER_ID = v_Record_ID;
-       IF v_Aux=0 THEN
-         RAISE_APPLICATION_ERROR(-20000, '@OrderWithoutLines@');
-       END IF;
+      INTO v_Aux
+      FROM C_ORDERLINE
+      WHERE C_ORDER_ID = v_Record_ID;
+      IF (v_Aux = 0) THEN
+        RAISE_APPLICATION_ERROR(-20000, '@OrderWithoutLines@');
+      END IF;
+    END IF;
+
+    /**
+    * Check if already processed / reactivated
+    */
+    IF (v_DocAction = 'CO' OR v_DocAction = 'PR') THEN
+      IF (v_IsProcessed = 'Y') THEN
+        RAISE_APPLICATION_ERROR(-20000,'@AlreadyPosted@');
+      END IF;
+    ELSIF (v_DocAction='RE') THEN
+      IF (v_IsProcessed = 'N') THEN
+        RAISE_APPLICATION_ERROR(-20000,'@ActionNotSupported@');
+      END IF;
     END IF;
 
     -- Check the cash vat flag for all the taxes matches the order one
--- a/src-db/database/model/functions/M_INVENTORY_LISTUPDATE.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/model/functions/M_INVENTORY_LISTUPDATE.xml	Mon May 09 09:57:27 2016 +0200
@@ -19,7 +19,7 @@
   * parts created by ComPiere are Copyright (C) ComPiere, Inc.;
   * All Rights Reserved.
   * Contributor(s): Openbravo SLU
-  * Contributions are Copyright (C) 2001-2015 Openbravo, S.L.U.
+  * Contributions are Copyright (C) 2001-2016 Openbravo, S.L.U.
   *
   * Specifically, this derivative work is based upon the following Compiere
   * file and version.
@@ -100,7 +100,8 @@
   */
   IF(NOT END_PROCESS) THEN
     v_ResultStr:='UpdatingLine';
-    DELETE FROM M_InventoryLine
+    UPDATE M_InventoryLine
+    SET QtyBook = 0, QuantityOrderBook = 0
       WHERE M_Inventory_ID=v_Record_ID
         AND (NOT EXISTS
         (SELECT *
@@ -122,10 +123,6 @@
           AND (s.QTYORDERONHAND = 0 OR s.QTYORDERONHAND IS NULL)
         ))
     ;
-    rowcount:=SQL%ROWCOUNT;
-    IF(rowcount<>0) THEN
-      v_Message:='@Deleted@=' || rowcount || ', ';  
-    END IF;
     UPDATE M_InventoryLine
       SET QtyBook=
       (SELECT QtyOnHand
--- a/src-db/database/sourcedata/AD_MESSAGE.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/sourcedata/AD_MESSAGE.xml	Mon May 09 09:57:27 2016 +0200
@@ -26569,6 +26569,18 @@
 <!--E54B403F2B0944E6A68D06661BD7F47E-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--E54B403F2B0944E6A68D06661BD7F47E--></AD_MESSAGE>
 
+<!--E5591DEB3EF44C7493DAA1A7A4429105--><AD_MESSAGE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_MESSAGE_ID><![CDATA[E5591DEB3EF44C7493DAA1A7A4429105]]></AD_MESSAGE_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <VALUE><![CDATA[OPSWSCounterDay]]></VALUE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <MSGTEXT><![CDATA[Current Web Services calls]]></MSGTEXT>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--E5591DEB3EF44C7493DAA1A7A4429105-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--E5591DEB3EF44C7493DAA1A7A4429105--></AD_MESSAGE>
+
 <!--E584531278034B1BA298C7CEBB58EAD2--><AD_MESSAGE>
 <!--E584531278034B1BA298C7CEBB58EAD2-->  <AD_MESSAGE_ID><![CDATA[E584531278034B1BA298C7CEBB58EAD2]]></AD_MESSAGE_ID>
 <!--E584531278034B1BA298C7CEBB58EAD2-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
@@ -26750,6 +26762,18 @@
 <!--E7EBD616ABA7417DB1759D8B7E901405-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
 <!--E7EBD616ABA7417DB1759D8B7E901405--></AD_MESSAGE>
 
+<!--E7EBD96FEE9A4B9790F47EB089F72888--><AD_MESSAGE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_MESSAGE_ID><![CDATA[E7EBD96FEE9A4B9790F47EB089F72888]]></AD_MESSAGE_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <VALUE><![CDATA[OPSCurrentConcurrentUsers]]></VALUE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <MSGTEXT><![CDATA[Current concurrent users]]></MSGTEXT>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <MSGTYPE><![CDATA[I]]></MSGTYPE>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--E7EBD96FEE9A4B9790F47EB089F72888-->  <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
+<!--E7EBD96FEE9A4B9790F47EB089F72888--></AD_MESSAGE>
+
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F--><AD_MESSAGE>
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F-->  <AD_MESSAGE_ID><![CDATA[E83760BF3C4E4BE9BEEE76CD6CBE734F]]></AD_MESSAGE_ID>
 <!--E83760BF3C4E4BE9BEEE76CD6CBE734F-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/AD_REF_LIST.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/sourcedata/AD_REF_LIST.xml	Mon May 09 09:57:27 2016 +0200
@@ -7923,8 +7923,8 @@
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
 <!--06F962562D694CEC88B00D4247A2315A-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--06F962562D694CEC88B00D4247A2315A-->  <VALUE><![CDATA[S]]></VALUE>
-<!--06F962562D694CEC88B00D4247A2315A-->  <NAME><![CDATA[Successfull]]></NAME>
-<!--06F962562D694CEC88B00D4247A2315A-->  <DESCRIPTION><![CDATA[Sesion logged in successfully]]></DESCRIPTION>
+<!--06F962562D694CEC88B00D4247A2315A-->  <NAME><![CDATA[Successful]]></NAME>
+<!--06F962562D694CEC88B00D4247A2315A-->  <DESCRIPTION><![CDATA[Session logged in successfully]]></DESCRIPTION>
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_REFERENCE_ID><![CDATA[86086D70DDBC42B09E2BEB51D25C159F]]></AD_REFERENCE_ID>
 <!--06F962562D694CEC88B00D4247A2315A-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--06F962562D694CEC88B00D4247A2315A--></AD_REF_LIST>
@@ -10466,7 +10466,7 @@
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <VALUE><![CDATA[CUR]]></VALUE>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <NAME><![CDATA[Concurrent Users Limit Reached]]></NAME>
-<!--88EDCB912A6445A4BE6EEA28952212E9-->  <DESCRIPTION><![CDATA[Reached number of maximum concurrent users in the instance]]></DESCRIPTION>
+<!--88EDCB912A6445A4BE6EEA28952212E9-->  <DESCRIPTION><![CDATA[Reached maximum number of allowed concurrent users in the instance]]></DESCRIPTION>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <AD_REFERENCE_ID><![CDATA[86086D70DDBC42B09E2BEB51D25C159F]]></AD_REFERENCE_ID>
 <!--88EDCB912A6445A4BE6EEA28952212E9-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--88EDCB912A6445A4BE6EEA28952212E9--></AD_REF_LIST>
@@ -12383,6 +12383,18 @@
 <!--D9FFDD5DD51D434FB45628FCBAD10A4E-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
 <!--D9FFDD5DD51D434FB45628FCBAD10A4E--></AD_REF_LIST>
 
+<!--DA98D956E0BF4DCA887932756C327D73--><AD_REF_LIST>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_REF_LIST_ID><![CDATA[DA98D956E0BF4DCA887932756C327D73]]></AD_REF_LIST_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <ISACTIVE><![CDATA[Y]]></ISACTIVE>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <VALUE><![CDATA[BypassAccessLevelEntityCheck]]></VALUE>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <NAME><![CDATA[Bypass Access Level Entity Check]]></NAME>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <DESCRIPTION><![CDATA[When its value is Y, entity access level check will not be performed.]]></DESCRIPTION>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_REFERENCE_ID><![CDATA[A26BA480E2014707B47257024C3CBFF7]]></AD_REFERENCE_ID>
+<!--DA98D956E0BF4DCA887932756C327D73-->  <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
+<!--DA98D956E0BF4DCA887932756C327D73--></AD_REF_LIST>
+
 <!--DAC02370F50D485BAA4F79957AA1A7A4--><AD_REF_LIST>
 <!--DAC02370F50D485BAA4F79957AA1A7A4-->  <AD_REF_LIST_ID><![CDATA[DAC02370F50D485BAA4F79957AA1A7A4]]></AD_REF_LIST_ID>
 <!--DAC02370F50D485BAA4F79957AA1A7A4-->  <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
--- a/src-db/database/sourcedata/referencedData/C_CURRENCY.xml	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-db/database/sourcedata/referencedData/C_CURRENCY.xml	Mon May 09 09:57:27 2016 +0200
@@ -855,7 +855,7 @@
 <!--170-->  <CREATEDBY><![CDATA[0]]></CREATEDBY>
 <!--170-->  <UPDATED><![CDATA[2011-02-22 17:06:39.0]]></UPDATED>
 <!--170-->  <UPDATEDBY><![CDATA[0]]></UPDATEDBY>
-<!--170-->  <ISO_CODE><![CDATA[GHC]]></ISO_CODE>
+<!--170-->  <ISO_CODE><![CDATA[GHS]]></ISO_CODE>
 <!--170-->  <CURSYMBOL><![CDATA[ยข]]></CURSYMBOL>
 <!--170-->  <DESCRIPTION><![CDATA[Cedi]]></DESCRIPTION>
 <!--170-->  <STDPRECISION><![CDATA[2]]></STDPRECISION>
--- a/src-test/src/org/openbravo/test/AllAntTaskTests.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-test/src/org/openbravo/test/AllAntTaskTests.java	Mon May 09 09:57:27 2016 +0200
@@ -77,6 +77,7 @@
 import org.openbravo.test.scheduling.ProcessSchedulingTest;
 import org.openbravo.test.security.AccessLevelTest;
 import org.openbravo.test.security.AllowedOrganizationsTest;
+import org.openbravo.test.security.BypassAccessLevelCheck;
 import org.openbravo.test.security.EntityAccessTest;
 import org.openbravo.test.security.StandardCrossOrganizationReference;
 import org.openbravo.test.security.WritableReadableOrganizationClientTest;
@@ -159,6 +160,7 @@
     EntityAccessTest.class, //
     WritableReadableOrganizationClientTest.class, //
     StandardCrossOrganizationReference.class, //
+    BypassAccessLevelCheck.class, //
 
     // system
     SystemServiceTest.class, //
--- a/src-test/src/org/openbravo/test/datasource/DataSourceSecurity.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-test/src/org/openbravo/test/datasource/DataSourceSecurity.java	Mon May 09 09:57:27 2016 +0200
@@ -29,6 +29,7 @@
 import java.util.List;
 import java.util.Map;
 
+import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -74,6 +75,9 @@
   private static final String ID_TESTING = "11";
   private static final Object PROD_RESERVATION = "DA7FC1BB3BA44EC48EC1AB9C74168CED";
 
+  private static final String OPERATION_FETCH = "fetch";
+  private static final String OPERATION_UPDATE = "update";
+
   private RoleType role;
   private DataSource dataSource;
   private int expectedResponseStatus;
@@ -92,139 +96,235 @@
     }
   }
 
+  private enum JSONObjectURL {
+    // Move node in Account Tree
+    MOVEMENT_NODE(
+        "?_skinVersion=Default&_create=true&Constants_FIELDSEPARATOR=$&_new=true"
+            + "&_contextUrl=http://localhost:8080/openbravo&Constants_IDENTIFIER=_identifier"
+            + "&_startRow=0&_endRow=200&referencedTableId=188&parentRecordId=56E65CF592BD4DAF8A8A879810646266&tabId=132"
+            + "&_selectedProperties=['searchKey','name','elementLevel','accountType','showValueCondition','summaryLevel']"
+            + "&@FinancialMgmtElement.client@=23C59575B9CF467C9620760EB255B389"
+            + "&@FinancialMgmtElement.id@=56E65CF592BD4DAF8A8A879810646266"
+            + "&@FinancialMgmtElement.organization@=B843C30461EA4501935CB1D125C9C25A&@FinancialMgmtElement.type@=A"
+            + "&@FinancialMgmtElementValue.organization@=B843C30461EA4501935CB1D125C9C25A"
+            + "&@FinancialMgmtElementValue.client@=23C59575B9CF467C9620760EB255B389"
+            + "&@FinancialMgmtElementValue.accountingElement@=56E65CF592BD4DAF8A8A879810646266"
+            + "&@FinancialMgmtElementValue.id@=A45B7570F9BE4A69A3BF53CFEBB29FC0&dropIndex=2"
+            + "&nextNodeId=FF30CF29CE614360AF85020438BFE328&isc_dataFormat=json&prevNodeId=C3FE5804602E481FAEDCA5D4D71B6CF",
+        createJsonObjectForNodeMovement()), //
+    NO_APPLIED("", "");
+
+    private String url;
+    private String content;
+
+    private JSONObjectURL(String url, String content) {
+      this.url = url;
+      this.content = content;
+    }
+
+    private static String createJsonObjectForNodeMovement() {
+      JSONObject dataObject = new JSONObject();
+      JSONObject oldValuesJSON = new JSONObject();
+      JSONObject contentJson = new JSONObject();
+      try {
+        dataObject.put("_identifier", "P - PATRIMONIO NETO Y PASIVO");
+        dataObject.put("_entityName", "FinancialMgmtElementValue");
+        dataObject.put("$ref", "FinancialMgmtElementValue/C3FE5804602E481FAEDCA5D4D71B6CF3");
+        dataObject.put("id", "C3FE5804602E481FAEDCA5D4D71B6CF3");
+        dataObject.put("client", "23C59575B9CF467C9620760EB255B389");
+        dataObject.put("parentId", "-1");
+        dataObject.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        dataObject.put("searchKey", "A");
+        dataObject.put("accountingElement", "56E65CF592BD4DAF8A8A879810646266");
+        dataObject.put("nodeId", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        dataObject.put("seqno", "210");
+
+        oldValuesJSON.put("_identifier", "A - ACTIVO");
+        oldValuesJSON.put("_entityName", "FinancialMgmtElementValue");
+        oldValuesJSON.put("$ref", "FinancialMgmtElementValue/A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        oldValuesJSON.put("id", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+        oldValuesJSON.put("client", "23C59575B9CF467C9620760EB255B389");
+        oldValuesJSON.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        oldValuesJSON.put("organization", "B843C30461EA4501935CB1D125C9C25A");
+        oldValuesJSON.put("searchKey", "A");
+        oldValuesJSON.put("name", "ACTIVO");
+        oldValuesJSON.put("accountingElement", "56E65CF592BD4DAF8A8A879810646266");
+        oldValuesJSON.put("nodeId", "A45B7570F9BE4A69A3BF53CFEBB29FC0");
+
+        contentJson.put("dataSource",
+            "D2F94DC86DEC48D69E4BFCE59DC670CF_1462265510526_1462271742157");
+        contentJson.put("operationType", "update");
+        contentJson.put("data", dataObject);
+        contentJson.put("oldValues", oldValuesJSON);
+      } catch (JSONException e) {
+        e.printStackTrace();
+      }
+      return contentJson.toString();
+    }
+  }
+
   @SuppressWarnings("serial")
   private enum DataSource {
-    Order("Order"), //
-    Alert("DB9F062472294F12A0291A7BD203F922"), //
-    ProductByPriceAndWarehouse("ProductByPriceAndWarehouse", new HashMap<String, String>() {
-      {
-        try {
-          put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
-          put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
-          put("_sortBy", "_identifier");
-          put("_requestType", "Window");
-          put("_distinct", "productPrice");
+    Order("Order", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    Alert("DB9F062472294F12A0291A7BD203F922", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    ProductByPriceAndWarehouse("ProductByPriceAndWarehouse", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
+            try {
+              put("_selectorDefinitionId", "2E64F551C7C4470C80C29DBA24B34A5F");
+              put("filterClass", "org.openbravo.userinterface.selector.SelectorDataSourceFilter");
+              put("_sortBy", "_identifier");
+              put("_requestType", "Window");
+              put("_distinct", "productPrice");
 
-          // To reproduce this problem is important not to add the targetProperty parameter. For
-          // this reason targetProperty=null.
-          put("_inpTableId", "293");
-          put("_textMatchStyle", "substring");
+              // To reproduce this problem is important not to add the targetProperty parameter. For
+              // this reason targetProperty=null.
+              put("_inpTableId", "293");
+              put("_textMatchStyle", "substring");
 
-          // Filter selector
-          JSONObject criteria = new JSONObject();
-          criteria.put("fieldName", "productPrice$priceListVersion$_identifier");
-          criteria.put("operator", "iContains");
-          criteria.put("value", "Tarifa");
-          put("criteria", criteria.toString());
-        } catch (Exception ignore) {
-        }
-      }
-    }), //
-    PropertySelector("83B60C4C19AE4A9EBA947B948C5BA04D", new HashMap<String, String>() {
-      {
-        // Property selector invocation from Windows > Tab > Field > Property field
-        put("_selectorDefinitionId", "387D9FFC48A74054835C5DF6E6FD08F7");
-        put("inpadTableId", "259");
-        put("inpTabId", "107");
-        put("targetProperty", "property");
-      }
-    }), //
-    ManageVariants("6654D607F650425A9DFF7B6961D54920", new HashMap<String, String>() {
-      {
-        put("@Product.id@", ID_TESTING);
-      }
-    }), //
-    Note("090A37D22E61FE94012E621729090048", new HashMap<String, String>() {
-      {
-        // Note of a record in Windows, Tabs and Fields.
-        String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
-            + TABLE_WINDOWS_TABS_FIELDS_ID
-            + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
-            + RECORD_OF_WINDOWS_TABS_FIELDS_ID + "\"}";
-        String entityName = "OBUIAPP_Note";
-        put("criteria", criteria);
-        put("_entityName", entityName);
-      }
-    }), //
-    ProductCharacteristics("BE2735798ECC4EF88D131F16F1C4EC72"), //
-    Combo("ComboTableDatasourceService", new HashMap<String, String>() {
-      {
-        // Sales Order > Payment Terms
-        put("fieldId", "1099");
-      }
-    }), //
-    CustomQuerySelectorDatasource("F8DD408F2F3A414188668836F84C21AF",
+              // Filter selector
+              JSONObject criteria = new JSONObject();
+              criteria.put("fieldName", "productPrice$priceListVersion$_identifier");
+              criteria.put("operator", "iContains");
+              criteria.put("value", "Tarifa");
+              put("criteria", criteria.toString());
+            } catch (Exception ignore) {
+            }
+          }
+        }), //
+    PropertySelector("83B60C4C19AE4A9EBA947B948C5BA04D", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
         new HashMap<String, String>() {
           {
+            // Property selector invocation from Windows > Tab > Field > Property field
+            put("_selectorDefinitionId", "387D9FFC48A74054835C5DF6E6FD08F7");
+            put("inpadTableId", "259");
+            put("inpTabId", "107");
+            put("targetProperty", "property");
+          }
+        }), //
+    ManageVariants("6654D607F650425A9DFF7B6961D54920", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            put("@Product.id@", ID_TESTING);
+          }
+        }), //
+    Note("090A37D22E61FE94012E621729090048", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Note of a record in Windows, Tabs and Fields.
+            String criteria = "{\"fieldName\":\"table\",\"operator\":\"equals\",\"value\":\""
+                + TABLE_WINDOWS_TABS_FIELDS_ID
+                + "\"}__;__{\"fieldName\":\"record\",\"operator\":\"equals\",\"value\":\""
+                + RECORD_OF_WINDOWS_TABS_FIELDS_ID + "\"}";
+            String entityName = "OBUIAPP_Note";
+            put("criteria", criteria);
+            put("_entityName", entityName);
+          }
+        }), //
+    ProductCharacteristics("BE2735798ECC4EF88D131F16F1C4EC72", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH), //
+    Combo("ComboTableDatasourceService", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Sales Order > Payment Terms
+            put("fieldId", "1099");
+          }
+        }), //
+    CustomQuerySelectorDatasource("F8DD408F2F3A414188668836F84C21AF", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
             // Sales Invoice > Selector Business Partner
             put("_selectorDefinitionId", "862F54CB1B074513BD791C6789F4AA42");
             put("inpTableId", "318");
             put("targetProperty", "businessPartner");
           }
         }), //
-    CustomQuerySelectorDatasourceProcess("ADList", new HashMap<String, String>() {
-      {
-        // Sales Order > Add Payment process > Selector Action Regarding Document
-        put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
-        put("_processDefinitionId", "9BED7889E1034FE68BD85D5D16857320");
-        put("targetProperty", "businessPartner");
-      }
-    }), //
-    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E"), //
-    QuickCreate("C17951F970E942FD9F3771B7BE91D049"), //
-    HQLDataSource("3C1148C0AB604DE1B51B7EA4112C325F", new HashMap<String, String>() {
-      {
-        // Invocation from Sales Order > Add Payment process > Credit to Use.
-        put("tableId", "58AF4D3E594B421A9A7307480736F03E");
-      }
-    }), //
-    ADTree("90034CAE96E847D78FBEF6D38CB1930D", new HashMap<String, String>() {
-      {
-        // Organization tree view.
-        put("referencedTableId", "155");
-        put("tabId", "143");
-        String selectedPro = "[\"searchKey\",\"name\",\"description\",\"active\",\"summaryLevel\",\"socialName\",\"organizationType\",\"currency\",\"allowPeriodControl\",\"calendar\"]";
-        put("_selectedProperties", selectedPro);
-      }
-    }), //
-    AccountTree("D2F94DC86DEC48D69E4BFCE59DC670CF", new HashMap<String, String>() {
-      {
-        // Account tree > Element value > Open tree view.
-        put("referencedTableId", "188");
-        put("tabId", "132");
-        String selectedPro = "[\"searchKey\",\"name\",\"elementLevel\",\"accountType\",\"showValueCondition\",\"summaryLevel\"]";
-        put("_selectedProperties", selectedPro);
-        put("@FinancialMgmtElement.client@", CLIENT);
-        put("@FinancialMgmtElement.id@", "56E65CF592BD4DAF8A8A879810646266");
-        put("@FinancialMgmtElement.organization@", "B843C30461EA4501935CB1D125C9C25A");
-      }
-    }), //
-    StockReservations("2F5B70D7F12E4F5C8FE20D6F17D69ECF", new HashMap<String, String>() {
-      {
-        // Manage Stock from Stock Reservations
-        put("@MaterialMgmtReservation.id@", ID_TESTING);
-      }
-    }), //
-    QueryList("DD17275427E94026AD721067C3C91C18", new HashMap<String, String>() {
-      {
-        // Query List Widget > Best Sellers
-        put("widgetId", "CD1B06C4ED974B5F905A5A01B097DF4E");
-      }
-    });
+    CustomQuerySelectorDatasourceProcess("ADList", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Sales Order > Add Payment process > Selector Action Regarding Document
+            put("_selectorDefinitionId", "41B3A5EA61AB46FBAF4567E3755BA190");
+            put("_processDefinitionId", "9BED7889E1034FE68BD85D5D16857320");
+            put("targetProperty", "businessPartner");
+          }
+        }), //
+    SelectorGLItemDatasource("FinancialMgmtGLItem", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Payment In > Add Details process > GLItem section > Selector GLItem
+            put("_selectorDefinitionId", "9FAD469CE4414A25974CF45C0AD22D35");
+            put("inpTableId", "D1A97202E832470285C9B1EB026D54E2");
+            put("targetProperty", "gLItem");
+          }
+        }), //
+    QuickLaunch("99B9CC42FDEA4CA7A4EE35BC49D61E0E", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    QuickCreate("C17951F970E942FD9F3771B7BE91D049", JSONObjectURL.NO_APPLIED, OPERATION_FETCH), //
+    HQLDataSource("3C1148C0AB604DE1B51B7EA4112C325F", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Invocation from Sales Order > Add Payment process > Credit to Use.
+            put("tableId", "58AF4D3E594B421A9A7307480736F03E");
+          }
+        }), //
+    ADTree("90034CAE96E847D78FBEF6D38CB1930D", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Organization tree view.
+            put("referencedTableId", "155");
+            put("tabId", "143");
+            String selectedPro = "[\"searchKey\",\"name\",\"description\",\"active\",\"summaryLevel\",\"socialName\",\"organizationType\",\"currency\",\"allowPeriodControl\",\"calendar\"]";
+            put("_selectedProperties", selectedPro);
+          }
+        }), //
+    AccountTree("D2F94DC86DEC48D69E4BFCE59DC670CF", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Account tree > Element value > Open tree view.
+            put("referencedTableId", "188");
+            put("tabId", "132");
+            String selectedPro = "[\"searchKey\",\"name\",\"elementLevel\",\"accountType\",\"showValueCondition\",\"summaryLevel\"]";
+            put("_selectedProperties", selectedPro);
+            put("@FinancialMgmtElement.client@", CLIENT);
+            put("@FinancialMgmtElement.id@", "56E65CF592BD4DAF8A8A879810646266");
+            put("@FinancialMgmtElement.organization@", "B843C30461EA4501935CB1D125C9C25A");
+          }
+        }), //
+    StockReservations("2F5B70D7F12E4F5C8FE20D6F17D69ECF", JSONObjectURL.NO_APPLIED,
+        OPERATION_FETCH, new HashMap<String, String>() {
+          {
+            // Manage Stock from Stock Reservations
+            put("@MaterialMgmtReservation.id@", ID_TESTING);
+          }
+        }), //
+    QueryList("DD17275427E94026AD721067C3C91C18", JSONObjectURL.NO_APPLIED, OPERATION_FETCH,
+        new HashMap<String, String>() {
+          {
+            // Query List Widget > Best Sellers
+            put("widgetId", "CD1B06C4ED974B5F905A5A01B097DF4E");
+          }
+        }), //
+    AccountTreeMovement("D2F94DC86DEC48D69E4BFCE59DC670CF", JSONObjectURL.MOVEMENT_NODE,
+        OPERATION_UPDATE);
 
     private String ds;
+    private JSONObjectURL urlAndJson;
+    private String operation;
     private Map<String, String> params;
 
-    private DataSource(String ds) {
+    private DataSource(String ds, JSONObjectURL urlAndJson, String operation) {
       this.ds = ds;
+      this.urlAndJson = urlAndJson;
+      this.operation = operation;
+
       params = new HashMap<String, String>();
-      params.put("_operationType", "fetch");
+      params.put("_operationType", operation);
       params.put("_startRow", "0");
       params.put("_endRow", "1");
     }
 
-    private DataSource(String ds, Map<String, String> extraParams) {
-      this(ds);
+    private DataSource(String ds, JSONObjectURL urlAndJson, String operation,
+        Map<String, String> extraParams) {
+      this(ds, urlAndJson, operation);
       params.putAll(extraParams);
     }
   }
@@ -280,11 +380,14 @@
 
       // Note ds is accessible if current role has access to entity of the notes. This note is
       // invocated from a record in Windows, Tabs and Fields.
-      testCases.add(new Object[] {
-          type,
-          DataSource.Note,
-          type == RoleType.NO_ACCESS_ROLE ? JsonConstants.RPCREQUEST_STATUS_VALIDATION_ERROR
-              : JsonConstants.RPCREQUEST_STATUS_SUCCESS });
+      testCases.add(new Object[] { type, DataSource.Note, accessForAdminAndSystemOnly });
+
+      // Selector into a datasource into a P&E Window.
+      testCases.add(new Object[] { type, DataSource.SelectorGLItemDatasource,
+          accessForAdminAndSystemOnly });
+
+      // Moving a tree node : https://issues.openbravo.com/view.php?id=32833
+      testCases.add(new Object[] { type, DataSource.AccountTreeMovement, accessForAdminOnly });
     }
     // testing a problem detected in how properties are initialized.
     testCases.add(new Object[] { RoleType.ADMIN_ROLE, DataSource.ProductByPriceAndWarehouse,
@@ -365,10 +468,21 @@
   public void fetchShouldBeAllowedOnlyIfRoleIsGranted() throws Exception {
     OBContext.setOBContext(CONTEXT_USER);
     changeProfile(role.roleId, LANGUAGE_ID, role.orgId, WAREHOUSE_ID);
+
     JSONObject jsonResponse = null;
-    jsonResponse = fetchDataSource();
+    if (dataSource.operation.equals(OPERATION_FETCH)) {
+      jsonResponse = fetchDataSource();
+    } else if (dataSource.operation.equals(OPERATION_UPDATE)) {
+      jsonResponse = updateDataSource();
+    }
     assertThat("Request status", jsonResponse.getInt("status"), is(expectedResponseStatus));
+  }
 
+  private JSONObject updateDataSource() throws Exception {
+    String responseUpdate = doRequest("/org.openbravo.service.datasource/" + dataSource.ds
+        + dataSource.urlAndJson.url, dataSource.urlAndJson.content, 200, "PUT", "application/json");
+
+    return new JSONObject(responseUpdate).getJSONObject("response");
   }
 
   private JSONObject fetchDataSource() throws Exception {
--- a/src-test/src/org/openbravo/test/datasource/TestInitializeAccess.java	Fri Apr 29 14:59:04 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,320 +0,0 @@
-/*
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html
- * Software distributed under the License  is  distributed  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License.
- * The Original Code is Openbravo ERP.
- * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2016 Openbravo SLU
- * All Rights Reserved.
- * Contributor(s):  ______________________________________.
- ************************************************************************
- */
-
-package org.openbravo.test.datasource;
-
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertThat;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.criterion.Restrictions;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.openbravo.base.model.Entity;
-import org.openbravo.base.provider.OBProvider;
-import org.openbravo.dal.core.OBContext;
-import org.openbravo.dal.service.OBCriteria;
-import org.openbravo.dal.service.OBDal;
-import org.openbravo.model.ad.access.Role;
-import org.openbravo.model.ad.access.RoleOrganization;
-import org.openbravo.model.ad.access.UserRoles;
-import org.openbravo.model.ad.access.WindowAccess;
-import org.openbravo.model.ad.ui.Window;
-import org.openbravo.model.common.enterprise.Organization;
-import org.openbravo.test.base.OBBaseTest;
-
-/**
- * Test cases to ensure that initialize method of EntityAccessChecker is working properly.
- *
- * @author inigo.sanchez
- *
- *         BaseDataSourceTestDal
- */
-@RunWith(Parameterized.class)
-public class TestInitializeAccess extends OBBaseTest {
-  private static final String ASTERISK_ORG_ID = "0";
-  private static final String CONTEXT_USER = "100";
-  private static final String LANGUAGE_ID = "192";
-  private static final String WAREHOUSE_ID = "B2D40D8A5D644DD89E329DC297309055";
-  private static final String ROLE_INTERNATIONAL_ADMIN = "42D0EEB1C66F497A90DD526DC597E6F0";
-  private static final String ROLE_ACCESS_FINANCIAL_ACCOUNT = "1";
-  private static final String ROLE_SYSTEM_ADMIN = "0";
-  private static final String ESP_ORG = "E443A31992CB4635AFCAEABE7183CE85";
-  private static final String FINANCIAL_ACCOUNT_WINDOW = "94EAA455D2644E04AB25D93BE5157B6D";
-  private static final String CLIENT_ID_INT = "23C59575B9CF467C9620760EB255B389";
-
-  private static final String TABLE_WINDOWS_TABS_FIELDS_ID = "105";
-  private static final String RECORD_OF_WINDOWS_TABS_FIELDS_ID = "283";
-
-  private RoleType role;
-  private int expectedResponseStatus;
-
-  private enum RoleType {
-    FIN_ACC_ROLE(ROLE_ACCESS_FINANCIAL_ACCOUNT, ESP_ORG);
-
-    private String roleId;
-    private String orgId;
-
-    private RoleType(String roleId, String orgId) {
-      this.roleId = roleId;
-      this.orgId = orgId;
-    }
-  }
-
-  @SuppressWarnings("serial")
-  private HashMap<String, String> expectedPermissions = new HashMap<String, String>() {
-    {
-
-      put("APRM_FinAcc_Transaction_acct_v", "Readable");
-      put("APRM_Finacc_Transaction_v", "Readable");
-      put("APRM_Finacc_Trx_Full_Acct_V", "Readable");
-      put("APRM_Reconciliation", "Readable");
-      put("Aprm_Credit_To_Use", "Readable");
-      put("CurrencyConversionRateDoc", "Readable");
-      put("FIN_BankStatement", "Readable");
-      put("FIN_BankStatementLine", "Readable");
-      put("FIN_Finacc_Transaction", "Readable");
-      put("FIN_Financial_Account", "Readable");
-      put("FIN_Financial_Account_Acct", "Readable");
-      put("FIN_Payment", "Readable");
-      put("FIN_Reconciliation", "Readable");
-      put("FIN_ReconciliationLine_v", "Readable");
-      put("FinancialMgmtFinAccPaymentMethod", "Readable");
-      put("aprm_gl_item", "Readable");
-      put("aprm_matchstatement", "Readable");
-      put("aprm_orderinvoice", "Readable");
-      put("aprm_transactiontomatch", "Readable");
-
-      put("ADClient", "DerivedReadable");
-      put("ADTable", "DerivedReadable");
-      put("ADUser", "DerivedReadable");
-      put("BusinessPartner", "DerivedReadable");
-      put("Costcenter", "DerivedReadable");
-      put("Country", "DerivedReadable");
-      put("Currency", "DerivedReadable");
-      put("DocumentType", "DerivedReadable");
-      // put("FIN_Payment1", "DerivedReadable");
-      put("FIN_PaymentMethod", "DerivedReadable");
-      put("FIN_Payment_Detail_V", "DerivedReadable");
-      put("FIN_Payment_Proposal", "DerivedReadable");
-      put("FIN_Payment_Sched_Inv_V", "DerivedReadable");
-      put("FIN_Payment_Sched_Ord_V", "DerivedReadable");
-      put("FIN_ReconciliationLineTemp", "DerivedReadable");
-      put("FinancialMgmtAccountingCombination", "DerivedReadable");
-      put("FinancialMgmtAcctSchema", "DerivedReadable");
-      put("FinancialMgmtAsset", "DerivedReadable");
-      put("FinancialMgmtBankFileException", "DerivedReadable");
-      put("FinancialMgmtBankFileFormat", "DerivedReadable");
-      put("FinancialMgmtElementValue", "DerivedReadable");
-      put("FinancialMgmtGLCategory", "DerivedReadable");
-      put("FinancialMgmtGLItem", "DerivedReadable");
-      put("FinancialMgmtGLJournal", "DerivedReadable");
-      put("FinancialMgmtGLJournalLine", "DerivedReadable");
-      put("FinancialMgmtMatchingAlgorithm", "DerivedReadable");
-      put("FinancialMgmtPaymentExecutionProcess", "DerivedReadable");
-      put("FinancialMgmtPeriod", "DerivedReadable");
-      put("FinancialMgmtTaxCategory", "DerivedReadable");
-      put("FinancialMgmtTaxRate", "DerivedReadable");
-      put("FinancialMgmtWithholding", "DerivedReadable");
-      put("Invoice", "DerivedReadable");
-      put("Location", "DerivedReadable");
-      put("Locator", "DerivedReadable");
-      put("MarketingCampaign", "DerivedReadable");
-      put("MaterialMgmtABCActivity", "DerivedReadable");
-      put("Order", "DerivedReadable");
-      put("Organization", "DerivedReadable");
-      put("Product", "DerivedReadable");
-      put("Project", "DerivedReadable");
-      put("Region", "DerivedReadable");
-      put("SalesRegion", "DerivedReadable");
-      put("UOM", "DerivedReadable");
-      put("UserDimension1", "DerivedReadable");
-      put("UserDimension2", "DerivedReadable");
-
-      put("ADList", "DerivedProcess");
-
-      /*
-       * 2120369 [http-8080-3] INFO org.openbravo.dal.security.EntityAccessChecker - Add Multiple
-       * Payments 2120369 [http-8080-3] INFO org.openbravo.dal.security.EntityAccessChecker - Add
-       * Payment 2120369 [http-8080-3] INFO org.openbravo.dal.security.EntityAccessChecker - Add
-       * Transaction 2120369 [http-8080-3] INFO org.openbravo.dal.security.EntityAccessChecker -
-       * Find Transactions to Match 2120369 [http-8080-3] INFO
-       * org.openbravo.dal.security.EntityAccessChecker - Match Statement
-       */
-    }
-  };
-
-  public TestInitializeAccess(RoleType role) {
-    this.role = role;
-  }
-
-  @Parameters(name = "{0} - dataSource: {1}")
-  public static Collection<Object[]> parameters() {
-    List<Object[]> testCases = new ArrayList<Object[]>();
-
-    // testing a problem detected in how properties are initialized.
-    testCases.add(new Object[] { RoleType.FIN_ACC_ROLE });
-    return testCases;
-  }
-
-  /** Creates dummy role with access to Financial Account window for testing purposes */
-  @BeforeClass
-  public static void createRoleWithAccesFinancialAccount() {
-    OBContext.setOBContext(CONTEXT_USER);
-
-    Role noAccessRole = OBProvider.getInstance().get(Role.class);
-    noAccessRole.setId("1");
-    noAccessRole.setNewOBObject(true);
-    noAccessRole.setOrganization(OBDal.getInstance().get(Organization.class, ASTERISK_ORG_ID));
-    noAccessRole.setName("Test Access FA");
-    noAccessRole.setManual(true);
-    noAccessRole.setUserLevel(" CO");
-    noAccessRole.setClientList(OBContext.getOBContext().getCurrentClient().getId());
-    noAccessRole.setOrganizationList(ASTERISK_ORG_ID);
-    OBDal.getInstance().save(noAccessRole);
-
-    RoleOrganization noAcessRoleOrg = OBProvider.getInstance().get(RoleOrganization.class);
-    noAcessRoleOrg.setOrganization((Organization) OBDal.getInstance().getProxy(
-        Organization.ENTITY_NAME, ESP_ORG));
-    noAcessRoleOrg.setRole(noAccessRole);
-    OBDal.getInstance().save(noAcessRoleOrg);
-
-    UserRoles noAccessRoleUser = OBProvider.getInstance().get(UserRoles.class);
-    noAccessRoleUser.setOrganization(noAccessRole.getOrganization());
-    noAccessRoleUser.setUserContact(OBContext.getOBContext().getUser());
-    noAccessRoleUser.setRole(noAccessRole);
-    OBDal.getInstance().save(noAccessRoleUser);
-
-    // ****
-    final WindowAccess windowAccess = OBProvider.getInstance().get(WindowAccess.class);
-    final OBCriteria<Window> obCriteria = OBDal.getInstance().createCriteria(Window.class);
-    obCriteria.add(Restrictions.eq(Window.PROPERTY_ID, FINANCIAL_ACCOUNT_WINDOW));
-    obCriteria.setMaxResults(1);
-    windowAccess.setClient(OBContext.getOBContext().getCurrentClient());
-    windowAccess.setOrganization(OBDal.getInstance().get(Organization.class, ASTERISK_ORG_ID));
-    windowAccess.setRole(OBDal.getInstance().get(Role.class, ROLE_ACCESS_FINANCIAL_ACCOUNT));
-    windowAccess.setWindow((Window) obCriteria.uniqueResult());
-    windowAccess.setEditableField(true);
-    OBDal.getInstance().save(windowAccess);
-    OBDal.getInstance().flush();
-    // ****
-    // WindowAccess windowAccess = OBProvider.getInstance().get(WindowAccess.class);
-    // windowAccess.setId(FINANCIAL_ACCOUNT_WINDOW);
-    // windowAccess.setNewOBObject(true);
-    // windowAccess.setWindow(OBDal.getInstance().get(Window.class, FINANCIAL_ACCOUNT_WINDOW));
-    // windowAccess.setEditableField(true);
-    // OBDal.getInstance().save(windowAccess);
-
-    OBDal.getInstance().commitAndClose();
-  }
-
-  /** Tests datasource allows or denies fetch action based on role access */
-  @Test
-  public void calculatePermissionsForRole() throws Exception {
-    OBContext.setOBContext(CONTEXT_USER, ROLE_ACCESS_FINANCIAL_ACCOUNT, CLIENT_ID_INT,
-        ASTERISK_ORG_ID);
-
-    final OBContext obContext = OBContext.getOBContext();
-    // OBContext.setOBContext(CONTEXT_USER, role.roleId, "0", role.orgId);
-    obContext.getEntityAccessChecker().dump();
-    int numberOfWritable = obContext.getEntityAccessChecker().getWritableEntities().size();
-    int numberOfReadable = obContext.getEntityAccessChecker().getReadableEntities().size();
-    int numberOfDerivedReadable = obContext.getEntityAccessChecker().getDerivedReadableEntities()
-        .size();
-    int numberOfDerivedFromProcess = obContext.getEntityAccessChecker()
-        .getDerivedEntitiesFromProcess().size();
-    int totalPermissions = numberOfWritable + numberOfDerivedReadable + numberOfDerivedFromProcess;
-
-    assertThat("Total of permissions", totalPermissions, is(expectedPermissions.size()));
-    assertThat("Readable and Writable number of permissions", numberOfWritable,
-        is(numberOfReadable));
-
-    // Writable and Readable
-    List<Entity> calculatedEntities = new ArrayList<Entity>(obContext.getEntityAccessChecker()
-        .getWritableEntities());
-    ArrayList<String> calculatedEntitiesList = new ArrayList<String>();
-
-    Iterator<Entity> et = calculatedEntities.iterator();
-    while (et.hasNext()) {
-      calculatedEntitiesList.add(et.next().getName());
-    }
-
-    for (Map.Entry<String, String> entry : expectedPermissions.entrySet()) {
-      if (entry.getValue().equals("Readable") && calculatedEntitiesList.contains(entry.getKey())) {
-        numberOfWritable--;
-      }
-    }
-
-    // Derived
-    calculatedEntities = new ArrayList<Entity>(obContext.getEntityAccessChecker()
-        .getDerivedReadableEntities());
-    calculatedEntitiesList = new ArrayList<String>();
-
-    et = calculatedEntities.iterator();
-    while (et.hasNext()) {
-      calculatedEntitiesList.add(et.next().getName());
-    }
-    for (Map.Entry<String, String> entry : expectedPermissions.entrySet()) {
-      if (entry.getValue().equals("DerivedReadable")
-          && calculatedEntitiesList.contains(entry.getKey())) {
-        numberOfDerivedReadable--;
-      }
-    }
-
-    // Derived from process
-    calculatedEntities = new ArrayList<Entity>(obContext.getEntityAccessChecker()
-        .getDerivedEntitiesFromProcess());
-    calculatedEntitiesList = new ArrayList<String>();
-
-    et = calculatedEntities.iterator();
-    while (et.hasNext()) {
-      calculatedEntitiesList.add(et.next().getName());
-    }
-    for (Map.Entry<String, String> entry : expectedPermissions.entrySet()) {
-      if (entry.getValue().equals("DerivedProcess")
-          && calculatedEntitiesList.contains(entry.getKey())) {
-        numberOfDerivedFromProcess--;
-      }
-    }
-
-    // If there is more permissions than 0 permissions are not calculated properly.
-    assertThat("Readable and Writable permissions", numberOfWritable, is(0));
-    assertThat("Derived permissions", numberOfDerivedReadable, is(0));
-    assertThat("Derived from process permissions", numberOfDerivedFromProcess, is(0));
-
-  }
-
-  /** Deletes dummy testing role */
-  @AfterClass
-  public static void cleanUp() {
-    OBContext.setOBContext(CONTEXT_USER);
-    OBDal.getInstance().remove(OBDal.getInstance().get(Role.class, ROLE_ACCESS_FINANCIAL_ACCOUNT));
-    OBDal.getInstance().commitAndClose();
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/security/BypassAccessLevelCheck.java	Mon May 09 09:57:27 2016 +0200
@@ -0,0 +1,93 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html 
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU 
+ * All portions are Copyright (C) 2016 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+
+package org.openbravo.test.security;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.greaterThan;
+import static org.junit.Assert.assertThat;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.openbravo.base.exception.OBSecurityException;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBCriteria;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.ad.access.Role;
+import org.openbravo.model.common.currency.Currency;
+import org.openbravo.test.base.OBBaseTest;
+
+/**
+ * By default access level in entity and role is checked preventing reading data if role's user
+ * level is Organization and the entity trying to be accessed is Client or System. These checks can
+ * be bypassed.
+ * 
+ * @author alostale
+ *
+ */
+public class BypassAccessLevelCheck extends OBBaseTest {
+  private static String ORG_LEVEL_ROLE;
+  private static final String CURRENCY_WINDOW = "115";
+  private static final String SPAIN_ORG = "357947E87C284935AD1D783CF6F099A1";
+
+  @Rule
+  public ExpectedException exception = ExpectedException.none();
+
+  @BeforeClass
+  public static void createOrgLevelRole() {
+    Role role = ExplicitCrossOrganizationReference.createOrgUserLevelRole();
+    ORG_LEVEL_ROLE = role.getId();
+    ExplicitCrossOrganizationReference.grantWindowAccess(role, CURRENCY_WINDOW);
+
+    OBDal.getInstance().commitAndClose();
+  }
+
+  /** By default Org level roles cannot see data in System level entities */
+  @Test
+  public void orgLevelShouldntGrantAccessToSystemEntity() {
+    OBContext.setOBContext("100", ORG_LEVEL_ROLE, QA_TEST_CLIENT_ID, SPAIN_ORG);
+
+    assertThat("doOrgClientAccessCheck", OBContext.getOBContext().doOrgClientAccessCheck(),
+        is(true));
+
+    exception.expect(OBSecurityException.class);
+    exception.expectMessage(containsString("Entity Currency is not readable"));
+
+    OBDal.getInstance().createCriteria(Currency.class);
+  }
+
+  /** Default behavior of for access level check can be bypassed */
+  @Test
+  public void orgLevelCanAccessEntityAccessIfEnabled() {
+    OBContext.setOBContext("100", ORG_LEVEL_ROLE, QA_TEST_CLIENT_ID, SPAIN_ORG);
+    OBContext.getOBContext().setCheckAccessLevel(false);
+    OBCriteria<Currency> q = OBDal.getInstance().createCriteria(Currency.class);
+
+    assertThat("Visible currencies", q.count(), is(greaterThan(0)));
+  }
+
+  @AfterClass
+  public static void cleanUpCreatedObjects() {
+    CrossOrganizationReference.removeCreatedObjects();
+  }
+}
--- a/src-test/src/org/openbravo/test/security/CrossOrganizationReference.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-test/src/org/openbravo/test/security/CrossOrganizationReference.java	Mon May 09 09:57:27 2016 +0200
@@ -182,6 +182,7 @@
         OBDal.getInstance().flush();
       }
       OBDal.getInstance().commitAndClose();
+      createdObjects.clear();
     } catch (Exception ignore) {
     } finally {
       OBContext.restorePreviousMode();
--- a/src-test/src/org/openbravo/test/security/ExplicitCrossOrganizationReference.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src-test/src/org/openbravo/test/security/ExplicitCrossOrganizationReference.java	Mon May 09 09:57:27 2016 +0200
@@ -64,6 +64,7 @@
  *
  */
 public class ExplicitCrossOrganizationReference extends CrossOrganizationReference {
+  private static final String SALES_ORDER_WINDOW = "143";
   private static String QA_ONLY_SPAIN_ROLE;
   private static final String CORE = "0";
   private static final String ORDER_WAREHOUSE_COLUMN = "2202";
@@ -489,7 +490,15 @@
     DalLayerInitializer.getInstance().setInitialized(false);
     setDalUp();
 
-    // create a role with access only to Spain org
+    Role qaRole = createOrgUserLevelRole();
+    QA_ONLY_SPAIN_ROLE = qaRole.getId();
+    grantWindowAccess(qaRole, SALES_ORDER_WINDOW);
+
+    OBDal.getInstance().commitAndClose();
+  }
+
+  /** Creates a role with Org user level, and access to Spain Org */
+  static Role createOrgUserLevelRole() {
     setQAAdminRole();
     Role spainRole = OBProvider.getInstance().get(Role.class);
     spainRole.setName("QA Only Spain - " + System.currentTimeMillis()); // some randomness
@@ -500,21 +509,6 @@
     spainRole.setUserLevel("  O");
     OBDal.getInstance().save(spainRole);
     createdObjects.add(spainRole);
-    QA_ONLY_SPAIN_ROLE = spainRole.getId();
-
-    // create a window access for previous role
-    Role role = OBDal.getInstance().get(Role.class, QA_ONLY_SPAIN_ROLE);
-    WindowAccess windowAccess = OBProvider.getInstance().get(WindowAccess.class);
-    final OBCriteria<Window> obCriteria = OBDal.getInstance().createCriteria(Window.class);
-    obCriteria.add(Restrictions.eq(Window.PROPERTY_ID, "143"));
-    obCriteria.setMaxResults(1);
-    windowAccess.setClient(role.getClient());
-    windowAccess.setOrganization(role.getOrganization());
-    windowAccess.setRole(role);
-    windowAccess.setWindow((Window) obCriteria.uniqueResult());
-    windowAccess.setEditableField(true);
-    OBDal.getInstance().save(windowAccess);
-    createdObjects.add(windowAccess);
 
     RoleOrganization orgAccess = OBProvider.getInstance().get(RoleOrganization.class);
     orgAccess.setOrganization(OBDal.getInstance().getProxy(Organization.class, SPAIN_ORG));
@@ -529,7 +523,21 @@
     OBDal.getInstance().save(userRole);
     createdObjects.add(userRole);
 
-    OBDal.getInstance().commitAndClose();
+    return spainRole;
+  }
+
+  static void grantWindowAccess(Role role, String windowId) {
+    WindowAccess windowAccess = OBProvider.getInstance().get(WindowAccess.class);
+    final OBCriteria<Window> obCriteria = OBDal.getInstance().createCriteria(Window.class);
+    obCriteria.add(Restrictions.eq(Window.PROPERTY_ID, windowId));
+    obCriteria.setMaxResults(1);
+    windowAccess.setClient(role.getClient());
+    windowAccess.setOrganization(role.getOrganization());
+    windowAccess.setRole(role);
+    windowAccess.setWindow((Window) obCriteria.uniqueResult());
+    windowAccess.setEditableField(true);
+    OBDal.getInstance().save(windowAccess);
+    createdObjects.add(windowAccess);
   }
 
   @AfterClass
--- a/src/index.jsp	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/index.jsp	Mon May 09 09:57:27 2016 +0200
@@ -13,6 +13,13 @@
 <%@ page import="org.openbravo.model.ad.access.User" %>
 <%@ page import="org.openbravo.dal.service.OBDal" %>
 <%@ page import="org.openbravo.base.secureApp.VariablesSecureApp" %>
+<%@ page import="org.openbravo.erpCommon.obps.ActivationKey" %>
+<%@ page import="org.openbravo.base.secureApp.LoginHandler" %>
+<%@ page import="org.openbravo.base.HttpBaseUtils" %>
+<%@ page import="org.openbravo.erpCommon.utility.OBMessageUtils" %>
+<%@ page import="org.openbravo.erpCommon.utility.OBError" %>
+<%@ page import="java.util.Date" %>
+<%@ page import="org.openbravo.erpCommon.obps.ActivationKey.LicenseRestriction" %>
 <%@ page contentType="text/html; charset=UTF-8" %>
 <%
   /*
@@ -44,6 +51,41 @@
   return;
 }
 
+OBContext.setAdminMode(false);
+String sessionId = null;
+try {
+  sessionId = (String) session.getAttribute("#AD_SESSION_ID");
+  if (sessionId != null && !"".equals(sessionId) && !"Y".equals(session.getAttribute("forceLogin"))) {
+    org.openbravo.model.ad.access.Session dbSession = OBDal.getInstance().get(org.openbravo.model.ad.access.Session.class, sessionId);
+    String currentSessionType = dbSession.getLoginStatus();
+
+    if (!ActivationKey.consumesConcurrentUser(currentSessionType)) {
+      // session was created not counting concurrent users, now switching to backend so they
+      // should be counted
+      dbSession.setLoginStatus(LoginHandler.SUCCESS_SESSION_STANDARD);
+      OBDal.getInstance().flush();
+
+      if (ActivationKey.getInstance().checkOPSLimitations(sessionId) == LicenseRestriction.NUMBER_OF_CONCURRENT_USERS_REACHED) {
+        dbSession.setSessionActive(false);
+        OBDal.getInstance().flush();
+
+        OBError errMsg = new OBError();
+        errMsg.setTitle(OBMessageUtils.messageBD("NUMBER_OF_CONCURRENT_USERS_REACHED_TITLE", false, true));
+        errMsg.setMessage(OBMessageUtils.messageBD("NUMBER_OF_CONCURRENT_USERS_REACHED", false, true));
+        session.setAttribute("LOGINERRORMSG", errMsg);
+
+        response.sendRedirect(authManager.getLoginURL(request));
+        return;
+      }
+    }
+  }
+} catch (Exception e) {
+  log.error("Error resetting login status for session "  + sessionId,e);
+} finally {
+  OBContext.restorePreviousMode();
+}
+
+
 boolean uncompSC = false;
 String scDevModulePackage = "org.openbravo.userinterface.smartclient.dev";
 OBContext.setAdminMode();
--- a/src/org/openbravo/authentication/AuthenticationManager.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/authentication/AuthenticationManager.java	Mon May 09 09:57:27 2016 +0200
@@ -1,6 +1,6 @@
 /*
  ************************************************************************************
- * Copyright (C) 2001-2013 Openbravo S.L.U.
+ * Copyright (C) 2001-2016 Openbravo S.L.U.
  * Licensed under the Apache Software License version 2.0
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  * Unless required by applicable law or agreed to  in writing,  software  distributed
@@ -12,6 +12,8 @@
 
 package org.openbravo.authentication;
 
+import static org.openbravo.base.secureApp.LoginHandler.SUCCESS_SESSION_STANDARD;
+
 import java.io.IOException;
 import java.io.PrintWriter;
 
@@ -52,7 +54,6 @@
   private static final Logger log4j = Logger.getLogger(AuthenticationManager.class);
   private static final String DEFAULT_AUTH_CLASS = "org.openbravo.authentication.basic.DefaultAuthenticationManager";
 
-  private static final String SUCCESS_SESSION_STANDARD = "S";
   private static final String SUCCESS_SESSION_WEB_SERVICE = "WS";
   private static final String REJECTED_SESSION_WEB_SERVICE = "WSR";
   private static final String SUCCESS_SESSION_CONNECTOR = "WSC";
@@ -151,19 +152,22 @@
       return null;
     }
 
+    if (userId == null && !response.isCommitted()) {
+      response.sendRedirect(getLoginURL(request));
+      return null;
+    }
+
+    return userId;
+  }
+
+  /** Returns the URL that displays the login window (request for user/password) */
+  public String getLoginURL(HttpServletRequest request) {
     // A restricted resource can define a custom login URL
     // It just need to set an the attribute loginURL in the request
     final String customLoginURL = (String) request.getAttribute("loginURL");
 
-    final String loginURL = localAdress
+    return localAdress
         + (customLoginURL == null || "".equals(customLoginURL) ? defaultServletUrl : customLoginURL);
-
-    if (userId == null && !response.isCommitted()) {
-      response.sendRedirect(loginURL);
-      return null;
-    }
-
-    return userId;
   }
 
   /**
--- a/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/base/secureApp/HttpSecureAppServlet.java	Mon May 09 09:57:27 2016 +0200
@@ -432,12 +432,16 @@
         UsageAudit.auditActionNoDal(this, vars1, this.getClass().getName(),
             System.currentTimeMillis() - t);
       } else {
-        if ((strPopUp != null && !strPopUp.equals("")) || (classInfo.type.equals("S")))
+        if ((strPopUp != null && !strPopUp.equals("")) || classInfo.type.equals("S")) {
           bdErrorGeneralPopUp(request, response,
               Utility.messageBD(this, "Error", variables.getLanguage()),
               Utility.messageBD(this, "AccessTableNoView", variables.getLanguage()));
-        else
+        } else {
           bdError(request, response, "AccessTableNoView", vars1.getLanguage());
+        }
+        String roleStr = "".equals(vars1.getRole()) ? "" : " (" + vars1.getRole() + ")";
+        log4j
+            .warn("Role" + roleStr + " tried to access ungranted resource with ID " + classInfo.id);
       }
     } catch (final ServletException ex) {
       log4j.error("Error captured: ", ex);
@@ -528,6 +532,10 @@
    * 
    */
   private boolean hasLevelAccess(VariablesSecureApp vars, String accessLevel) {
+    if (!OBContext.getOBContext().doAccessLevelCheck()) {
+      return true;
+    }
+
     final String userLevel = vars.getSessionValue("#User_Level");
 
     boolean retValue = true;
--- a/src/org/openbravo/base/secureApp/LoginHandler.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/base/secureApp/LoginHandler.java	Mon May 09 09:57:27 2016 +0200
@@ -63,6 +63,7 @@
  */
 public class LoginHandler extends HttpBaseServlet {
   private static final long serialVersionUID = 1L;
+  public static final String SUCCESS_SESSION_STANDARD = "S";
 
   @Inject
   private ServerControllerHandler serverController;
@@ -197,7 +198,7 @@
       boolean forceNamedUserLogin = "FORCE_NAMED_USER".equals(vars.getCommand());
 
       LicenseRestriction limitation = ak.checkOPSLimitations(sessionId, username,
-          forceNamedUserLogin);
+          forceNamedUserLogin, getSessionType());
       boolean doRedirect = redirect
           || (limitation == LicenseRestriction.NO_RESTRICTION && forceNamedUserLogin);
 
@@ -395,6 +396,11 @@
 
   }
 
+  /** Returns how the successful session will be marked in ad_session. It can be app specific. */
+  protected String getSessionType() {
+    return SUCCESS_SESSION_STANDARD;
+  }
+
   /**
    * Returns true if the access to the current login handler should be restricted in the store
    * servers
--- a/src/org/openbravo/base/secureApp/LoginUtils.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/base/secureApp/LoginUtils.java	Mon May 09 09:57:27 2016 +0200
@@ -32,6 +32,7 @@
 import org.openbravo.erpCommon.businessUtility.Preferences;
 import org.openbravo.erpCommon.security.SessionLogin;
 import org.openbravo.erpCommon.utility.DimensionDisplayUtility;
+import org.openbravo.erpCommon.utility.PropertyException;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.access.RoleOrganization;
 import org.openbravo.model.ad.domain.Preference;
@@ -209,6 +210,18 @@
       return false;
     }
 
+    boolean shouldCheckAccessLevel = true;
+
+    try {
+      shouldCheckAccessLevel = "N".equals(Preferences.getPreferenceValue(
+          "BypassAccessLevelEntityCheck", true, OBContext.getOBContext().getCurrentClient(),
+          OBContext.getOBContext().getCurrentOrganization(), OBContext.getOBContext().getUser(),
+          OBContext.getOBContext().getRole(), null));
+    } catch (PropertyException prefNotDefined) {
+    }
+
+    OBContext.getOBContext().setCheckAccessLevel(shouldCheckAccessLevel);
+
     // Set session vars
     vars.setSessionValue("#AD_User_ID", strUserAuth);
     vars.setSessionValue("#SalesRep_ID", strUserAuth);
--- a/src/org/openbravo/dal/core/OBContext.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/dal/core/OBContext.java	Mon May 09 09:57:27 2016 +0200
@@ -573,6 +573,8 @@
   // check whether using new or old UI
   private boolean newUI = false;
 
+  private boolean checkAccessLevel = true;
+
   public String getUserLevel() {
     return userLevel;
   }
@@ -1111,6 +1113,19 @@
     return !(adminModeSet.get() != null || isAdministrator);
   }
 
+  /**
+   * Defines whether entity check should or not compare entity's access level with role's user level
+   * in order to completely prevent access to that entity.
+   */
+  public boolean doAccessLevelCheck() {
+    return checkAccessLevel;
+  }
+
+  /** @see OBContext#doAccessLevelCheck() */
+  public void setCheckAccessLevel(boolean checkAccessLevel) {
+    this.checkAccessLevel = checkAccessLevel;
+  }
+
   public boolean isAdminContext() {
     return this == adminContext;
   }
--- a/src/org/openbravo/dal/core/OBInterceptor.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/dal/core/OBInterceptor.java	Mon May 09 09:57:27 2016 +0200
@@ -298,8 +298,8 @@
             && bob.getEntity().getProperty(propertyNames[i]).isAllowedCrossOrgReference();
 
         if (!skipCrossOrgCheck
-            && !obContext.getOrganizationStructureProvider(o1.getClient().getId()).isInNaturalTree(
-                o1, o2)) {
+            && !obContext.getOrganizationStructureProvider((String) DalUtil.getId(o1.getClient()))
+                .isInNaturalTree(o1, o2)) {
           throw new OBSecurityException("Entity " + bob.getIdentifier() + " ("
               + bob.getEntityName() + ") with organization " + o1.getIdentifier()
               + " references an entity " + ((BaseOBObject) currentState[i]).getIdentifier()
--- a/src/org/openbravo/dal/security/EntityAccessChecker.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/dal/security/EntityAccessChecker.java	Mon May 09 09:57:27 2016 +0200
@@ -266,6 +266,10 @@
    */
   private boolean hasCorrectAccessLevel(String userLevel, int accessLevel) {
     // copied from HttpSecureAppServlet.
+    if (!OBContext.getOBContext().doAccessLevelCheck()) {
+      return true;
+    }
+
     if (accessLevel == 4 && userLevel.indexOf("S") == -1) {
       return false;
     } else if (accessLevel == 1 && userLevel.indexOf("O") == -1) {
@@ -339,8 +343,13 @@
 
   private void dumpSortedProcess(Set<String> set) {
     final List<String> names = new ArrayList<String>();
-    for (final String p : set) {
-      names.add(OBDal.getInstance().get(Process.class, p).getName());
+    OBContext.setAdminMode(true);
+    try {
+      for (final String p : set) {
+        names.add(OBDal.getInstance().get(Process.class, p).getName());
+      }
+    } finally {
+      OBContext.restorePreviousMode();
     }
     Collections.sort(names);
     for (final String n : names) {
@@ -573,15 +582,7 @@
     if (processes.isEmpty()) {
       return;
     }
-    StringBuilder processesInList = new StringBuilder();
-    boolean first = true;
-    for (String p : processes) {
-      if (!first) {
-        processesInList.append(", ");
-      }
-      first = false;
-      processesInList.append("'").append(p).append("'");
-    }
+    String processesInList = createWhereInCondition(processes);
 
     String hql = "select p.referenceSearchKey from OBUIAPP_Parameter p where p.reference.id in('"
         + WINDOW_REFERENCE + "','" + SELECTOR_REFERENCE + "') and p.obuiappProcess.id in ("
@@ -637,7 +638,9 @@
    * Obtain entities from window and added to readable and writable entities.
    */
   private void addEntitiesOfWindowReference(ModelProvider mp, Window window) {
+    Set<String> tabs = new HashSet<String>();
     for (Tab tab : window.getADTabList()) {
+      tabs.add((String) DalUtil.getId(tab));
       final Entity derivedEntity = mp.getEntityByTableId((String) DalUtil.getId(tab.getTable()));
       if (!writableEntities.contains(derivedEntity) && !readableEntities.contains(derivedEntity)
           && !nonReadableEntities.contains(derivedEntity)) {
@@ -649,5 +652,37 @@
         }
       }
     }
+    if (tabs.isEmpty()) {
+      return;
+    }
+    String tabInList = createWhereInCondition(tabs);
+    addEntitiesSelectorsFromTabs(mp, tabInList);
+  }
+
+  /**
+   * Obtain selector references in tabs and added to derivedReadableEntities to take into account as
+   * a derived entity.
+   */
+  private void addEntitiesSelectorsFromTabs(ModelProvider mp, String tabs) {
+    String hql = "select r from ADField f inner join f.column c inner join c.referenceSearchKey r  where r.parentReference='"
+        + SELECTOR_REFERENCE + "' and f.tab.id in(" + tabs + ")";
+    @SuppressWarnings("unchecked")
+    final List<Reference> references = SessionHandler.getInstance().createQuery(hql).list();
+    for (Reference ref : references) {
+      addEntitiesOfSelectorReference(mp, ref);
+    }
+  }
+
+  private String createWhereInCondition(Set<String> list) {
+    StringBuilder processesInList = new StringBuilder();
+    boolean first = true;
+    for (String p : list) {
+      if (!first) {
+        processesInList.append(", ");
+      }
+      first = false;
+      processesInList.append("'").append(p).append("'");
+    }
+    return processesInList.toString();
   }
 }
--- a/src/org/openbravo/erpCommon/ad_forms/GenerateInvoicesmanual_data.xsql	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_forms/GenerateInvoicesmanual_data.xsql	Mon May 09 09:57:27 2016 +0200
@@ -12,7 +12,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -29,7 +29,7 @@
     <Sql>
     <![CDATA[
       SELECT ic.C_Order_ID, o.Name as adorgname, COALESCE(dttrl.Name, dt.Name) as cdoctypename, ic.DocumentNo, bp.Name as cbpartnername, ic.DateOrdered,
-      amountlines, notinvoicedlines, l.Name as TermName, l.Value as TermValue, pendinglines as pendinglines, '' as amountlinesgross, '' as notinvoicedlinesgross,
+      amountlines, notinvoicedlines, COALESCE(ltrl.Name, l.Name) as TermName, l.Value as TermValue, pendinglines as pendinglines, '' as amountlinesgross, '' as notinvoicedlinesgross,
       '' as pendinglinesgross, ic.qtyordered as qtyordered, ic.qtydelivered as qtydelivered, (amountlines-notinvoicedlines) as linesinvoiced, amountlinesgross as totalgross
       FROM C_Invoice_Candidate_v ic, C_ORDER ord, AD_Org o, C_BPartner bp, AD_Ref_List l left join AD_Ref_List_trl ltrl on l.AD_Ref_List_ID=ltrl.AD_Ref_List_ID and ltrl.ad_language=?, 
       C_DocType dt left join C_DocType_trl dttrl on dt.C_DocType_ID=dttrl.C_DocType_ID AND dttrl.ad_language=?
@@ -61,7 +61,7 @@
     <Sql>
     <![CDATA[
       SELECT ic.C_Order_ID, o.Name as adorgname, COALESCE(dttrl.Name, dt.Name) as cdoctypename, ic.DocumentNo, bp.Name as cbpartnername, ic.DateOrdered,
-      amountlinesgross as amountlines, notinvoicedlinesgross as notinvoicedlines, l.Name as TermName, l.Value as TermValue, pendinglinesgross as pendinglines,
+      amountlinesgross as amountlines, notinvoicedlinesgross as notinvoicedlines, COALESCE(ltrl.Name, l.Name) as TermName, l.Value as TermValue, pendinglinesgross as pendinglines,
       ic.qtyordered as qtyordered, ic.qtydelivered as qtydelivered, (amountlinesgross-notinvoicedlinesgross) as linesinvoiced, amountlinesgross as totalgross
       FROM C_Invoice_Candidate_v ic, C_ORDER ord, AD_Org o, C_BPartner bp, AD_Ref_List l left join AD_Ref_List_trl ltrl on l.AD_Ref_List_ID=ltrl.AD_Ref_List_ID and ltrl.ad_language=?, 
       C_DocType dt left join C_DocType_trl dttrl on dt.C_DocType_ID=dttrl.C_DocType_ID AND dttrl.ad_language=?
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.html	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.html	Mon May 09 09:57:27 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2011 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -145,6 +145,35 @@
   return true;
 }
 
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText && document.getElementById('inpcAcctSchemaId').value != strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                    refreshComboReports();
+                }
+                else {
+                    refreshComboYears();
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "GeneralAccountingReports.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
 }
 </script>
@@ -173,12 +202,12 @@
 	setTabTableParentElement();
 	enableShortcuts('edition');
 	setBrowserAutoComplete(false);
-	
 	resizeArea();
 	updateMenuIcon('buttonMenu');
 
 	setWindowElementFocus('firstElement');
-       displayLogic();
+	setDefaultLedger();
+	displayLogic();
 }
 
 function onResizeDo(){
@@ -366,7 +395,7 @@
 
                 <tr>
                   <td class="TitleCell"><span class="LabelText">Organization</span></td>
-                  <td class="Combo_ContentCell" colspan="2"> <select name="inpOrganizacion" id="inpOrganizacion" class="ComboKey Combo_TwoCells_width" onchange="refreshComboYears(); logChanges(this); return true;">
+                  <td class="Combo_ContentCell" colspan="2"> <select name="inpOrganizacion" id="inpOrganizacion" class="ComboKey Combo_TwoCells_width" onchange="setDefaultLedger(); logChanges(this); return true;">
                       <option value=""></option><div id="reportC_Org_ID"></div>
                     </select></td>
                 </tr>
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Mon May 09 09:57:27 2016 +0200
@@ -54,6 +54,7 @@
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.erpCommon.utility.WindowTreeData;
@@ -127,8 +128,19 @@
       printPagePDF(request, response, vars, strAgno, strAgnoRef, strDateFrom, strDateTo,
           strDateFromRef, strDateToRef, strAsDateTo, strAsDateToRef, strElementValue,
           strConImporte, strOrg, strLevel, strConCodigo, strcAcctSchemaId, strPageNo);
-    } else
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars
+          .getGlobalVariable("inpOrganizacion", "GeneralAccountingReports|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    }
+
+    else {
       pageError(response);
+    }
   }
 
   private void printPagePDF(HttpServletRequest request, HttpServletResponse response,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.html	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.html	Mon May 09 09:57:27 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2012 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -89,6 +89,32 @@
   return true;
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportGeneralLedger.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdTo', 'inpElementValueIdTo_DES', document.frmMain.inpElementValueIdTo_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdTo_DES", "null");
@@ -123,11 +149,14 @@
     updateMenuIcon('buttonMenu');
 
     setWindowElementFocus('firstElement');
+    setDefaultLedger();
+
   }
 
   function onResizeDo(){
     resizeArea();
   }
+  
 
   function openGeneralLedgerJournal(recordid) {
       
@@ -370,7 +399,7 @@
             </tr>
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
-              <td class="Combo_ContentCell" colspan="2"> <select name="inpOrg" id="inpOrg" class="Combo Combo_TwoCells_width">
+              <td class="Combo_ContentCell" colspan="2"> <select name="inpOrg" id="inpOrg" class="Combo Combo_TwoCells_width" onChange="setDefaultLedger();">
                   <div id="reportAD_ORGID"></div>
                 </select>
               </td>              
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -46,6 +46,7 @@
 import org.openbravo.erpCommon.utility.LimitRowsScrollableFieldProviderFilter;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.xmlEngine.XmlDocument;
@@ -192,16 +193,27 @@
       String strGroupBy = vars
           .getRequestGlobalVariable("inpGroupBy", "ReportGeneralLedger|GroupBy");
       String strPageNo = vars.getGlobalVariable("inpPageNo", "ReportGeneralLedger|PageNo", "1");
-      if (vars.commandIn("PDF"))
+      if (vars.commandIn("PDF")) {
         printPageDataPDF(request, response, vars, strDateFrom, strDateTo, strAmtFrom, strAmtTo,
             strcelementvaluefrom, strcelementvalueto, strOrg, strcBpartnerId, strmProductId,
             strcProjectId, strGroupBy, strcAcctSchemaId, strPageNo, strShowOpenBalances);
-      else
+      } else {
         printPageDataXLS(request, response, vars, strDateFrom, strDateTo, strAmtFrom, strAmtTo,
             strcelementvaluefrom, strcelementvalueto, strOrg, strcBpartnerId, strmProductId,
             strcProjectId, strGroupBy, strcAcctSchemaId, strShowOpenBalances);
-    } else
+      }
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "ReportGeneralLedger|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    }
+
+    else {
       pageError(response);
+    }
   }
 
   private void printPageDataSheet(HttpServletResponse response, VariablesSecureApp vars,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.html	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.html	Mon May 09 09:57:27 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -89,6 +89,33 @@
     return true;
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText && document.getElementById('inpcAcctSchemaId').value != strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                    selectDocument();
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportGeneralLedgerJournal.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdTo', 'inpElementValueIdTo_DES', document.frmMain.inpElementValueIdTo_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdTo_DES", "null");
@@ -289,6 +316,7 @@
         updateMenuIcon('buttonMenu');
 
         setWindowElementFocus('firstElement');
+        setDefaultLedger();
         displayDocumentNo();
         displayAdvancedFilters();
         selectDocument();
@@ -514,7 +542,7 @@
             </tr>
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
-              <td class="Combo_ContentCell" colspan="2"> <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width required Combo_focus" required="true" onchange="selectDocument();">
+              <td class="Combo_ContentCell" colspan="2"> <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width required Combo_focus" required="true" onchange="setDefaultLedger();">
                  <div id="reportAD_ORGID"></div>
                 </select></td>
               <td class="TitleCell"> <span class="LabelText">General Ledger</span></td>
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -55,6 +55,7 @@
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.datamodel.Table;
@@ -268,8 +269,9 @@
           strPageNo, strEntryNo, strShowDescription, strShowRegular, strShowDivideUp, "", "",
           strcelementvaluefrom, strcelementvalueto, strcelementvaluefromdes, strcelementvaluetodes);
     } else if (vars.commandIn("PDF", "XLS")) {
-      if (log4j.isDebugEnabled())
+      if (log4j.isDebugEnabled()) {
         log4j.debug("PDF");
+      }
       String strcAcctSchemaId = vars.getRequestGlobalVariable("inpcAcctSchemaId",
           "ReportGeneralLedger|cAcctSchemaId");
       String strDateFrom = vars.getRequestGlobalVariable("inpDateFrom",
@@ -409,9 +411,16 @@
       PrintWriter out = response.getWriter();
       out.println("objson = " + combobox);
       out.close();
-
-    } else
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "ReportGeneralLedgerJournal|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
+    } else {
       pageError(response);
+    }
   }
 
   private void printPageDataSheet(HttpServletResponse response, VariablesSecureApp vars,
--- a/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.html	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.html	Mon May 09 09:57:27 2016 +0200
@@ -13,7 +13,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2001-2015 Openbravo SLU
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -87,6 +87,32 @@
     }    
 }
 
+
+function callbackLedger(paramXMLParticular, XMLHttpRequestObj) {
+    var strText = "";
+    if (getReadyStateHandler(XMLHttpRequestObj)) {
+        try {
+            if (XMLHttpRequestObj.responseText) {
+                strText = XMLHttpRequestObj.responseText;
+                if (strText) {
+                    document.getElementById('inpcAcctSchemaId').value = strText;
+                }
+            }
+       } catch (e) {
+       }
+    }
+    return true;
+}
+
+function setDefaultLedger() {
+    try {
+        var paramXMLReq = null;
+        return submitXmlHttpRequest(callbackLedger, document.frmMain, "LEDGER", "ReportTrialBalance.html", false, null, paramXMLReq);
+    } catch (e) {
+        alert(e);
+    }
+}
+
 function onloadFunctions() {
   displayLogic();
   keyArray[keyArray.length] = new keyArrayItem("ENTER", "openSearch(null, null, '../info/AccountElementValue.html', 'SELECTOR_ACCOUNTELEMENTVALUE', false, 'frmMain', 'inpcElementValueIdFrom', 'inpElementValueIdFrom_DES', document.frmMain.inpElementValueIdFrom_DES.value, 'inpcAcctSchemaId', document.frmMain.inpcAcctSchemaId.value, 'Command', 'KEY');", "inpElementValueIdFrom_DES", "null");
@@ -273,6 +299,7 @@
   updateMenuIcon('buttonMenu');
 
   setWindowElementFocus('firstElement');
+  setDefaultLedger();
   displayAdvancedFilters();
 }
 
@@ -550,7 +577,7 @@
             <tr>
               <td class="TitleCell"><span class="LabelText">Organization</span></td>
               <td class="Combo_ContentCell">
-                <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width" required="true">
+                <select  name="inpOrg" id="inpOrg" class="ComboKey Combo_TwoCells_width" required="true" onchange="setDefaultLedger();">
                  <div id="reportAD_ORGID"></div>
                 </select></td>
               <td class="TitleCell"/></td>
--- a/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -50,6 +50,7 @@
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
 import org.openbravo.erpCommon.utility.OBError;
+import org.openbravo.erpCommon.utility.OBLedgerUtils;
 import org.openbravo.erpCommon.utility.ToolBar;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.financialmgmt.accounting.coa.AcctSchema;
@@ -211,7 +212,13 @@
       printPageOpen(response, vars, strDateFrom, strDateTo, strOrg, strLevel, strcBpartnerId,
           strmProductId, strcProjectId, strcAcctSchemaId, strGroupBy, strAccountId,
           strNotInitialBalance);
-
+    } else if (vars.commandIn("LEDGER")) {
+      String strOrg = vars.getGlobalVariable("inpOrg", "AgingInquiry|Org", "0");
+      String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
+      response.setContentType("text/html; charset=UTF-8");
+      PrintWriter out = response.getWriter();
+      out.print(strcAcctSchemaId);
+      out.close();
     } else {
       pageError(response);
     }
--- a/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2001-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2016 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -25,6 +25,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.secureApp.HttpSecureAppServlet;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.costing.CostingBackground;
@@ -39,6 +40,7 @@
 import org.openbravo.erpCommon.utility.DateTimeData;
 import org.openbravo.erpCommon.utility.LeftTabsBar;
 import org.openbravo.erpCommon.utility.NavigationBar;
+import org.openbravo.erpCommon.utility.OBCurrencyUtils;
 import org.openbravo.erpCommon.utility.OBDateUtils;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -63,6 +65,7 @@
 
     // Get user Client's base currency
     String strUserCurrencyId = Utility.stringBaseCurrencyId(this, vars.getClient());
+
     if (vars.commandIn("DEFAULT", "RELATION")) {
       String strDate = vars.getGlobalVariable("inpDate", "ReportValuationStock|Date",
           DateTimeData.today(this));
@@ -70,8 +73,11 @@
           "ReportValuationStock|Warehouse", "");
       String strCategoryProduct = vars.getGlobalVariable("inpCategoryProduct",
           "ReportValuationStock|CategoryProduct", "");
-      String strCurrencyId = vars.getGlobalVariable("inpCurrencyId",
-          "ReportValuationStock|currency", strUserCurrencyId);
+      String strCurrencyId = OBCurrencyUtils.getOrgCurrency(vars.getOrg());
+      if (StringUtils.isEmpty(strCurrencyId)) {
+        strCurrencyId = strUserCurrencyId;
+      }
+
       printPageDataSheet(request, response, vars, strDate, strWarehouse, strCategoryProduct,
           strCurrencyId);
     } else if (vars.commandIn("FIND")) {
--- a/src/org/openbravo/erpCommon/obps/ActivationKey.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/obps/ActivationKey.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2015 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -53,6 +53,7 @@
 import javax.crypto.Cipher;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
+import javax.servlet.http.HttpSession;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Appender;
@@ -68,6 +69,7 @@
 import org.openbravo.base.session.OBPropertiesProvider;
 import org.openbravo.base.weld.WeldUtils;
 import org.openbravo.dal.core.DalContextListener;
+import org.openbravo.dal.core.DalUtil;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBCriteria;
 import org.openbravo.dal.service.OBDal;
@@ -75,6 +77,7 @@
 import org.openbravo.erpCommon.obps.DisabledModules.Artifacts;
 import org.openbravo.erpCommon.obps.ModuleLicenseRestrictions.ActivationMsg;
 import org.openbravo.erpCommon.obps.ModuleLicenseRestrictions.MsgSeverity;
+import org.openbravo.erpCommon.security.SessionListener;
 import org.openbravo.erpCommon.utility.HttpsUtils;
 import org.openbravo.erpCommon.utility.OBError;
 import org.openbravo.erpCommon.utility.OBMessageUtils;
@@ -232,14 +235,14 @@
   private static final String ON_DEMAND_PLATFORM_CHECK_URL = "http://localhost:20290/checkOnDemand?qry=";
 
   /**
-   * Session types that are considered for user concurrency
+   * Session types that are not taken into account for counting concurrent users
    */
   @SuppressWarnings("serial")
-  private static final List<String> ACTIVE_SESSION_TYPES = new ArrayList<String>() {
+  private static final List<String> NO_CU_SESSION_TYPES = new ArrayList<String>() {
     {
-      add("S");
-      add("CUR");
-      add("SUR");
+      add("WS"); // Web service
+      add("WSC"); // Connector
+      add("OBPOS_POS"); // WebPOS
     }
   };
   public static final Long NO_LIMIT = -1L;
@@ -862,7 +865,9 @@
     return new ActivationMsg(severity, customMsg);
   }
 
-  /** gets HTML to be injected in Instance Activation window with additional actions to be performed */
+  /**
+   * gets HTML to be injected in Instance Activation window with additional actions to be performed
+   */
   public String getInstanceActivationExtraActionsHtml(XmlEngine xmlEngine) {
     String html = "";
 
@@ -885,15 +890,24 @@
     return checkOPSLimitations("");
   }
 
+  /** @see ActivationKey#checkOPSLimitations(String, String) */
+  public LicenseRestriction checkOPSLimitations(String currentSession) {
+    return checkOPSLimitations(currentSession, null);
+  }
+
   /**
    * Checks the current activation key
    * 
    * @param currentSession
    *          Current session, not to be taken into account
+   * @param sessionType
+   *          Successful session type: if the session is finally successful this is the type that
+   *          will be marked with in {@code AD_Session}, it is used to determine whether it should
+   *          or not count for CU limitation. In case it is {@code null} it will be counted.
    * 
    * @return {@link LicenseRestriction} with the status of the restrictions
    */
-  public LicenseRestriction checkOPSLimitations(String currentSession) {
+  public LicenseRestriction checkOPSLimitations(String currentSession, String sessionType) {
     LicenseRestriction result = LicenseRestriction.NO_RESTRICTION;
     if (!isOPSInstance()) {
       return LicenseRestriction.NO_RESTRICTION;
@@ -921,7 +935,8 @@
     }
 
     // maxUsers==0 is unlimited concurrent users
-    if (maxUsers != 0) {
+    boolean checkConcurrentUsers = maxUsers != 0 && consumesConcurrentUser(sessionType);
+    if (checkConcurrentUsers) {
       OBContext.setAdminMode();
       int activeSessions = 0;
       try {
@@ -973,14 +988,24 @@
     return result;
   }
 
+  /** Returns whether a session type is counted for concurrent users */
+  public static boolean consumesConcurrentUser(String sessionType) {
+    return sessionType == null || !NO_CU_SESSION_TYPES.contains(sessionType);
+  }
+
   public LicenseRestriction checkOPSLimitations(String currentSession, String username,
       boolean forceNamedUserLogin) {
+    return checkOPSLimitations(currentSession, username, forceNamedUserLogin, null);
+  }
+
+  public LicenseRestriction checkOPSLimitations(String currentSession, String username,
+      boolean forceNamedUserLogin, String sessionType) {
     if (forceNamedUserLogin) {
       // Forcing log in even there are other sessions for same user: disabling the other sessions
       disableOtherSessionsOfUser(currentSession, username);
     }
 
-    LicenseRestriction result = checkOPSLimitations(currentSession);
+    LicenseRestriction result = checkOPSLimitations(currentSession, sessionType);
 
     boolean checkNamedUserLimitation = StringUtils.isNotEmpty(username) && limitNamedUsers;
 
@@ -1060,16 +1085,22 @@
         Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true),
         Restrictions.or(Restrictions.isNull(Session.PROPERTY_LASTPING),
             Restrictions.lt(Session.PROPERTY_LASTPING, lastValidPingTime))));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
-    obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSessionId));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
+
+    if (currentSessionId != null) {
+      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSessionId));
+    }
 
     boolean sessionDeactivated = false;
     for (Session expiredSession : obCriteria.list()) {
-      expiredSession.setSessionActive(false);
-      sessionDeactivated = true;
-      log4j.info("Deactivated session: " + expiredSession.getId()
-          + " beacuse of ping time out. Last ping: " + expiredSession.getLastPing()
-          + ". Last valid ping time: " + lastValidPingTime);
+      if (shouldDeactivateSession(expiredSession, lastValidPingTime)) {
+        expiredSession.setSessionActive(false);
+        sessionDeactivated = true;
+        log4j.info("Deactivated session: " + expiredSession.getId()
+            + " beacuse of ping time out. Last ping: " + expiredSession.getLastPing()
+            + ". Last valid ping time: " + lastValidPingTime);
+      }
     }
     if (sessionDeactivated) {
       OBDal.getInstance().flush();
@@ -1080,24 +1111,27 @@
   }
 
   /**
-   * Returns the number of current active sessions
+   * Do not deactivate those sessions that are not using ping but consume concurrent users (ie.
+   * mobile apps) if activity from them has been recently detected.
    */
-  private int getActiveSessions(String currentSession) {
-    OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
-    obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
-
-    if (currentSession != null && !currentSession.equals("")) {
-      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
+  private boolean shouldDeactivateSession(Session expiredSession, Date lastValidPingTime) {
+    String sessionId = (String) DalUtil.getId(expiredSession);
+    HttpSession session = SessionListener.getActiveSession(sessionId);
+    if (session == null) {
+      log4j.debug("Session " + sessionId + " not found in context");
+      return true;
     }
-    return obCriteria.count();
+    Date lastRequestTime = new Date(session.getLastAccessedTime());
+    log4j.debug("Last request received from session " + sessionId + ": " + lastRequestTime);
+    return lastRequestTime.compareTo(lastValidPingTime) < 0;
   }
 
   private int getActiveSessionsForNamedUser(String currentSession, String username) {
     OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
     obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
     obCriteria.add(Restrictions.eq(Session.PROPERTY_USERNAME, username));
-    obCriteria.add(Restrictions.in(Session.PROPERTY_LOGINSTATUS, ACTIVE_SESSION_TYPES));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
     if (currentSession != null && !currentSession.equals("")) {
       obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
     }
@@ -1174,6 +1208,11 @@
           sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSConcurrentUsersWarn", lang))
               .append("</td><td>").append(getProperty("limituserswarn")).append("</td></tr>");
         }
+
+        sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSCurrentConcurrentUsers", lang))
+            .append("</td><td>");
+        sb.append(getActiveSessions(null));
+        sb.append("</td></tr>");
       }
 
       sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSInstanceNo", lang))
@@ -1189,11 +1228,23 @@
       sb.append(getWSExplanation(conn, lang));
       sb.append("</td></tr>");
 
+      sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSWSCounterDay", lang))
+          .append("</td><td>");
+      sb.append(getNumberWSDayCounter());
+      sb.append("</td></tr>");
+
       sb.append("<tr><td>").append(Utility.messageBD(conn, "OPSPOSLimitation", lang))
           .append("</td><td>");
       sb.append(getPOSTerminalsExplanation());
       sb.append("</td></tr>");
 
+      for (ModuleLicenseRestrictions.AdditionalInfo addInfo : getAdditionalMessageInfo()) {
+        sb.append("<tr><td>").append(Utility.messageBD(conn, addInfo.getKey(), lang))
+            .append("</td><td>");
+        sb.append(addInfo.getValue());
+        sb.append("</td></tr>");
+      }
+
     } else {
       sb.append(Utility.messageBD(conn, "OPSNonActiveInstance", lang));
     }
@@ -1296,6 +1347,32 @@
   }
 
   /**
+   * get all additional messages to be printed in Instance Activation window.
+   */
+  private List<ModuleLicenseRestrictions.AdditionalInfo> getAdditionalMessageInfo() {
+    List<ModuleLicenseRestrictions.AdditionalInfo> additionalInfo = new ArrayList<ModuleLicenseRestrictions.AdditionalInfo>();
+    for (ModuleLicenseRestrictions moduleRestriction : getModuleLicenseRestrictions()) {
+      additionalInfo.addAll(moduleRestriction.getAdditionalMessage());
+    }
+    return additionalInfo;
+  }
+
+  /**
+   * Returns the number of current active sessions
+   */
+  private int getActiveSessions(String currentSession) {
+    OBCriteria<Session> obCriteria = OBDal.getInstance().createCriteria(Session.class);
+    obCriteria.add(Restrictions.eq(Session.PROPERTY_SESSIONACTIVE, true));
+    obCriteria.add(Restrictions.not(Restrictions.in(Session.PROPERTY_LOGINSTATUS,
+        NO_CU_SESSION_TYPES)));
+
+    if (currentSession != null && !currentSession.equals("")) {
+      obCriteria.add(Restrictions.ne(Session.PROPERTY_ID, currentSession));
+    }
+    return obCriteria.count();
+  }
+
+  /**
    * Same as {@link ActivationKey#getSubscribedModules()} with the includeDisabled parameter. When
    * this parameter is true, disabled modules are returned with the DISABLED status, other way they
    * are returned with the status they would have if they were not disabled.
@@ -1833,16 +1910,21 @@
     initWsCountTime = getDayAt0(new Date());
     OBContext.setAdminMode();
     try {
-      OBCriteria<Session> qLogins = OBDal.getInstance().createCriteria(Session.class);
-      qLogins.add(Restrictions.eq(Session.PROPERTY_LOGINSTATUS, "WS"));
-      qLogins.add(Restrictions.ge(Session.PROPERTY_CREATIONDATE, initWsCountTime));
-      wsDayCounter = qLogins.count();
+      wsDayCounter = getNumberWSDayCounter();
       log.info("Initialized ws count to " + wsDayCounter + " from " + initWsCountTime);
     } finally {
       OBContext.restorePreviousMode();
     }
   }
 
+  private int getNumberWSDayCounter() {
+    Date date = getDayAt0(new Date());
+    OBCriteria<Session> qLogins = OBDal.getInstance().createCriteria(Session.class);
+    qLogins.add(Restrictions.eq(Session.PROPERTY_LOGINSTATUS, "WS"));
+    qLogins.add(Restrictions.ge(Session.PROPERTY_CREATIONDATE, date));
+    return qLogins.count();
+  }
+
   private void initializeWsCounter() {
     StringBuilder hql = new StringBuilder();
     hql.append("select min(creationDate)\n");
--- a/src/org/openbravo/erpCommon/obps/ModuleLicenseRestrictions.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/obps/ModuleLicenseRestrictions.java	Mon May 09 09:57:27 2016 +0200
@@ -11,13 +11,15 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2015 Openbravo SLU 
+ * All portions are Copyright (C) 2015-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
  */
 package org.openbravo.erpCommon.obps;
 
+import java.util.List;
+
 import javax.enterprise.context.ApplicationScoped;
 
 import org.openbravo.erpCommon.obps.ActivationKey.LicenseRestriction;
@@ -49,6 +51,33 @@
   /** Provides the HTML to be injected in Instance Activation window to perform additional actions */
   public String getInstanceActivationExtraActionsHtml(XmlEngine xmlEngine);
 
+  /**
+   * Provides a mechanism to returns an extra message. This information will be shown in Instance
+   * Activation window.
+   */
+  public List<AdditionalInfo> getAdditionalMessage();
+
+  /**
+   * Holder for additional messages. The key is used for retrieves a message from ad_message table.
+   */
+  public static class AdditionalInfo {
+    private String key;
+    private String value;
+
+    public AdditionalInfo(String key, String value) {
+      this.key = key;
+      this.value = value;
+    }
+
+    public String getKey() {
+      return key;
+    }
+
+    public String getValue() {
+      return value;
+    }
+  }
+
   public enum MsgSeverity {
     WARN("Warning"), ERROR("Error");
 
--- a/src/org/openbravo/erpCommon/security/SessionListener.java	Fri Apr 29 14:59:04 2016 +0200
+++ b/src/org/openbravo/erpCommon/security/SessionListener.java	Mon May 09 09:57:27 2016 +0200
@@ -11,7 +11,7 @@
  * under the License. 
  * The Original Code is Openbravo ERP. 
  * The Initial Developer of the Original Code is Openbravo SLU 
- * All portions are Copyright (C) 2009-2014 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2016 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -21,12 +21,14 @@
 
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
-import java.util.Vector;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.ServletContextListener;
 import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
 import javax.servlet.http.HttpSessionEvent;
 import javax.servlet.http.HttpSessionListener;
 
@@ -34,13 +36,18 @@
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.database.SessionInfo;
 
+/**
+ * Keeps track of active sessions in this context so they can be marked as no active in database
+ * when they are destroyed. Also used to keep last activity info for CU management.
+ */
 public class SessionListener implements HttpSessionListener, ServletContextListener {
 
   private static final int PING_TIMEOUT_SECS = 120;
 
   private static final Logger log = Logger.getLogger(SessionListener.class);
 
-  private static Vector<String> sessionsInContext = new Vector<String>();
+  private static Set<String> sessionsInContext = new HashSet<String>();
+  private static Set<HttpSession> activeHttpSessions = new HashSet<HttpSession>();
   private static ServletContext context = null;
 
   /**
@@ -51,11 +58,16 @@
   @Override
   public void sessionDestroyed(HttpSessionEvent event) {
     log.debug("Destroying session");
-    String sessionId = (String) event.getSession().getAttribute("#AD_SESSION_ID");
+    HttpSession session = event.getSession();
+    String sessionId = (String) session.getAttribute("#AD_SESSION_ID");
     if (sessionId != null) {
       deactivateSession(sessionId);
+    }
+    synchronized (activeHttpSessions) {
+      activeHttpSessions.remove(session);
+    }
 
-    }
+    log.debug("Session destroyed. Active sessions count: " + activeHttpSessions.size());
   }
 
   /**
@@ -87,7 +99,7 @@
    * @param sessionId
    *          db id for the session to keep track
    */
-  public static void addSession(String sessionId) {
+  public static synchronized void addSession(String sessionId) {
     sessionsInContext.add(sessionId);
   }
 
@@ -136,12 +148,36 @@
 
   @Override
   public void sessionCreated(HttpSessionEvent event) {
-    // do nothing
+    synchronized (activeHttpSessions) {
+      activeHttpSessions.add(event.getSession());
+    }
+
+    log.debug("Session created. Active sessions count: " + activeHttpSessions.size());
+  }
+
+  /**
+   * Returns the {@code HttpSession} identified by {@code sessionId} it is present in this context.
+   * If not present {@code null} is returned.
+   */
+  public static HttpSession getActiveSession(String sessionId) {
+    try {
+      for (HttpSession session : activeHttpSessions) {
+        if (sessionId.equals(session.getAttribute("#AD_SESSION_ID"))) {
+          return session;
+        }
+      }
+    } catch (Exception e) {
+      log.error("Error getting active session from context", e);
+      // give up and return null
+    }
+    return null;
   }
 
   private void deactivateSession(String sessionId) {
     try {
-      sessionsInContext.remove(sessionId);
+      synchronized (sessionsInContext) {
+        sessionsInContext.remove(sessionId);
+      }
 
       // Do not use DAL here
       SessionLoginData.deactivate((ConnectionProvider) context.getAttribute("openbravoPool"),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/erpCommon/utility/OBLedgerUtils.java	Mon May 09 09:57:27 2016 +0200
@@ -0,0 +1,114 @@
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2016 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.erpCommon.utility;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.hibernate.Query;
+import org.openbravo.dal.core.OBContext;
+import org.openbravo.dal.service.OBDal;
+import org.openbravo.model.common.enterprise.Organization;
+import org.openbravo.model.financialmgmt.accounting.coa.AcctSchema;
+
+/**
+ * Utilities to get AcctSchema
+ */
+public class OBLedgerUtils {
+  private static Logger log4j = Logger.getLogger(OBLedgerUtils.class);
+
+  /**
+   * Returns the ledger id for the given organization id.
+   * 
+   * If the org id is empty, it returns null. If the given organization has no ledger, it tries to
+   * get its legal entity's ledger. If not found, it returns the organization client's ledger
+   * 
+   * @param orgId
+   *          Organization Id whose ledger is needed
+   * 
+   * @return String ledgerId ledger id for the given organization. Null if not found
+   */
+  public static String getOrgLedger(String orgId) {
+    try {
+      OBContext.setAdminMode(true);
+
+      if (StringUtils.isBlank(orgId)) {
+        // No organization
+        return null;
+      }
+      final Organization org = OBDal.getInstance().get(Organization.class, orgId);
+      if (org == null) {
+        // No organization
+        return null;
+      }
+      String acctSchemaId = getOrgLedgerRecursive(orgId);
+      if (!StringUtils.isEmpty(acctSchemaId)) {
+        // Get ledger of organization tree
+        return acctSchemaId;
+      }
+      String clientId = StringUtils.equals(orgId, "0") ? OBContext.getOBContext()
+          .getCurrentClient().getId() : org.getClient().getId();
+      // Get client base Ledger
+      return getClientLedger(clientId);
+
+    } catch (Exception e) {
+      log4j.error("Impossible to get ledger for organization id " + orgId, e);
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+
+    return null;
+  }
+
+  private static String getOrgLedgerRecursive(String orgId) {
+    try {
+      OBContext.setAdminMode(true);
+      StringBuffer where = new StringBuffer();
+      where.append(" select " + Organization.PROPERTY_GENERALLEDGER + ".id");
+      where.append(" from " + Organization.ENTITY_NAME);
+      where.append(" where ad_isorgincluded(:orgId, " + Organization.PROPERTY_ID + ", "
+          + Organization.PROPERTY_CLIENT + ".id) <> -1");
+      where.append(" and " + Organization.PROPERTY_GENERALLEDGER + " is not null");
+      where.append(" order by ad_isorgincluded(:orgId, " + Organization.PROPERTY_ID + ", "
+          + Organization.PROPERTY_CLIENT + ".id)");
+      Query qry = OBDal.getInstance().getSession().createQuery(where.toString());
+      qry.setParameter("orgId", orgId);
+      qry.setMaxResults(1);
+      return (String) qry.uniqueResult();
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+
+  private static String getClientLedger(String clientId) {
+    try {
+      OBContext.setAdminMode(true);
+      StringBuffer where = new StringBuffer();
+      where.append(" select " + AcctSchema.PROPERTY_ID);
+      where.append(" from " + AcctSchema.ENTITY_NAME);
+      where.append(" where " + AcctSchema.PROPERTY_CLIENT + ".id = :clientId");
+      where.append(" order by " + AcctSchema.PROPERTY_NAME);
+      Query qry = OBDal.getInstance().getSession().createQuery(where.toString());
+      qry.setParameter("clientId", clientId);
+      qry.setMaxResults(1);
+      return (String) qry.uniqueResult();
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
+}