[deliverymodeissue] merge from main repo
authorGuillermo Alvarez de Eulate <guillermo.alvarez@openbravo.com>
Thu, 09 May 2019 09:05:05 +0200
changeset 35795 32469d8b110c
parent 35794 f9ba6dd4f475 (current diff)
parent 35751 eac83131aa3f (diff)
child 35796 df96ff60c3c4
[deliverymodeissue] merge from main repo
--- a/.hgsigs	Thu Apr 25 14:52:39 2019 -0400
+++ b/.hgsigs	Thu May 09 09:05:05 2019 +0200
@@ -245,3 +245,4 @@
 c508fdfd08e0165b19ce0b036057fb477ec53b2d 0 iF0EABECAB0WIQQwlWrRXxlUdnEi7O8Jf+gZ/7aqQwUCXHaDaQAKCRAJf+gZ/7aqQ+WQAKC9aZKEZiAzmHtHS2DU/BebakLrDwCgmPGmEdALKCn+hWjKUkLY6Yc5FbI=
 ab23c5504c6082c745fd74bdbd8790040217373e 0 iF0EABECAB0WIQQwlWrRXxlUdnEi7O8Jf+gZ/7aqQwUCXLV8WwAKCRAJf+gZ/7aqQyGHAKCi6W3sN7+WShE66VENLwKlvrlWDQCeP0Fu2ITFgmftDOoad6iIaEogDCA=
 6154268d4b94fc3e4eee2a6e42cc1bd2cb7c3988 0 iF0EABECAB0WIQQwlWrRXxlUdnEi7O8Jf+gZ/7aqQwUCXJtnAAAKCRAJf+gZ/7aqQxgWAKDD39xe/9/GPyV2/8flksKGQs+RlgCeM5lTApT6W4dcmB+5aN3yCDmDdlI=
+10080fe6bda147693cc393a808d1c3b08717dff3 0 iF0EABECAB0WIQQwlWrRXxlUdnEi7O8Jf+gZ/7aqQwUCXNFiOQAKCRAJf+gZ/7aqQy9/AJ4uFDZAAKj7w4tDqWvjCgiwisMgLACfVhQYjql8qv4znV+JqTvNwQsa9Y0=
--- a/.hgtags	Thu Apr 25 14:52:39 2019 -0400
+++ b/.hgtags	Thu May 09 09:05:05 2019 +0200
@@ -256,3 +256,4 @@
 c23ab3fedd95c122ea2e49cb4a9d6744f75dd975 3.0PR18Q4.2
 e735af032865638eb4f37c83926e20eae145819c 3.0PR18Q4.3
 66655fa7994900d014804a4d6cc7a88579c8fb9e 3.0PR19Q1
+5a9355cfa0e6a56f4eeba25c54650ab5c139121e 3.0PR19Q1.1
--- a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddPaymentActionHandler.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/actionHandler/AddPaymentActionHandler.java	Thu May 09 09:05:05 2019 +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-2016 Openbravo SLU
+ * All portions are Copyright (C) 2014-2019 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -26,6 +26,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 import javax.servlet.ServletException;
 
@@ -323,6 +324,7 @@
       List<FIN_PaymentScheduleDetail> psds = getOrderedPaymentScheduleDetails(psdIds);
       BigDecimal outstandingAmount = BigDecimal.ZERO;
       BigDecimal remainingAmount = paidAmount;
+      boolean isFullPaydAndHasNegativeLines = fullPaydAndHasNegativeLines(psds, paidAmount);
       for (FIN_PaymentScheduleDetail psd : psds) {
         BigDecimal assignAmount = BigDecimal.ZERO;
 
@@ -344,16 +346,35 @@
             || (remainingAmount.signum() < 0
                 && remainingAmount.compareTo(outstandingAmount) <= 0)) {
           assignAmount = outstandingAmount;
-          remainingAmount = remainingAmount.subtract(outstandingAmount);
+          if (!isFullPaydAndHasNegativeLines) {
+            remainingAmount = remainingAmount.subtract(outstandingAmount);
+          }
         } else {
-          assignAmount = remainingAmount;
-          remainingAmount = BigDecimal.ZERO;
+          if (isFullPaydAndHasNegativeLines) {
+            assignAmount = outstandingAmount;
+          } else {
+            assignAmount = remainingAmount;
+            remainingAmount = BigDecimal.ZERO;
+          }
         }
         FIN_AddPayment.updatePaymentDetail(psd, payment, assignAmount, isWriteOff);
       }
     }
   }
 
+  private boolean fullPaydAndHasNegativeLines(List<FIN_PaymentScheduleDetail> psds,
+      BigDecimal paidAmount) {
+    BigDecimal sumOfAmounts = psds.stream()
+        .map(FIN_PaymentScheduleDetail::getAmount)
+        .reduce(BigDecimal::add)
+        .get();
+
+    List<FIN_PaymentScheduleDetail> negativePsd = psds.stream()
+        .filter(t -> t.getAmount().signum() < 0)
+        .collect(Collectors.toList());
+    return sumOfAmounts.compareTo(paidAmount) == 0 && !negativePsd.isEmpty();
+  }
+
   private void addCredit(FIN_Payment payment, JSONObject jsonparams, BigDecimal differenceAmount,
       String strDifferenceAction) throws JSONException {
     // Credit to Use Grid
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-fk-filter.js	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/form/formitem/ob-formitem-fk-filter.js	Thu May 09 09:05:05 2019 +0200
@@ -175,13 +175,22 @@
         },
         _original_recordClick: isc.PickListMenu.getPrototype().recordClick,
         recordClick: function (viewer, record, recordNum, field, fieldNum, value, rawValue) {
+          var filterEditor = this.formItem && this.formItem.grid,
+              grid = filterEditor && filterEditor.parentElement;
           if (field && field.name === '_checkboxField') {
             // when clicking on the checkbox, execute default behaviour
             return this._original_recordClick(viewer, record, recordNum, field, fieldNum, value, rawValue);
           } else {
             // when clicking a row outside the checkbox, select that specific row and close the popup
             this.formItem.setValue('==' + record._identifier);
-            this.formItem.grid.performFilter(true, true);
+            if (grid) {
+              if (grid.lazyFiltering) {
+                grid.filterHasChanged = true;
+                grid.sorter.enable();
+              } else {
+                filterEditor.performFilter(true, true);
+              }
+            }
             this.hide();
           }
         }
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/grid/ob-grid.js	Thu May 09 09:05:05 2019 +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) 2010-2018 Openbravo SLU
+ * All portions are Copyright (C) 2010-2019 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -137,7 +137,7 @@
         return OB.Utilities.getPromptString(cellErrors);
       }
     }
-    if (record && record[isc.OBViewGrid.ERROR_MESSAGE_PROP]) {
+    if (record[isc.OBViewGrid.ERROR_MESSAGE_PROP]) {
       return record[isc.OBViewGrid.ERROR_MESSAGE_PROP];
     }
 
@@ -823,8 +823,7 @@
   },
 
   clearFilter: function (keepFilterClause, noPerformAction) {
-    var i = 0,
-        fld, length, groupState, forceRefresh;
+    var i, fld, length, groupState, forceRefresh;
     if (this.lazyFiltering) {
       noPerformAction = true;
       if (this.sorter) {
@@ -1242,6 +1241,7 @@
       _textMatchStyle: 'substring',
       _UTCOffsetMiliseconds: OB.Utilities.Date.getUTCOffsetInMiliseconds()
     }, lcriteria, this.getFetchRequestParams(null, isExporting));
+
     sortCriteria = this.getSort();
     if (sortCriteria && sortCriteria.length > 0) {
       d._sortBy = sortCriteria[0].property;
@@ -1249,6 +1249,13 @@
         d._sortBy = '-' + d._sortBy;
       }
     }
+
+    if (d.criteria) {
+      // Encode the grid criteria as it is done for the standard grid requests
+      // Note that OB.Utilities.postThroughHiddenForm has its own logic for encoding dates
+      d.criteria = isc.JSON.encode(d.criteria);
+    }
+
     OB.Utilities.postThroughHiddenForm(dsURL, d);
   },
 
@@ -1564,7 +1571,7 @@
       newDrawArea = this.getDrawArea();
       drawArea = this._oldDrawArea;
       if (!drawArea) {
-        drawArea = this._oldDrawArea = [0, 0, 0, 0];
+        this._oldDrawArea = [0, 0, 0, 0];
       }
 
       firstRecord = grid.getRecord(newDrawArea[0]);
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-grid.js	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/process/ob-pick-and-execute-grid.js	Thu May 09 09:05:05 2019 +0200
@@ -925,7 +925,9 @@
       return;
     }
     contextInfo = isc.addProperties({}, this.view.parentWindow.activeView.getContextInfo(false, true, true, true));
-    isc.addProperties(contextInfo, this.viewProperties.standardProperties);
+    if (this.viewProperties.standardProperties && this.viewProperties.standardProperties.inpTableId) {
+      contextInfo.inpPickAndExecuteTableId = this.viewProperties.standardProperties.inpTableId;
+    }
     record = isc.addProperties({}, this.getRecord(rowNum), this.getEditValues(rowNum));
     fields = this.viewProperties.fields;
     len = fields.length;
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceServlet.java	Thu May 09 09:05:05 2019 +0200
@@ -113,6 +113,7 @@
   private static String servletPathPart = "org.openbravo.service.datasource";
   private static Pattern csrfTokenPattern = Pattern
       .compile("\"csrfToken\":\"(?<token>[A-Z0-9]+)\"");
+  private static final String[] CSV_FORMULA_PREFIXES = new String[] { "=", "+", "-", "@" };
 
   public static String getServletPathPart() {
     return servletPathPart;
@@ -678,9 +679,9 @@
           String outputValue;
           if (keyValue != null && !keyValue.toString().equals("null")) {
             outputValue = keyValue.toString().replace("\"", "\"\"");
-            if (outputValue.startsWith("=")) {
+            if (StringUtils.startsWithAny(outputValue, CSV_FORMULA_PREFIXES)) {
               // escape formulas
-              outputValue = "'" + outputValue;
+              outputValue = "\t" + outputValue;
             }
           } else {
             outputValue = "";
--- a/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorConstants.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/modules/org.openbravo.userinterface.selector/src/org/openbravo/userinterface/selector/SelectorConstants.java	Thu May 09 09:05:05 2019 +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-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2009-2019 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -47,6 +47,7 @@
   public static final String PARAM_ID_FILTERS = "idFilters";
   public static final String PARAM_FILTER_EXPRESSION = "filterExpression";
   private static final String PARAM_TABLE_ID = "inpTableId";
+  private static final String PARAM_PICK_AND_EXECUTE_TABLE_ID = "inpPickAndExecuteTableId";
 
   // Reference definition IDs
   public static final String SELECTOR_REFERENCE_ID = "95E2A8B50A254B2AAE6774B8C2F28120";
@@ -69,8 +70,10 @@
         && parameters.containsKey(PARAM_TABLE_ID)
         && parameters.containsKey(PARAM_TARGET_PROPERTY_NAME);
     if (isSelector) {
-      Entity entity = ModelProvider.getInstance()
-          .getEntityByTableId(parameters.get(PARAM_TABLE_ID));
+      String tableId = parameters.containsKey(PARAM_PICK_AND_EXECUTE_TABLE_ID)
+          ? parameters.get(PARAM_PICK_AND_EXECUTE_TABLE_ID)
+          : parameters.get(PARAM_TABLE_ID);
+      Entity entity = ModelProvider.getInstance().getEntityByTableId(tableId);
       if (entity != null) {
         Property property = entity.getProperty(parameters.get(PARAM_TARGET_PROPERTY_NAME), false);
         return property != null && !property.isAllowedCrossOrgReference();
--- a/src-db/database/model/functions/M_GET_DEFAULT_AUM_FOR_DOCUMENT.xml	Thu Apr 25 14:52:39 2019 -0400
+++ b/src-db/database/model/functions/M_GET_DEFAULT_AUM_FOR_DOCUMENT.xml	Thu May 09 09:05:05 2019 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
   <database name="FUNCTION M_GET_DEFAULT_AUM_FOR_DOCUMENT">
-    <function name="M_GET_DEFAULT_AUM_FOR_DOCUMENT" type="VARCHAR">
+    <function name="M_GET_DEFAULT_AUM_FOR_DOCUMENT" type="VARCHAR" volatility="STABLE">
       <parameter name="mproductid" type="VARCHAR" mode="in">
         <default/>
       </parameter>
@@ -19,7 +19,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) 2016 Openbravo SLU
+* All portions are Copyright (C) 2016-2019 Openbravo SLU
 * All Rights Reserved.
 * Contributor(s):  ______________________________________.
 *
--- a/src-test/src/org/openbravo/test/AllAntTaskTests.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src-test/src/org/openbravo/test/AllAntTaskTests.java	Thu May 09 09:05:05 2019 +0200
@@ -41,6 +41,7 @@
 import org.openbravo.erpCommon.info.ClassicSelectorTest;
 import org.openbravo.test.accounting.PostDocumentTest;
 import org.openbravo.test.accounting.RecordID2Test;
+import org.openbravo.test.authentication.AuthenticationManagerTest;
 import org.openbravo.test.cancelandreplace.CancelAndReplaceTest;
 import org.openbravo.test.centralbroker.CentralBrokerTest;
 import org.openbravo.test.copyLinesFromOrders.CopyLinesFromOrdersTest;
@@ -67,6 +68,7 @@
 import org.openbravo.test.dal.ReadByNameTest;
 import org.openbravo.test.dal.ValidationTest;
 import org.openbravo.test.dal.ViewTest;
+import org.openbravo.test.datasource.GridExport;
 import org.openbravo.test.db.model.functions.ADOrgTreeTest;
 import org.openbravo.test.db.model.functions.Ad_isorgincludedTest;
 import org.openbravo.test.db.model.functions.SqlCallableStatement;
@@ -149,6 +151,9 @@
 @RunWith(Suite.class)
 @Suite.SuiteClasses({
 
+    // authentication
+    AuthenticationManagerTest.class, //
+
     // dal
     DalComplexQueryRequisitionTest.class, //
     DalComplexQueryTestOrderLine.class, //
@@ -309,6 +314,7 @@
 
     // others
     DocumentNumberGeneration.class, //
+    GridExport.class, //
     ViewGeneration.class,
 
     // Cancel and Replace Tests
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/authentication/AuthenticationManagerTest.java	Thu May 09 09:05:05 2019 +0200
@@ -0,0 +1,47 @@
+/*
+ *************************************************************************
+ * 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) 2019 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.test.authentication;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.openbravo.test.base.TestConstants.Users.OPENBRAVO;
+
+import org.junit.Test;
+import org.openbravo.authentication.basic.DefaultAuthenticationManager;
+import org.openbravo.test.base.OBBaseTest;
+
+/**
+ * Test cases to cover the authentication manager mechanism.
+ */
+public class AuthenticationManagerTest extends OBBaseTest {
+
+  private static final String USER_NAME = "Openbravo";
+  private static final String PASSWORD = "openbravo";
+
+  /**
+   * Test the authentication intended for non standard REST web services (such as SOAP).
+   */
+  @Test
+  public void webServiceAuthenticate() {
+    DefaultAuthenticationManager authManager = new DefaultAuthenticationManager();
+    String userId = authManager.webServiceAuthenticate(USER_NAME, PASSWORD);
+    assertThat(userId, equalTo(OPENBRAVO));
+  }
+
+}
--- a/src-test/src/org/openbravo/test/base/TestConstants.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src-test/src/org/openbravo/test/base/TestConstants.java	Thu May 09 09:05:05 2019 +0200
@@ -52,6 +52,14 @@
     public static final String DISCOUNTS_AND_PROMOTIONS = "800028";
   }
 
+  public static class Entities {
+    public static final String COUNTRY = "Country";
+  }
+
+  public static class Users {
+    public static final String OPENBRAVO = "100";
+  }
+
   private TestConstants() {
   }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src-test/src/org/openbravo/test/datasource/GridExport.java	Thu May 09 09:05:05 2019 +0200
@@ -0,0 +1,154 @@
+/*
+ *************************************************************************
+ * 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) 2019 Openbravo SLU 
+ * All Rights Reserved. 
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+package org.openbravo.test.datasource;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.openbravo.test.base.TestConstants.Entities.COUNTRY;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.junit.Test;
+import org.openbravo.base.exception.OBException;
+import org.openbravo.base.weld.test.WeldBaseTest;
+import org.openbravo.erpCommon.utility.StringCollectionUtils;
+import org.openbravo.service.datasource.DataSourceServiceProvider;
+import org.openbravo.service.datasource.DefaultDataSourceService;
+import org.openbravo.service.json.DefaultJsonDataService.QueryResultWriter;
+import org.openbravo.service.json.JsonConstants;
+
+/**
+ * Test cases to verify the correct behavior when exporting an standard grid. Note that the tests in
+ * this class does not need to execute any request as they are making direct use of the DataSource
+ * API.
+ */
+public class GridExport extends WeldBaseTest {
+
+  @Inject
+  private DataSourceServiceProvider dataSourceServiceProvider;
+
+  /** exports a grid filtered by a date column */
+  @Test
+  public void exportRecordsFilteredByDate() throws Exception {
+    TestQueryResultWriter writer = new TestQueryResultWriter(COUNTRY,
+        Arrays.asList("iSOCountryCode", "name", "addressPrintFormat", "currency", "hasRegions"));
+    exportGrid(writer);
+    assertThat(writer.getResults(), equalTo(getExpectedResult()));
+  }
+
+  private void exportGrid(TestQueryResultWriter writer) {
+    DefaultDataSourceService dataSource = (DefaultDataSourceService) dataSourceServiceProvider
+        .getDataSource(writer.getEntityName());
+
+    Map<String, String> parameters = getRequestParameters();
+    parameters.put(JsonConstants.NO_ACTIVE_FILTER, "true");
+    parameters.put(JsonConstants.SELECTEDPROPERTIES_PARAMETER, writer.getFieldProperties());
+
+    dataSource.fetch(parameters, writer);
+  }
+
+  private Map<String, String> getRequestParameters() {
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("_operationType", "fetch");
+    params.put("_noCount", "true");
+    params.put("exportAs", "csv");
+    params.put("_textMatchStyle", "substring");
+    params.put("_UTCOffsetMiliseconds", "7200000");
+    params.put("operator", "and");
+    params.put("_constructor", "AdvancedCriteria");
+    params.put("criteria", getFilterCriteria().toString());
+    return params;
+  }
+
+  private JSONArray getFilterCriteria() {
+    JSONArray criteria = new JSONArray();
+    try {
+      JSONObject criteriaObj = new JSONObject();
+      criteriaObj.put("fieldName", "creationDate");
+      criteriaObj.put("operator", "equals");
+      criteriaObj.put("value", "2017-12-04");
+      criteriaObj.put("minutesTimezoneOffset", "120");
+      criteriaObj.put("_constructor", "AdvancedCriteria");
+      criteria.put(criteriaObj);
+    } catch (JSONException ignore) {
+    }
+    return criteria;
+  }
+
+  private String getExpectedResult() {
+    JSONObject country = new JSONObject();
+    try {
+      country.put("iSOCountryCode", "IM");
+      country.put("name", "Isle of Man");
+      country.put("addressPrintFormat", "@C@,  @P@");
+      country.put("currency", "114");
+      country.put("hasRegions", false);
+    } catch (JSONException ignore) {
+    }
+    return country.toString();
+  }
+
+  private class TestQueryResultWriter extends QueryResultWriter {
+    private String entityName;
+    private List<String> fieldProperties;
+    private StringBuilder builder;
+
+    TestQueryResultWriter(String entityName, List<String> fieldProperties) {
+      this.entityName = entityName;
+      this.fieldProperties = fieldProperties;
+      builder = new StringBuilder();
+    }
+
+    @Override
+    public void write(JSONObject row) {
+      try {
+        JSONObject json = new JSONObject();
+        for (String property : fieldProperties) {
+          if (!row.has(property)) {
+            continue;
+          }
+          json.put(property, row.get(property));
+        }
+        builder.append(json.toString());
+      } catch (Exception ex) {
+        throw new OBException("Could not write results: " + row, ex);
+      }
+    }
+
+    String getEntityName() {
+      return entityName;
+    }
+
+    String getFieldProperties() {
+      return StringCollectionUtils.commaSeparated(fieldProperties, false);
+    }
+
+    String getResults() {
+      return builder.toString();
+    }
+  }
+}
Binary file src-util/buildvalidation/build/classes/org/openbravo/buildvalidation/DatabaseVersionCheck.class has changed
--- a/src-util/buildvalidation/src/org/openbravo/buildvalidation/DatabaseVersionCheck.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src-util/buildvalidation/src/org/openbravo/buildvalidation/DatabaseVersionCheck.java	Thu May 09 09:05:05 2019 +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) 2015-2017 Openbravo SLU
+ * All portions are Copyright (C) 2015-2019 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  
  *************************************************************************
@@ -39,7 +39,7 @@
   private final static String POSTGRES = "PostgreSQL";
   private final static String ORACLE = "Oracle";
   private final static String MIN_PG_VERSION = "9.3";
-  private final static String MIN_ORA_VERSION = "11";
+  private final static String MIN_ORA_VERSION = "11.2";
   private final static String[] WARNING_PG_VERSIONS = {};
   private final static String[] WARNING_ORA_VERSIONS = {};
 
@@ -67,7 +67,7 @@
     if (databaseVersion != null && !StringUtils.isEmpty(databaseVersion)) {
       if (compareVersion(databaseVersion, minVersion) < 0) {
         String msg1 = "The current " + databaseType + " database version (" + databaseVersion
-            + ") is not supported.";
+            + ") is not supported. Minimum supported version is " + minVersion;
         String msg2 = "Please, visit the following link: http://wiki.openbravo.com/wiki/System_Requirements "
             + "to check the list of supported versions.";
         errors.add(msg1);
--- a/src-util/diagnostic/config/diagnostics.properties	Thu Apr 25 14:52:39 2019 -0400
+++ b/src-util/diagnostic/config/diagnostics.properties	Thu May 09 09:05:05 2019 +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) 2008-2016 Openbravo SLU 
+# * All portions are Copyright (C) 2008-2019 Openbravo SLU 
 # * All Rights Reserved. 
 # * Contributor(s):  ______________________________________.
 # ************************************************************************
@@ -20,7 +20,7 @@
 max.memory=512
 jvm-version=1.7
 
-db.ora.version=11.1
+db.ora.version=11.2
 db.ora.opencursors=3000
 db.ora.processes=150
 
--- a/src/org/openbravo/authentication/AuthenticationManager.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/authentication/AuthenticationManager.java	Thu May 09 09:05:05 2019 +0200
@@ -263,7 +263,7 @@
     // If the current license has unlimited number of WS calls no limit will be checked, so there is
     // no need to create a new register in the AD_Session table
     if (activationKey.hasUnlimitedWsAccess()) {
-      if (!AuthenticationManager.isStatelessRequest(request)) {
+      if (request != null && !AuthenticationManager.isStatelessRequest(request)) {
         // force creation of the http session in stateful WS requests
         request.getSession(true);
       }
--- a/src/org/openbravo/base/secureApp/LoginHandler.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/base/secureApp/LoginHandler.java	Thu May 09 09:05:05 2019 +0200
@@ -324,7 +324,6 @@
         goToRetry(res, vars, msg, title, "Error", action);
         return;
       }
-
       // Build checks
 
       if (sysInfo.getSystemStatus() == null || sysInfo.getSystemStatus().equals("RB70")
@@ -411,6 +410,11 @@
 
   }
 
+  /** Is current login for a back-office session */
+  protected boolean isBackOfficeLogin() {
+    return true;
+  }
+
   private String getUserStartPage(String userId, RoleDefaults rd, String target,
       String targetQueryString) {
     String startPage = null;
@@ -525,7 +529,8 @@
       jsonMsg.put("messageTitle", title);
       jsonMsg.put("messageText", msg);
 
-      if (loginHasError) {
+      if (loginHasError && isBackOfficeLogin()) {
+        // mobile apps expect session to be populated in case of backoffice restricted roles
         vars.clearSession(false);
       }
 
--- a/src/org/openbravo/dal/xml/XMLUtil.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/dal/xml/XMLUtil.java	Thu May 09 09:05:05 2019 +0200
@@ -87,8 +87,8 @@
   /** @return a new secure {@link TransformerHandler} */
   public TransformerHandler newSAXTransformerHandler() throws TransformerConfigurationException {
     final SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
-    tf.setAttribute(javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD, "");
-    tf.setAttribute(javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+    tf.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");
+    tf.setAttribute("http://javax.xml.XMLConstants/property/accessExternalStylesheet", "");
 
     return tf.newTransformerHandler();
   }
@@ -105,8 +105,8 @@
   /** @return a new secure {@link TransformerFactory} */
   public TransformerFactory newTransformerFactory() {
     TransformerFactory factory = TransformerFactory.newInstance();
-    factory.setAttribute(javax.xml.XMLConstants.ACCESS_EXTERNAL_DTD, "");
-    factory.setAttribute(javax.xml.XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+    factory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalDTD", "");
+    factory.setAttribute("http://javax.xml.XMLConstants/property/accessExternalStylesheet", "");
     return factory;
   }
 
--- a/src/org/openbravo/erpCommon/ad_callouts/SL_TaxCategory_Org.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_callouts/SL_TaxCategory_Org.java	Thu May 09 09:05:05 2019 +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) 2012-2016 Openbravo SLU
+ * All portions are Copyright (C) 2012-2019 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -46,8 +46,7 @@
     String whereClause = "";
 
     while ("".equals(taxCategoryId)) {
-      whereClause = "as tn where tn.node = '" + organization.getId() + "' and tn.client.id = '"
-          + organization.getClient().getId() + "'";
+      whereClause = "as tn where tn.node = :organizationId and tn.client.id = :clientId";
       OBCriteria<TaxCategory> taxCategory = OBDal.getInstance().createCriteria(TaxCategory.class);
       taxCategory.add(Restrictions.eq(TaxCategory.PROPERTY_ORGANIZATION, organization));
       taxCategory.add(Restrictions.eq(TaxCategory.PROPERTY_DEFAULT, true));
@@ -56,6 +55,8 @@
       TaxCategory taxCategoryObject = (!listTaxCategory.isEmpty() ? listTaxCategory.get(0) : null);
       if (taxCategoryObject == null && !"0".equals(organization.getId())) {
         OBQuery<TreeNode> query = OBDal.getInstance().createQuery(TreeNode.class, whereClause);
+        query.setNamedParameter("organizationId", organization.getId());
+        query.setNamedParameter("clientId", organization.getClient().getId());
         query.setMaxResult(1);
         List<TreeNode> listTreeNode = query.list();
         TreeNode treeNode = listTreeNode.get(0);
--- a/src/org/openbravo/erpCommon/ad_forms/FactLine.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_forms/FactLine.java	Thu May 09 09:05:05 2019 +0200
@@ -11,7 +11,7 @@
  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
  * created by ComPiere are Copyright (C) ComPiere, Inc.;   All Rights Reserved.
  * Contributor(s): Openbravo SLU
- * Contributions are Copyright (C) 2001-2017 Openbravo S.L.U.
+ * Contributions are Copyright (C) 2001-2019 Openbravo S.L.U.
  ******************************************************************************
  */
 package org.openbravo.erpCommon.ad_forms;
@@ -19,21 +19,18 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.sql.Connection;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
 
 import javax.servlet.ServletException;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
+import org.hibernate.query.NativeQuery;
 import org.openbravo.base.secureApp.VariablesSecureApp;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.dal.service.OBDal;
 import org.openbravo.database.ConnectionProvider;
 import org.openbravo.erpCommon.utility.SequenceIdData;
-import org.openbravo.exception.NoConnectionAvailableException;
 import org.openbravo.model.common.currency.ConversionRateDoc;
 import org.openbravo.model.common.currency.Currency;
 
@@ -1127,38 +1124,24 @@
   public StringBuffer getDescription(ConnectionProvider connectionProvider, String strC_Bpartner_ID,
       String strC_AcctSchema_ID, String strAD_Table_ID, String strRecord_ID, String strLine)
       throws ServletException {
-    String localStrLine = strLine;
     StringBuffer description = new StringBuffer();
     String strSql = AcctServerData.selectDescription(connectionProvider, strAD_Table_ID,
         strC_AcctSchema_ID);
     try {
-      if (!strSql.equals("")/* && strLine!=null && !strLine.equals("") */) {
-        strSql = strSql.replaceAll("@RecordId@", "'" + strRecord_ID + "'");
-        if (localStrLine == null || localStrLine.equals("")) {
-          localStrLine = "NULL";
-        } else {
-          localStrLine = "'" + localStrLine + "'";
+      if (!StringUtils.isBlank(strSql)) {
+        strSql = strSql.replaceAll("@RecordId@", ":paramRecordId")
+            .replaceAll("@Line@", ":paramLineId");
+
+        @SuppressWarnings("rawtypes")
+        NativeQuery query = OBDal.getInstance().getSession().createSQLQuery(strSql);
+        if (strSql.contains(":paramRecordId")) {
+          query.setParameter("paramRecordId", strRecord_ID);
         }
-        strSql = strSql.replaceAll("@Line@", localStrLine);
-        Statement st = connectionProvider.getStatement();
-        ResultSet result;
-        try {
-          if (st.execute(strSql)) {
-            result = st.getResultSet();
-            while (result.next()) {
-              description.append(result.getString(1));
-            }
-            result.close();
-          }
-        } catch (SQLException e) {
-          log4jFactLine.error("SQL error in query: " + strSql + "Exception:" + e);
-          throw new ServletException(Integer.toString(e.getErrorCode()));
-        } finally {
-          try {
-            connectionProvider.releaseStatement(st);
-          } catch (Exception ignored) {
-          }
+        if (strSql.contains(":paramLineId")) {
+          query.setParameter("paramLineId", StringUtils.isBlank(strLine) ? "NULL" : strLine);
         }
+        final String result = (String) query.uniqueResult();
+        description.append(StringUtils.defaultIfBlank(result, StringUtils.EMPTY));
       }
       if (description.length() == 0) {
         description.append((m_docVO.DocumentNo == null) ? "" : m_docVO.DocumentNo);
@@ -1180,11 +1163,6 @@
       if (description.length() > 255) {
         description = new StringBuffer(description.substring(0, 254));
       }
-    } catch (NoConnectionAvailableException ex) {
-      throw new ServletException("@CODE=NoConnectionAvailable");
-    } catch (SQLException ex2) {
-      throw new ServletException(
-          "@CODE=" + Integer.toString(ex2.getErrorCode()) + "@" + ex2.getMessage());
     } catch (Exception ex3) {
       throw new ServletException("@CODE=@" + ex3.getMessage());
     }
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports.java	Thu May 09 09:05:05 2019 +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-2018 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -33,6 +33,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
@@ -152,7 +153,7 @@
       String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strcAcctSchemaId);
+      out.print(StringEscapeUtils.escapeHtml(strcAcctSchemaId));
       out.close();
     } else if (vars.commandIn("CMBORG")) {
       String strAccSchema = vars.getStringParameter("inpcAcctSchemaId");
@@ -693,7 +694,7 @@
     }
     xmlDocument.setParameter("orgs", Utility.arrayDobleEntrada("arrOrgs", new FieldProvider[0]));
     xmlDocument.setParameter("accountingReports", Utility.arrayDobleEntrada("arrAccountingReports",
-        GeneralAccountingReportsData.selectRptDouble(readOnlyCP)));
+        GeneralAccountingReportsData.selectRptDouble(readOnlyCP, OBContext.getOBContext().getRole().getId())));
     xmlDocument.setParameter("years", Utility.arrayDobleEntrada("arrYears", new FieldProvider[0]));
     response.setContentType("text/html; charset=UTF-8");
     PrintWriter out = response.getWriter();
--- a/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports_data.xsql	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/GeneralAccountingReports_data.xsql	Thu May 09 09:05:05 2019 +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-2016 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -46,12 +46,14 @@
    </SqlMethod>
    <SqlMethod name="selectRptDouble" type="preparedStatement" return="multiple">
       <SqlMethodComment></SqlMethodComment>
-      <Sql>
+      <Sql><![CDATA[
 		SELECT C_ACCT_RPT.C_ACCTSCHEMA_ID AS PADRE, COALESCE(REPORTTYPE,'N') || C_ACCT_RPT.C_ACCT_RPT_ID AS ID, C_ACCT_RPT.NAME AS NAME 
 		FROM C_ACCT_RPT
 		WHERE C_ACCT_RPT.ISACTIVE = 'Y'
+		AND EXISTS (SELECT 1 FROM AD_ROLE_ORGACCESS WHERE AD_ROLE_ORGACCESS.AD_ORG_ID = C_ACCT_RPT.AD_ORG_ID AND AD_ROLE_ORGACCESS.ISACTIVE = 'Y' AND AD_ROLE_ID = ?)	
 		ORDER BY NAME
-      </Sql>
+      ]]></Sql>
+      <Parameter name="roleId"/>
    </SqlMethod>
       
     <SqlMethod name="selectGroups" type="preparedStatement" return="multiple">
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedger.java	Thu May 09 09:05:05 2019 +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-2017 Openbravo SLU
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -28,6 +28,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.filter.IsIDFilter;
 import org.openbravo.base.secureApp.HttpSecureAppServlet;
@@ -225,7 +226,7 @@
       String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strcAcctSchemaId);
+      out.print(StringEscapeUtils.escapeHtml(strcAcctSchemaId));
       out.close();
     }
 
--- a/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportGeneralLedgerJournal.java	Thu May 09 09:05:05 2019 +0200
@@ -475,7 +475,7 @@
       String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strcAcctSchemaId);
+      out.print(StringEscapeUtils.escapeHtml(strcAcctSchemaId));
       out.close();
     } else {
       pageError(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportInvoiceCustomerDimensionalAnalysesJR.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportInvoiceCustomerDimensionalAnalysesJR.java	Thu May 09 09:05:05 2019 +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-2018 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -27,6 +27,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.filter.IsIDFilter;
 import org.openbravo.base.filter.IsPositiveIntFilter;
@@ -310,7 +311,7 @@
       }
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strOrgCurrencyId);
+      out.print(StringEscapeUtils.escapeHtml(strOrgCurrencyId));
       out.close();
     } else {
       pageErrorPopUp(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportMaterialDimensionalAnalysesJR.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportMaterialDimensionalAnalysesJR.java	Thu May 09 09:05:05 2019 +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-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -27,6 +27,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.filter.IsIDFilter;
 import org.openbravo.base.filter.IsPositiveIntFilter;
@@ -177,7 +178,7 @@
       }
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strOrgCurrencyId);
+      out.print(StringEscapeUtils.escapeHtml(strOrgCurrencyId));
       out.close();
     } else {
       pageErrorPopUp(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportSalesDimensionalAnalyzeJR.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportSalesDimensionalAnalyzeJR.java	Thu May 09 09:05:05 2019 +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-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -28,6 +28,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.filter.IsIDFilter;
 import org.openbravo.base.filter.IsPositiveIntFilter;
@@ -196,7 +197,7 @@
       }
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strOrgCurrencyId);
+      out.print(StringEscapeUtils.escapeHtml(strOrgCurrencyId));
       out.close();
     } else {
       pageErrorPopUp(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportShipmentDimensionalAnalyzeJR.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportShipmentDimensionalAnalyzeJR.java	Thu May 09 09:05:05 2019 +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-2017 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -27,6 +27,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.openbravo.base.filter.IsIDFilter;
 import org.openbravo.base.filter.IsPositiveIntFilter;
@@ -204,7 +205,7 @@
       }
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strOrgCurrencyId);
+      out.print(StringEscapeUtils.escapeHtml(strOrgCurrencyId));
       out.close();
     } else {
       pageErrorPopUp(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportTrialBalance.java	Thu May 09 09:05:05 2019 +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-2018 Openbravo SLU 
+ * All portions are Copyright (C) 2001-2019 Openbravo SLU 
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -33,6 +33,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
@@ -229,7 +230,7 @@
       String strcAcctSchemaId = OBLedgerUtils.getOrgLedger(strOrg);
       response.setContentType("text/html; charset=UTF-8");
       PrintWriter out = response.getWriter();
-      out.print(strcAcctSchemaId);
+      out.print(StringEscapeUtils.escapeHtml(strcAcctSchemaId));
       out.close();
     } else {
       pageError(response);
--- a/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock.java	Thu May 09 09:05:05 2019 +0200
@@ -196,7 +196,7 @@
       String strDateNext = DateTimeData.nDaysAfter(readOnlyCP, strDate, "1");
       String strMaxAggDate = ReportValuationStockData.selectMaxAggregatedDate(readOnlyCP,
           OBDal.getReadOnlyInstance().get(Organization.class, strLegalEntity).getClient().getId(),
-          strDate, orgIds);
+          strDateNext, orgIds);
       if (StringUtils.isEmpty(strMaxAggDate)) {
         DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
         Date maxAggDate = formatter.parse("01-01-0000");
--- a/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock_data.xsql	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/ad_reports/ReportValuationStock_data.xsql	Thu May 09 09:05:05 2019 +0200
@@ -53,8 +53,8 @@
                                  WHERE dateacct < to_date(?)
                                    AND dateacct > to_date(?)
                                  GROUP BY m_transaction_id, c_currency_id) tc ON trx.m_transaction_id = tc.m_transaction_id
-                    WHERE trx.MOVEMENTDATE < to_date(?)
-                    AND trx.MOVEMENTDATE > to_date(?)
+                    WHERE TRUNC(trx.MOVEMENTDATE) < to_date(?)
+                    AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
                     AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
                     AND trx.ad_org_id IN ('1')
                     AND 0=0
@@ -157,8 +157,8 @@
             JOIN M_PRODUCT p ON trx.m_product_id = p.m_product_id
             JOIN M_TRANSACTION_COST tc ON trx.m_transaction_id = tc.m_transaction_id AND tc.dateacct < to_date(?)
               AND tc.dateacct > to_date(?)
-          WHERE trx.MOVEMENTDATE < to_date(?)
-            AND trx.MOVEMENTDATE > to_date(?)
+          WHERE TRUNC(trx.MOVEMENTDATE) < to_date(?)
+            AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
             AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
             AND trx.ad_org_id IN ('1')
             AND trx.iscostcalculated = 'Y'
@@ -219,8 +219,8 @@
         JOIN m_transaction trx ON trx.m_product_id = p.m_product_id
         JOIN m_locator l ON trx.m_locator_id = l.m_locator_id
       WHERE trx.iscostcalculated = 'N'
-        AND trx.MOVEMENTDATE < to_date(?)
-        AND trx.MOVEMENTDATE > to_date(?)
+        AND TRUNC(trx.MOVEMENTDATE) < to_date(?)
+        AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
         AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
         AND  trx.ad_org_id IN ('2')
         AND 2 = 2
@@ -305,8 +305,8 @@
                                  WHERE dateacct < to_date(?)
                                    AND dateacct > to_date(?)
                                  GROUP BY m_transaction_id, c_currency_id) tc ON trx.m_transaction_id = tc.m_transaction_id
-                    WHERE trx.MOVEMENTDATE < to_date(?)
-                    AND trx.MOVEMENTDATE > to_date(?)
+                    WHERE TRUNC(trx.MOVEMENTDATE) < to_date(?)
+                    AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
                     AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
                     AND trx.ad_org_id IN ('1')
                     AND 0=0
@@ -380,8 +380,8 @@
             JOIN M_PRODUCT p ON trx.m_product_id = p.m_product_id
             JOIN M_TRANSACTION_COST tc ON trx.m_transaction_id = tc.m_transaction_id 
               AND tc.dateacct < to_date(?) AND tc.dateacct > to_date(?)
-          WHERE trx.MOVEMENTDATE < to_date(?)
-            AND trx.MOVEMENTDATE > to_date(?)
+          WHERE TRUNC(trx.MOVEMENTDATE) < to_date(?)
+            AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
             AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
             AND trx.ad_org_id IN ('1')
             AND trx.iscostcalculated = 'Y'
@@ -423,8 +423,8 @@
         JOIN m_transaction trx ON trx.m_product_id = p.m_product_id
         JOIN m_locator l ON trx.m_locator_id = l.m_locator_id
       WHERE trx.iscostcalculated = 'N'
-        AND trx.MOVEMENTDATE < to_date(?)
-        AND trx.MOVEMENTDATE > to_date(?)
+        AND TRUNC(trx.MOVEMENTDATE) < to_date(?)
+        AND TRUNC(trx.MOVEMENTDATE) > to_date(?)
         AND trx.TRXPROCESSDATE >= to_timestamp(?, ?)
         AND  trx.ad_org_id IN ('2')
         AND 2 = 2
--- a/src/org/openbravo/erpCommon/businessUtility/Preferences.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/businessUtility/Preferences.java	Thu May 09 09:05:05 2019 +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) 2010-2018 Openbravo SLU
+ * All portions are Copyright (C) 2010-2019 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
@@ -20,6 +20,7 @@
 package org.openbravo.erpCommon.businessUtility;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -34,7 +35,6 @@
 import org.openbravo.erpCommon.utility.PropertyConflictException;
 import org.openbravo.erpCommon.utility.PropertyException;
 import org.openbravo.erpCommon.utility.PropertyNotFoundException;
-import org.openbravo.erpCommon.utility.StringCollectionUtils;
 import org.openbravo.erpCommon.utility.Utility;
 import org.openbravo.model.ad.access.Role;
 import org.openbravo.model.ad.access.User;
@@ -430,16 +430,18 @@
       }
       hql.append("        p.visibleAtRole is null) ");
 
+      List<String> parentOrgs;
       if (org == null) {
-        hql.append("     and coalesce(p.visibleAtOrganization, '0')='0'");
+        parentOrgs = Arrays.asList("0");
       } else {
-        List<String> parentTree = OBContext.getOBContext()
+        parentOrgs = OBContext.getOBContext()
             .getOrganizationStructureProvider(client)
             .getParentList(org, true);
-        String parentOrgs = "(" + StringCollectionUtils.commaSeparated(parentTree) + ")";
-        hql.append("     and coalesce(p.visibleAtOrganization, '0') in " + parentOrgs);
       }
 
+      hql.append("     and coalesce(p.visibleAtOrganization.id, '0') in :parentOrgs");
+      parameters.put("parentOrgs", parentOrgs);
+
       if (user != null) {
         hql.append("  and (p.userContact.id = :userId or ");
         parameters.put("userId", user);
@@ -459,7 +461,8 @@
     }
 
     if (property != null) {
-      hql.append(" and p.propertyList = '" + (isListProperty ? "Y" : "N") + "'");
+      hql.append(" and p.propertyList = :isListProperty");
+      parameters.put("isListProperty", isListProperty);
       if (isListProperty) {
         hql.append(" and p.property = :property ");
       } else {
--- a/src/org/openbravo/erpCommon/security/Login.html	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/erpCommon/security/Login.html	Thu May 09 09:05:05 2019 +0200
@@ -43,13 +43,13 @@
 
 <script type="text/javascript">
 var validBrowserFirefox = '52.0.0.0';
-var validBrowserChrome = '71.0.0.0';
+var validBrowserChrome = '74.0.0.0';
 var validBrowserExplorer = '9.0.0.0';
 var validBrowserEdge = '42.0.0.0'; // EdgeHTML version
 var validBrowserSafari = '10.0.0.0';
 
 var recBrowserFirefox = '60.0.0.0';
-var recBrowserChrome = '72.0.0.0';
+var recBrowserChrome = '75.0.0.0';
 var recBrowserExplorer = '11.0.0.0';
 var recBrowserEdge = '44.0.0.0'; // EdgeHTML version
 var recBrowserSafari = '12.0.0.0';
--- a/src/org/openbravo/financial/ResetAccounting.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/financial/ResetAccounting.java	Thu May 09 09:05:05 2019 +0200
@@ -646,9 +646,10 @@
 
   private static boolean hasProcessingColumn(String strTableId) {
     int count = 0;
-    String hql = " select count(*) from ADColumn where table.id = '" + strTableId + "' "
+    String hql = " select count(*) from ADColumn where table.id = :tableId "
         + " and lower(dBColumnName) = 'processing'";
     Query<Long> query = OBDal.getInstance().getSession().createQuery(hql, Long.class);
+    query.setParameter("tableId", strTableId);
     count = query.list().get(0).intValue();
     return (count == 1);
   }
--- a/src/org/openbravo/materialmgmt/GenerateValuedStockAggregated_data.xsql	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/materialmgmt/GenerateValuedStockAggregated_data.xsql	Thu May 09 09:05:05 2019 +0200
@@ -64,7 +64,7 @@
                 SELECT trx.ad_client_id, trx.ad_org_id, trx.createdby, trx.updatedby, trx.m_product_id, trx.m_locator_id, trx.c_uom_id, trx.movementqty,
                   0 AS trxcost
                 FROM m_transaction trx
-                WHERE trx.movementdate <= TO_DATE(?)
+                WHERE TRUNC(trx.movementdate) <= TO_DATE(?)
                 AND 2=2
                 AND 4=4
                 AND 5=5
@@ -79,7 +79,7 @@
                 FROM(SELECT SUM(CASE WHEN t2.movementqty < 0 THEN -cost ELSE cost END) AS trxcost, t2.m_transaction_id, tc2.c_currency_id, COALESCE(dateacct, costdate) AS movementdate
                      FROM m_transaction_cost tc2
                      JOIN m_transaction t2 ON (tc2.m_transaction_id = t2.m_transaction_id)
-                     WHERE dateacct <= TO_DATE(?)
+                     WHERE TRUNC(dateacct) <= TO_DATE(?)
                      AND 3=3
                      AND 6=6
                      AND 7=7
@@ -110,7 +110,7 @@
     <Parameter name="cCurrencyID"/>
     <Parameter name="mCostingRuleID"/>
     <Parameter name="dateTo"/>
-    <Parameter name="startingDate" optional="true" after="AND 2=2"><![CDATA[ AND trx.movementdate > TO_DATE(?) ]]></Parameter>
+    <Parameter name="startingDate" optional="true" after="AND 2=2"><![CDATA[ AND TRUNC(trx.movementdate) > TO_DATE(?) ]]></Parameter>
     <Parameter name="crStartDate" optional="true" after="AND 4=4"><![CDATA[ AND trx.trxprocessdate >= to_timestamp(?, 'DD-MM-YYYY HH24:MI:SS') ]]></Parameter>
     <Parameter name="crEndDate" optional="true" after="AND 5=5"><![CDATA[ AND trx.trxprocessdate <= to_timestamp(?, 'DD-MM-YYYY HH24:MI:SS') ]]></Parameter>
     <Parameter name="adClientId"/>
@@ -118,7 +118,7 @@
     <Parameter name="cCurrencyID"/>
     <Parameter name="legalOrg"/>
     <Parameter name="dateTo"/>
-    <Parameter name="startingDate" optional="true" after="AND 3=3"><![CDATA[ AND dateacct > TO_DATE(?) ]]></Parameter>
+    <Parameter name="startingDate" optional="true" after="AND 3=3"><![CDATA[ AND TRUNC(dateacct) > TO_DATE(?) ]]></Parameter>
     <Parameter name="crStartDate" optional="true" after="AND 6=6"><![CDATA[ AND t2.trxprocessdate >= to_timestamp(?, 'DD-MM-YYYY HH24:MI:SS') ]]></Parameter>
     <Parameter name="crEndDate" optional="true" after="AND 7=7"><![CDATA[ AND t2.trxprocessdate <= to_timestamp(?, 'DD-MM-YYYY HH24:MI:SS') ]]></Parameter>
     <Parameter name="adClientId"/>
--- a/src/org/openbravo/service/importprocess/ImportEntryManager.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/service/importprocess/ImportEntryManager.java	Thu May 09 09:05:05 2019 +0200
@@ -153,6 +153,10 @@
   // default to number of processors plus some additionals for the main threads
   private int numberOfThreads = Runtime.getRuntime().availableProcessors() + 3;
 
+  // used to determine the time to wait after each cycle before querying for new entries to be
+  // processed
+  private int processingCapacityPerSecond;
+
   // defines the batch size of reading and processing import entries by the
   // main thread, for each type of data the batch size is being read
   private int importBatchSize = 5000;
@@ -178,9 +182,18 @@
     maxTaskQueueSize = ImportProcessUtils.getCheckIntProperty(log, "import.max.task.queue.size",
         maxTaskQueueSize, 50);
     managerWaitTime = ImportProcessUtils.getCheckIntProperty(log, "import.wait.time", 600, 1);
+    processingCapacityPerSecond = ImportProcessUtils.getCheckIntProperty(log,
+        "import.processing.capacity.per.second", numberOfThreads * 30, 10);
 
     // property defined in secs, convert to ms
     managerWaitTime = managerWaitTime * 1000;
+
+    log.info("Import entry manager settings");
+    log.info("  batch size: {}", importBatchSize);
+    log.info("  number of threads: {}", numberOfThreads);
+    log.info("  task queue size: {}", maxTaskQueueSize);
+    log.info("  wait time: {} sec", managerWaitTime);
+    log.info("  processing capacity per second: {} entries", processingCapacityPerSecond);
   }
 
   public synchronized void start() {
@@ -613,23 +626,24 @@
             if (entryCount > 0) {
               // if there was data then just wait some time
               // give the threads time to process it all before trying
-              // a next batch of entries
+              // a next batch of entries to prevent retrieving from DB the same records we have just
+              // handled in this cycle
               try {
-                // wait one second per 30 records, somewhat arbitrary
-                // but high enough for most cases, also always wait 300 millis additional to
-                // start up threads etc.
+                // wait processingCapacityPerSecond which is the expected entries number of entries
+                // that can be processed per second, it defaults to one second per 30 records per
+                // thread, somewhat arbitrary but high enough for most cases, also always wait 300
+                // milliseconds additional to start up threads etc.
                 // note computation of timing ensures that int rounding is done on 1000* entrycount
-                if (isTest) {
-                  // in case of test don't wait minimal 2 seconds
-                  Thread.sleep(300 + ((1000 * entryCount) / 30));
-                } else {
-                  // wait minimal 2 seconds or based on entry count
-                  long t = Math.max(2000, 300 + ((1000 * entryCount) / 30));
-                  log.debug(
-                      "{} entries have been processed. Wait {} ms, and try again to capture new entries which have been added",
-                      entryCount, t);
-                  Thread.sleep(t);
-                }
+
+                // wait minimal 2 seconds or based on entry count, no minimal wait in case of test
+                int minWait = isTest ? 0 : 2_000;
+                long t = Math.max(minWait,
+                    300 + ((1_000 * entryCount) / manager.processingCapacityPerSecond));
+
+                log.debug(
+                    "{} entries have been handled. Wait {} ms, and try again to capture new entries which have been added",
+                    entryCount, t);
+                Thread.sleep(t);
               } catch (Exception ignored) {
               }
             } else {
@@ -702,7 +716,9 @@
   private static class ImportStatistics {
     private String typeOfData;
     private long cnt;
+    private long cntPartial;
     private long totalTime;
+    private long totalTimePartial;
 
     public void setTypeOfData(String typeOfData) {
       this.typeOfData = typeOfData;
@@ -714,11 +730,16 @@
 
     public synchronized void addTiming(long timeForEntry) {
       cnt++;
+      cntPartial++;
       totalTime += timeForEntry;
+      totalTimePartial += timeForEntry;
     }
 
     public synchronized void log() {
-      log.info("Timings for " + typeOfData + " cnt: " + cnt + " avg millis: " + (totalTime / cnt));
+      log.info("Timings for {}. Partial [cnt: {}, avg: {} ms] - Total [cnt: {}, avg: {} ms]",
+          typeOfData, cntPartial, totalTimePartial / cntPartial, cnt, totalTime / cnt);
+      cntPartial = 0;
+      totalTimePartial = 0;
     }
   }
 
--- a/src/org/openbravo/service/importprocess/ImportEntryProcessor.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/service/importprocess/ImportEntryProcessor.java	Thu May 09 09:05:05 2019 +0200
@@ -176,8 +176,8 @@
     // give it the entry
     runnable.setImportEntryManager(importEntryManager);
     runnable.setImportEntryProcessor(this);
+    runnable.setKey(key);
     runnable.addEntry(importEntry);
-    runnable.setKey(key);
 
     // and make sure it can get next entries by caching it
     runnables.put(key, runnable);
@@ -366,14 +366,14 @@
           final String typeOfData = localImportEntry.getTypeofdata();
 
           if (logger.isDebugEnabled()) {
-            logger.debug("Processing entry " + localImportEntry.getIdentifier() + " " + typeOfData);
+            logger.debug("Processing entry {} {}", localImportEntry.getIdentifier(), typeOfData);
           }
 
           processEntry(localImportEntry);
 
           if (logger.isDebugEnabled()) {
-            logger.debug(
-                "Finished Processing entry " + localImportEntry.getIdentifier() + " " + typeOfData);
+            logger.debug("Finished Processing entry {} {} in {} ms",
+                localImportEntry.getIdentifier(), typeOfData, System.currentTimeMillis() - t0);
           }
 
           // don't use the import entry anymore, touching methods on it
@@ -540,20 +540,22 @@
       // prevents memory problems
       if (importEntries.size() > MAX_QUEUE_SIZE) {
         // set to level debug until other changes have been made in subclassing code
-        logger.debug("Ignoring import entry, will be reprocessed later, too many queue entries "
-            + importEntries.size());
+        logger.warn(
+            "Ignoring import entry {} - {}, will be reprocessed later, too many queue entries {}",
+            importEntry.getTypeofdata(), key, importEntries.size());
         return;
       }
 
       if (!importEntryIds.contains(importEntry.getId())) {
-        logger.debug("Adding entry to runnable with key " + key);
+        logger.debug("Adding entry to runnable with key {} - {}", importEntry.getTypeofdata(), key);
 
         importEntryIds.add(importEntry.getId());
         // cache a queued entry as it has a much lower mem foot print than the import
         // entry itself
         importEntries.add(new QueuedEntry(importEntry));
       } else {
-        logger.debug("Not adding entry, it is already in the list of ids " + importEntry.getId());
+        logger.debug("Not adding entry, it is already in the list of ids {} - {} - {} ",
+            importEntry.getTypeofdata(), key, importEntry.getId());
       }
     }
 
--- a/src/org/openbravo/service/system/DatabaseValidator.java	Thu Apr 25 14:52:39 2019 -0400
+++ b/src/org/openbravo/service/system/DatabaseValidator.java	Thu May 09 09:05:05 2019 +0200
@@ -159,14 +159,6 @@
       }
     }
 
-    final OBCriteria<Table> tcs = OBDal.getInstance().createCriteria(Table.class);
-    tcs.add(Restrictions.eq(Table.PROPERTY_VIEW, false));
-    final List<Table> adTables = tcs.list();
-    final Map<String, Table> adTablesByName = new HashMap<String, Table>();
-    for (Table adTable : adTables) {
-      adTablesByName.put(adTable.getDBTableName(), adTable);
-    }
-
     // the following cases are checked:
     // 1) table present in ad, but not in db
     // 2) table present in db, not in ad
@@ -192,14 +184,14 @@
       dbViews.put(view.getName().toUpperCase(), view);
     }
 
+    final List<Table> adTables = OBDal.getInstance()
+        .createCriteria(Table.class)
+        .add(Restrictions.eq(Table.PROPERTY_VIEW, false))
+        .add(Restrictions.eq(Table.PROPERTY_DATAORIGINTYPE, ApplicationConstants.TABLEBASEDTABLE))
+        .list();
+
     final String moduleId = (getValidateModule() == null ? null : getValidateModule().getId());
     for (Table adTable : adTables) {
-
-      // Do not validate the table if it is based on a datasource
-      if (!ApplicationConstants.TABLEBASEDTABLE.equals(adTable.getDataOriginType())) {
-        continue;
-      }
-
       final org.apache.ddlutils.model.Table dbTable = dbTablesByName
           .get(adTable.getDBTableName().toUpperCase());
       final View view = dbViews.get(adTable.getDBTableName().toUpperCase());
@@ -264,6 +256,7 @@
 
     checkKillableImplementation(result);
 
+    OBDal.getInstance().getSession().clear();
     return result;
   }