fixes issue 32231: wrong number comparison when checking field access of a role
authorCarlos Aristu <carlos.aristu@openbravo.com>
Tue, 16 Feb 2016 10:15:42 +0100
changeset 28606 c400203ec54f
parent 28605 0301db6b51d5
child 28607 5435ecfe6c1f
fixes issue 32231: wrong number comparison when checking field access of a role

When checking the access of a numeric field, if it is an integer, the client sends the value without decimal places. This value is compared with the current value stored in the database which already stores the value with decimals. So, the comparison of the string values determines that they are different as for example we are comparing '100' with '100.00'.

To solve the problem, for this type of fields now the numeric value is compared instead of using its string representation.
modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java
--- a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Fri Feb 05 14:06:10 2016 +0100
+++ b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DefaultDataSourceService.java	Tue Feb 16 10:15:42 2016 +0100
@@ -11,13 +11,14 @@
  * 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-2015 Openbravo SLU
+ * All portions are Copyright (C) 2010-2016 Openbravo SLU
  * All Rights Reserved. 
  * Contributor(s):  ______________________________________.
  ************************************************************************
  */
 package org.openbravo.service.datasource;
 
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -252,10 +253,15 @@
       fieldQuery.setNamedParameter("tabId", tab.getId());
       fieldQuery.setNamedParameter("roleId", roleId);
       for (Field f : fieldQuery.list()) {
-        String key = KernelUtils.getProperty(f).getName();
+        Property property = KernelUtils.getProperty(f);
+        String key = property.getName();
         if (data.has(key)) {
           String newValue = getValue(data, key);
           String oldValue = getValue(oldData, key);
+          if (property.isPrimitive() && property.isNumericType()
+              && isSameNumericValue(newValue, oldValue)) {
+            continue;
+          }
           if (oldValue == null && newValue != null || oldValue != null
               && !oldValue.equals(newValue)) {
             throw new RuntimeException(KernelUtils.getInstance().getI18N(
@@ -284,6 +290,17 @@
       return val.toString();
   }
 
+  private static boolean isSameNumericValue(String str1, String str2) {
+    try {
+      BigDecimal bd1 = new BigDecimal(str1);
+      BigDecimal bd2 = new BigDecimal(str2);
+      return bd1.doubleValue() == bd2.doubleValue();
+    } catch (NumberFormatException nfex) {
+      log4j.error("Could not compare numeric values", nfex);
+    }
+    return false;
+  }
+
   public List<DataSourceProperty> getDataSourceProperties(Map<String, Object> parameters) {
     final Entity entity = getEntity();
     final List<DataSourceProperty> dsProperties;