Fixed bug 26689 Return from customer pick lines does not keep selected lines
authorSandra Huguet <sandra.huguet@openbravo.com>
Thu, 29 May 2014 12:35:15 +0200
changeset 23406 eece3bb3d696
parent 23405 85730acf7b16
child 23407 2b23a4e38022
Fixed bug 26689 Return from customer pick lines does not keep selected lines
src-db/database/sourcedata/AD_TAB.xml
src-db/database/sourcedata/AD_TABLE.xml
src-db/database/sourcedata/OBUIAPP_PARAMETER.xml
src/org/openbravo/common/datasource/ResultMapCriteriaUtils.java
src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineDatasource.java
src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineRow.java
--- a/src-db/database/sourcedata/AD_TAB.xml	Wed May 28 13:23:22 2014 +0200
+++ b/src-db/database/sourcedata/AD_TAB.xml	Thu May 29 12:35:15 2014 +0200
@@ -18104,6 +18104,7 @@
 <!--F4204696A73647E2AA9700106C00C7A5-->  <DISABLE_PARENT_KEY_PROPERTY><![CDATA[N]]></DISABLE_PARENT_KEY_PROPERTY>
 <!--F4204696A73647E2AA9700106C00C7A5-->  <ISREADONLYTREE><![CDATA[N]]></ISREADONLYTREE>
 <!--F4204696A73647E2AA9700106C00C7A5-->  <ISSHOWTREENODEICONS><![CDATA[Y]]></ISSHOWTREENODEICONS>
+<!--F4204696A73647E2AA9700106C00C7A5-->  <EM_OBUIAPP_SELECTION><![CDATA[OB.RM.RMOrderSelectionChange]]></EM_OBUIAPP_SELECTION>
 <!--F4204696A73647E2AA9700106C00C7A5-->  <EM_OBUIAPP_CAN_ADD><![CDATA[N]]></EM_OBUIAPP_CAN_ADD>
 <!--F4204696A73647E2AA9700106C00C7A5-->  <EM_OBUIAPP_CAN_DELETE><![CDATA[N]]></EM_OBUIAPP_CAN_DELETE>
 <!--F4204696A73647E2AA9700106C00C7A5-->  <EM_OBUIAPP_SHOW_SELECT><![CDATA[Y]]></EM_OBUIAPP_SHOW_SELECT>
--- a/src-db/database/sourcedata/AD_TABLE.xml	Wed May 28 13:23:22 2014 +0200
+++ b/src-db/database/sourcedata/AD_TABLE.xml	Thu May 29 12:35:15 2014 +0200
@@ -11031,7 +11031,8 @@
 <!--A9BC62219E644720867F6402B0C25933-->  <TABLENAME><![CDATA[C_RM_RFC_PE_LINES]]></TABLENAME>
 <!--A9BC62219E644720867F6402B0C25933-->  <CLASSNAME><![CDATA[C_RM_RFC_PE_LINES]]></CLASSNAME>
 <!--A9BC62219E644720867F6402B0C25933-->  <ISVIEW><![CDATA[N]]></ISVIEW>
-<!--A9BC62219E644720867F6402B0C25933-->  <ACCESSLEVEL><![CDATA[3]]></ACCESSLEVEL>
+<!--A9BC62219E644720867F6402B0C25933-->  <ACCESSLEVEL><![CDATA[1]]></ACCESSLEVEL>
+<!--A9BC62219E644720867F6402B0C25933-->  <AD_WINDOW_ID><![CDATA[FF808081330213E60133021822E40007]]></AD_WINDOW_ID>
 <!--A9BC62219E644720867F6402B0C25933-->  <ISSECURITYENABLED><![CDATA[N]]></ISSECURITYENABLED>
 <!--A9BC62219E644720867F6402B0C25933-->  <ISDELETEABLE><![CDATA[Y]]></ISDELETEABLE>
 <!--A9BC62219E644720867F6402B0C25933-->  <ISHIGHVOLUME><![CDATA[N]]></ISHIGHVOLUME>
--- a/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Wed May 28 13:23:22 2014 +0200
+++ b/src-db/database/sourcedata/OBUIAPP_PARAMETER.xml	Thu May 29 12:35:15 2014 +0200
@@ -318,7 +318,7 @@
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <FIELDLENGTH><![CDATA[0]]></FIELDLENGTH>
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <ISMANDATORY><![CDATA[N]]></ISMANDATORY>
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <AD_ELEMENT_ID><![CDATA[B27C7AF72FEFEC33E040007F0100076A]]></AD_ELEMENT_ID>
-<!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <ISFIXED><![CDATA[N]]></ISFIXED>
+<!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <ISFIXED><![CDATA[Y]]></ISFIXED>
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <EVALUATEFIXEDVALUE><![CDATA[N]]></EVALUATEFIXEDVALUE>
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <OBUIAPP_PROCESS_ID><![CDATA[30A4E65B69B14134A78C7B270D3502F7]]></OBUIAPP_PROCESS_ID>
 <!--DAC023BDC4D2413D9B5F9ECD5411E39D-->  <STARTINNEWLINE><![CDATA[N]]></STARTINNEWLINE>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/openbravo/common/datasource/ResultMapCriteriaUtils.java	Thu May 29 12:35:15 2014 +0200
@@ -0,0 +1,520 @@
+package org.openbravo.common.datasource;
+
+import java.math.BigDecimal;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+import org.codehaus.jettison.json.JSONArray;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
+import org.openbravo.base.structure.BaseOBObject;
+import org.openbravo.service.json.JsonUtils;
+
+class ResultMapCriteriaUtils {
+  private static final String CRITERIA_KEY = "criteria";
+  private static final String VALUE_KEY = "value";
+  private static final String FIELD_NAME_KEY = "fieldName";
+  private static final String OPERATOR_KEY = "operator";
+
+  private static final String OPERATOR_AND = "and";
+  private static final String OPERATOR_OR = "or";
+
+  private static final String OPERATOR_EQUALS = "equals";
+  private static final String OPERATOR_NOTEQUAL = "notEqual";
+  private static final String OPERATOR_IEQUALS = "iEquals";
+  private static final String OPERATOR_INOTEQUAL = "iNotEqual";
+  private static final String OPERATOR_GREATERTHAN = "greaterThan";
+  private static final String OPERATOR_LESSTHAN = "lessThan";
+  private static final String OPERATOR_GREATEROREQUAL = "greaterOrEqual";
+  private static final String OPERATOR_LESSOREQUAL = "lessOrEqual";
+  private static final String OPERATOR_IGREATERTHAN = "iGreaterThan";
+  private static final String OPERATOR_ILESSTHAN = "iLessThan";
+  private static final String OPERATOR_IGREATEROREQUAL = "iGreaterOrEqual";
+  private static final String OPERATOR_ILESSOREQUAL = "iLessOrEqual";
+  private static final String OPERATOR_CONTAINS = "contains";
+  private static final String OPERATOR_STARTSWITH = "startsWith";
+  private static final String OPERATOR_ENDSWITH = "endsWith";
+  private static final String OPERATOR_ICONTAINS = "iContains";
+  private static final String OPERATOR_ISTARTSWITH = "iStartsWith";
+  private static final String OPERATOR_IENDSWITH = "iEndsWith";
+  private static final String OPERATOR_NOTCONTAINS = "notContains";
+  private static final String OPERATOR_NOTSTARTSWITH = "notStartsWith";
+  private static final String OPERATOR_NOTENDSWITH = "notEndsWith";
+  private static final String OPERATOR_INOTCONTAINS = "iNotContains";
+  private static final String OPERATOR_INOTSTARTSWITH = "iNotStartsWith";
+  private static final String OPERATOR_INOTENDSWITH = "iNotEndsWith";
+  // private static final String OPERATOR_REGEXP = "regexp";
+  // private static final String OPERATOR_IREGEXP = "iregexp";
+  private static final String OPERATOR_ISNULL = "isNull";
+  private static final String OPERATOR_NOTNULL = "notNull";
+  private static final String OPERATOR_INSET = "inSet";
+  private static final String OPERATOR_NOTINSET = "notInSet";
+  private static final String OPERATOR_EQUALSFIELD = "equalsField";
+  private static final String OPERATOR_NOTEQUALFIELD = "notEqualField";
+  private static final String OPERATOR_GREATERTHANFIElD = "greaterThanField";
+  private static final String OPERATOR_LESSTHANFIELD = "lessThanField";
+  private static final String OPERATOR_GREATEROREQUALFIELD = "greaterOrEqualField";
+  private static final String OPERATOR_LESSOREQUALFIElD = "lessOrEqualField";
+  private static final String OPERATOR_CONTAINSFIELD = "containsField";
+  private static final String OPERATOR_STARTSWITHFIELD = "startsWithField";
+  private static final String OPERATOR_ENDSWITHFIELD = "endsWithField";
+  private static final String OPERATOR_NOT = "not";
+  private static final String OPERATOR_BETWEEN = "between";
+  private static final String OPERATOR_BETWEENINCLUSIVE = "betweenInclusive";
+  private static final String OPERATOR_IBETWEEN = "iBetween";
+  private static final String OPERATOR_IBETWEENINCLUSIVE = "iBetweenInclusive";
+  private static final String OPERATOR_EXISTS = "exists";
+
+  Map<String, Object> recordMap;
+  JSONArray criteriaArray;
+  boolean mainOperatorIsAnd;
+
+  private int UTCServerMinutesTimeZoneDiff = 0;
+  private int clientUTCMinutesTimeZoneDiff = 0;
+
+  private SimpleDateFormat simpleDateFormat = JsonUtils.createDateFormat();
+  private SimpleDateFormat simpleDateTimeFormat = JsonUtils.createJSTimeFormat();
+
+  ResultMapCriteriaUtils(Map<String, Object> orderMap, Map<String, String> parameters) {
+    JSONArray _criteriaArray = null;
+    try {
+      _criteriaArray = (JSONArray) JsonUtils.buildCriteria(parameters).get("criteria");
+    } catch (JSONException e) {
+      _criteriaArray = null;
+    }
+    String mainOperator = parameters.get("operator");
+
+    this.recordMap = orderMap;
+    this.criteriaArray = _criteriaArray;
+    this.mainOperatorIsAnd = OPERATOR_AND.equals(mainOperator);
+  }
+
+  boolean applyFilter() throws JSONException {
+    if (criteriaArray == null) {
+      return true;
+    }
+    boolean finalResult = mainOperatorIsAnd;
+    for (int i = 0; i < criteriaArray.length(); i++) {
+      // Each element of the criteria array is added assuming an OR statement.
+      JSONObject criteria = criteriaArray.getJSONObject(i);
+      boolean critResult = parseCriteria(criteria);
+      if (mainOperatorIsAnd) {
+        finalResult &= critResult;
+      } else {
+        finalResult |= critResult;
+      }
+    }
+    return finalResult;
+  }
+
+  private boolean parseCriteria(JSONObject jsonCriteria) throws JSONException {
+    // a constructor so the content is an advanced criteria
+    if (jsonCriteria.has("_constructor") || hasOrAndOperator(jsonCriteria)) {
+      return parseAdvancedCriteria(jsonCriteria);
+    }
+    return parseSingleClause(jsonCriteria);
+  }
+
+  private boolean hasOrAndOperator(JSONObject jsonCriteria) throws JSONException {
+    if (!jsonCriteria.has(OPERATOR_KEY)) {
+      return mainOperatorIsAnd;
+    }
+    return OPERATOR_OR.equals(jsonCriteria.get(OPERATOR_KEY))
+        || OPERATOR_AND.equals(jsonCriteria.get(OPERATOR_KEY));
+  }
+
+  private boolean parseSingleClause(JSONObject jsonCriteria) throws JSONException {
+    String operator = jsonCriteria.getString(OPERATOR_KEY);
+
+    if (operator.equals(OPERATOR_BETWEEN) || operator.equals(OPERATOR_BETWEENINCLUSIVE)
+        || operator.equals(OPERATOR_IBETWEEN) || operator.equals(OPERATOR_IBETWEENINCLUSIVE)) {
+      return parseBetween(jsonCriteria, operator, true);
+    }
+
+    Object value = jsonCriteria.has(VALUE_KEY) ? jsonCriteria.get(VALUE_KEY) : null;
+
+    if (operator.equals(OPERATOR_EXISTS)) {
+      // not supported
+      return mainOperatorIsAnd;
+    }
+
+    String fieldName = jsonCriteria.getString(FIELD_NAME_KEY);
+
+    // translate to a OR for each value
+    if (value instanceof JSONArray) {
+      final JSONArray jsonArray = (JSONArray) value;
+      final JSONObject advancedCriteria = new JSONObject();
+      advancedCriteria.put(OPERATOR_KEY, OPERATOR_OR);
+      final JSONArray subCriteria = new JSONArray();
+      for (int i = 0; i < jsonArray.length(); i++) {
+        final JSONObject subCriterion = new JSONObject();
+        subCriterion.put(OPERATOR_KEY, operator);
+        subCriterion.put(FIELD_NAME_KEY, fieldName);
+        subCriterion.put(VALUE_KEY, jsonArray.get(i));
+        subCriteria.put(i, subCriterion);
+      }
+      advancedCriteria.put(CRITERIA_KEY, subCriteria);
+      return parseAdvancedCriteria(advancedCriteria);
+    }
+
+    // Retrieves the UTC time zone offset of the client
+    if (jsonCriteria.has("minutesTimezoneOffset")) {
+      int clientMinutesTimezoneOffset = Integer.parseInt(jsonCriteria.get("minutesTimezoneOffset")
+          .toString());
+      Calendar now = Calendar.getInstance();
+      // Obtains the UTC time zone offset of the server
+      int serverMinutesTimezoneOffset = (now.get(Calendar.ZONE_OFFSET) + now
+          .get(Calendar.DST_OFFSET)) / (1000 * 60);
+      // Obtains the time zone offset between the server and the client
+      clientUTCMinutesTimeZoneDiff = clientMinutesTimezoneOffset;
+      UTCServerMinutesTimeZoneDiff = serverMinutesTimezoneOffset;
+    }
+
+    if (operator.equals(OPERATOR_ISNULL) || operator.equals(OPERATOR_NOTNULL)) {
+      value = null;
+    }
+
+    // if a comparison is done on an equal date then replace
+    // with a between start time and end time on that date
+    if (operator.equals(OPERATOR_EQUALS) || operator.equals(OPERATOR_EQUALSFIELD)) {
+      Object curValue = recordMap.get(fieldName);
+      if (curValue instanceof Date) {
+        if (operator.equals(OPERATOR_EQUALS)) {
+          return parseSimpleClause(fieldName, OPERATOR_GREATEROREQUAL, value)
+              && parseSimpleClause(fieldName, OPERATOR_LESSOREQUAL, value);
+
+        } else {
+          return parseSimpleClause(fieldName, OPERATOR_GREATEROREQUALFIELD, value)
+              && parseSimpleClause(fieldName, OPERATOR_LESSOREQUALFIElD, value);
+        }
+      }
+    }
+
+    return parseSimpleClause(fieldName, operator, value);
+  }
+
+  private boolean parseBetween(JSONObject jsonCriteria, String operator, boolean inclusive)
+      throws JSONException {
+    final String fieldName = jsonCriteria.getString(FIELD_NAME_KEY);
+    final Object start = jsonCriteria.get("start");
+    final Object end = jsonCriteria.get("end");
+    final boolean leftClause = parseSimpleClause(fieldName, getBetweenOperator(operator, false),
+        start);
+    final boolean rightClause = parseSimpleClause(fieldName, getBetweenOperator(operator, true),
+        end);
+    return leftClause && rightClause;
+  }
+
+  private boolean parseSimpleClause(String fieldName, String operator, Object value)
+      throws JSONException {
+
+    String hqlOperator = getHqlOperator(operator);
+    String strField = fieldName;
+    boolean filterIdentifier = false;
+    // if (strField.endsWith("$_identifier")) {
+    // strField = strField.substring(0, strField.length() - 12);
+    // filterIdentifier = true;
+    // }
+    Object mapValue = recordMap.get(strField);
+    if (operator.equals(OPERATOR_NOTNULL)) {
+      return mapValue != null;
+    } else if (operator.equals(OPERATOR_ISNULL)) {
+      return mapValue == null;
+    }
+
+    Object localValue = value;
+    if (ignoreCase(mapValue, operator)) {
+      localValue = localValue.toString().toUpperCase();
+    }
+
+    boolean returnVal = mainOperatorIsAnd;
+
+    if ("id".equals(strField)) {
+      // ID is always equals
+      returnVal = mapValue != JSONObject.NULL && ((String) localValue).equals((String) mapValue);
+    } else if (filterIdentifier) {
+      BaseOBObject currentVal = (BaseOBObject) mapValue;
+      String strCurrValIdentifier = currentVal.getIdentifier();
+      String strCurrentFilter = (String) localValue;
+      returnVal = StringUtils.containsIgnoreCase(strCurrValIdentifier, strCurrentFilter);
+    } else if (mapValue instanceof Boolean) {
+      returnVal = (Boolean) mapValue == (Boolean) localValue;
+    } else if (mapValue instanceof BigDecimal) {
+      BigDecimal filterValue = new BigDecimal((Integer) localValue);
+      int compare = filterValue.compareTo((BigDecimal) mapValue);
+      if ("=".equals(hqlOperator)) {
+        returnVal = compare == 0;
+      } else if ("!=".equals(hqlOperator)) {
+        returnVal = compare != 0;
+      } else if (">".equals(hqlOperator)) {
+        returnVal = compare > 0;
+      } else if (">=".equals(hqlOperator)) {
+        returnVal = compare >= 0;
+      } else if ("<".equals(hqlOperator)) {
+        returnVal = compare < 0;
+      } else if ("<=".equals(hqlOperator)) {
+        returnVal = compare <= 0;
+      }
+
+    } else if (mapValue instanceof Date) {
+      try {
+        Date filterValue;
+        try {
+          filterValue = simpleDateTimeFormat.parse(localValue.toString());
+        } catch (ParseException e) {
+          // When a DateTime column is filtered, plan Date values are used
+          // See issue https://issues.openbravo.com/view.php?id=23203
+          filterValue = simpleDateFormat.parse(localValue.toString());
+        }
+        final Calendar calendar = Calendar.getInstance();
+        calendar.setTime(filterValue);
+        // Applies the time zone offset difference of the client
+        calendar.add(Calendar.MINUTE, clientUTCMinutesTimeZoneDiff);
+        // move the date to the beginning of the day
+        if (isGreaterOperator(operator)) {
+          calendar.set(Calendar.HOUR, 0);
+          calendar.set(Calendar.MINUTE, 0);
+          calendar.set(Calendar.SECOND, 0);
+          calendar.set(Calendar.MILLISECOND, 0);
+        } else if (isLesserOperator(operator)) {
+          // move the data to the end of the day
+          calendar.set(Calendar.HOUR, 23);
+          calendar.set(Calendar.MINUTE, 59);
+          calendar.set(Calendar.SECOND, 59);
+          calendar.set(Calendar.MILLISECOND, 999);
+        }
+        // Applies the time zone offset difference of the server
+        calendar.add(Calendar.MINUTE, -UTCServerMinutesTimeZoneDiff);
+        Date mapDate = (Date) mapValue;
+        boolean isBefore = mapDate.before(calendar.getTime());
+        boolean isAfter = mapDate.after(calendar.getTime());
+        boolean sameDate = mapDate.compareTo(calendar.getTime()) == 0;
+        if ("=".equals(hqlOperator)) {
+          returnVal = sameDate;
+        } else if ("!=".equals(hqlOperator)) {
+          returnVal = !sameDate;
+        } else if (">".equals(hqlOperator)) {
+          returnVal = isAfter;
+        } else if (">=".equals(hqlOperator)) {
+          returnVal = isAfter || sameDate;
+        } else if ("<".equals(hqlOperator)) {
+          returnVal = isBefore;
+        } else if ("<=".equals(hqlOperator)) {
+          returnVal = isBefore || sameDate;
+        }
+      } catch (Exception e) {
+        throw new IllegalArgumentException(e);
+      }
+    } else if (mapValue instanceof String) {
+      String strCurrentValue = (String) mapValue;
+      String strCurrentFilter = (String) localValue;
+      returnVal = StringUtils.containsIgnoreCase(strCurrentValue, strCurrentFilter);
+    }
+
+    if (isNot(operator)) {
+      return !returnVal;
+    } else {
+      return returnVal;
+    }
+  }
+
+  private boolean isGreaterOperator(String operator) {
+    return operator != null
+        && (operator.equals(OPERATOR_GREATERTHAN) || operator.equals(OPERATOR_GREATEROREQUAL)
+            || operator.equals(OPERATOR_IGREATERTHAN) || operator.equals(OPERATOR_IGREATEROREQUAL)
+            || operator.equals(OPERATOR_GREATERTHANFIElD) || operator
+              .equals(OPERATOR_GREATEROREQUALFIELD));
+  }
+
+  private boolean isLesserOperator(String operator) {
+    return operator != null
+        && (operator.equals(OPERATOR_LESSTHAN) || operator.equals(OPERATOR_LESSOREQUAL)
+            || operator.equals(OPERATOR_ILESSTHAN) || operator.equals(OPERATOR_ILESSOREQUAL)
+            || operator.equals(OPERATOR_LESSTHANFIELD) || operator
+              .equals(OPERATOR_LESSOREQUALFIElD));
+  }
+
+  private boolean parseAdvancedCriteria(JSONObject advancedCriteria) throws JSONException {
+    final String operator = advancedCriteria.getString(OPERATOR_KEY);
+    if (operator.equals(OPERATOR_NOT)) {
+      final boolean clause = parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY),
+          OPERATOR_OR);
+      return !clause;
+    }
+    if (operator.equals(OPERATOR_AND)) {
+      return parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY), OPERATOR_AND);
+    }
+    if (operator.equals(OPERATOR_OR)) {
+      final boolean value = parseStructuredClause(advancedCriteria.getJSONArray(CRITERIA_KEY),
+          OPERATOR_OR);
+      return value;
+    }
+    return parseSingleClause(advancedCriteria);
+  }
+
+  private boolean parseStructuredClause(JSONArray clauses, String hqlOperator) throws JSONException {
+    boolean doOr = OPERATOR_OR.equals(hqlOperator);
+    boolean doAnd = OPERATOR_AND.equals(hqlOperator);
+    for (int i = 0; i < clauses.length(); i++) {
+      final JSONObject clause = clauses.getJSONObject(i);
+      if (clause.has(VALUE_KEY) && clause.get(VALUE_KEY) != null
+          && clause.getString(VALUE_KEY).equals("")) {
+        continue;
+      }
+      final boolean clauseResult = parseCriteria(clause);
+      if (doOr && clauseResult) {
+        return true;
+      }
+      if (doAnd && !clauseResult) {
+        return false;
+      }
+    }
+    if (doOr) {
+      return false;
+    } else if (doAnd) {
+      return true;
+    }
+    return mainOperatorIsAnd;
+  }
+
+  private String getBetweenOperator(String operator, boolean rightClause) {
+    if (operator.equals(OPERATOR_IBETWEEN)) {
+      if (rightClause) {
+        return OPERATOR_ILESSTHAN;
+      } else {
+        return OPERATOR_IGREATERTHAN;
+      }
+    }
+    if (operator.equals(OPERATOR_BETWEEN)) {
+      if (rightClause) {
+        return OPERATOR_LESSTHAN;
+      } else {
+        return OPERATOR_GREATERTHAN;
+      }
+    }
+    if (operator.equals(OPERATOR_IBETWEENINCLUSIVE)) {
+      if (rightClause) {
+        return OPERATOR_ILESSOREQUAL;
+      } else {
+        return OPERATOR_IGREATEROREQUAL;
+      }
+    }
+    if (operator.equals(OPERATOR_BETWEENINCLUSIVE)) {
+      if (rightClause) {
+        return OPERATOR_LESSOREQUAL;
+      } else {
+        return OPERATOR_GREATEROREQUAL;
+      }
+    }
+    throw new IllegalArgumentException("Operator not supported " + operator);
+  }
+
+  private boolean ignoreCase(Object mapValue, String operator) {
+    if (mapValue instanceof BigDecimal || mapValue instanceof Date) {
+      return false;
+    }
+    return operator.equals(OPERATOR_IEQUALS) || operator.equals(OPERATOR_INOTEQUAL)
+        || operator.equals(OPERATOR_CONTAINS) || operator.equals(OPERATOR_ENDSWITH)
+        || operator.equals(OPERATOR_STARTSWITH) || operator.equals(OPERATOR_ICONTAINS)
+        || operator.equals(OPERATOR_INOTSTARTSWITH) || operator.equals(OPERATOR_INOTENDSWITH)
+        || operator.equals(OPERATOR_NOTSTARTSWITH) || operator.equals(OPERATOR_NOTCONTAINS)
+        || operator.equals(OPERATOR_INOTCONTAINS) || operator.equals(OPERATOR_NOTENDSWITH)
+        || operator.equals(OPERATOR_IENDSWITH) || operator.equals(OPERATOR_ISTARTSWITH)
+        || operator.equals(OPERATOR_IBETWEEN) || operator.equals(OPERATOR_IGREATEROREQUAL)
+        || operator.equals(OPERATOR_ILESSOREQUAL) || operator.equals(OPERATOR_IGREATERTHAN)
+        || operator.equals(OPERATOR_ILESSTHAN) || operator.equals(OPERATOR_IBETWEENINCLUSIVE);
+  }
+
+  private boolean isNot(String operator) {
+    return operator.equals(OPERATOR_NOTCONTAINS) || operator.equals(OPERATOR_NOTENDSWITH)
+        || operator.equals(OPERATOR_NOTSTARTSWITH) || operator.equals(OPERATOR_INOTCONTAINS)
+        || operator.equals(OPERATOR_INOTENDSWITH) || operator.equals(OPERATOR_INOTSTARTSWITH)
+        || operator.equals(OPERATOR_NOT) || operator.equals(OPERATOR_NOTINSET);
+  }
+
+  private String getHqlOperator(String operator) {
+    if (operator.equals(OPERATOR_EQUALS)) {
+      return "=";
+    } else if (operator.equals(OPERATOR_INSET)) {
+      return "in";
+    } else if (operator.equals(OPERATOR_NOTINSET)) {
+      return "in";
+    } else if (operator.equals(OPERATOR_NOTEQUAL)) {
+      return "!=";
+    } else if (operator.equals(OPERATOR_IEQUALS)) {
+      return "=";
+    } else if (operator.equals(OPERATOR_INOTEQUAL)) {
+      return "!=";
+    } else if (operator.equals(OPERATOR_GREATERTHAN)) {
+      return ">";
+    } else if (operator.equals(OPERATOR_LESSTHAN)) {
+      return "<";
+    } else if (operator.equals(OPERATOR_GREATEROREQUAL)) {
+      return ">=";
+    } else if (operator.equals(OPERATOR_LESSOREQUAL)) {
+      return "<=";
+    } else if (operator.equals(OPERATOR_IGREATERTHAN)) {
+      return ">";
+    } else if (operator.equals(OPERATOR_ILESSTHAN)) {
+      return "<";
+    } else if (operator.equals(OPERATOR_IGREATEROREQUAL)) {
+      return ">=";
+    } else if (operator.equals(OPERATOR_ILESSOREQUAL)) {
+      return "<=";
+    } else if (operator.equals(OPERATOR_CONTAINS)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_STARTSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_ENDSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_ICONTAINS)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_ISTARTSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_IENDSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_NOTCONTAINS)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_NOTSTARTSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_NOTENDSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_INOTCONTAINS)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_INOTSTARTSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_INOTENDSWITH)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_EQUALSFIELD)) {
+      return "=";
+    } else if (operator.equals(OPERATOR_NOTEQUALFIELD)) {
+      return "!=";
+    } else if (operator.equals(OPERATOR_GREATERTHANFIElD)) {
+      return ">";
+    } else if (operator.equals(OPERATOR_LESSTHANFIELD)) {
+      return "<";
+    } else if (operator.equals(OPERATOR_GREATEROREQUALFIELD)) {
+      return ">=";
+    } else if (operator.equals(OPERATOR_LESSOREQUALFIElD)) {
+      return "<=";
+    } else if (operator.equals(OPERATOR_CONTAINSFIELD)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_STARTSWITHFIELD)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_ENDSWITHFIELD)) {
+      return "like";
+    } else if (operator.equals(OPERATOR_ISNULL)) {
+      return "is";
+    } else if (operator.equals(OPERATOR_NOTNULL)) {
+      return "is not";
+    } else if (operator.equals(OPERATOR_EXISTS)) {
+      return "exists";
+    }
+    // todo throw exception
+    return null;
+  }
+}
--- a/src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineDatasource.java	Wed May 28 13:23:22 2014 +0200
+++ b/src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineDatasource.java	Thu May 29 12:35:15 2014 +0200
@@ -6,10 +6,13 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.hibernate.SQLQuery;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
 import org.openbravo.base.model.Entity;
 import org.openbravo.base.model.ModelProvider;
 import org.openbravo.base.provider.OBProvider;
@@ -23,6 +26,7 @@
 public class ReturnFromCustomerPickEditLineDatasource extends DefaultDataSourceService {
 
   private static final String AD_TABLE_ID = "A9BC62219E644720867F6402B0C25933";
+  int count = 0;
 
   @Override
   public Entity getEntity() {
@@ -31,17 +35,17 @@
 
   @Override
   public String fetch(Map<String, String> parameters) {
+
     int startRow = 0;
     final String startRowStr = parameters.get(JsonConstants.STARTROW_PARAMETER);
     if (startRowStr != null) {
       startRow = Integer.parseInt(startRowStr);
     }
 
-    final List<JSONObject> jsonObjects = fetchJSONObject(parameters);
-
     final JSONObject jsonResult = new JSONObject();
     final JSONObject jsonResponse = new JSONObject();
     try {
+      List<JSONObject> jsonObjects = fetchJSONObject(parameters);
       jsonResponse.put(JsonConstants.RESPONSE_STATUS, JsonConstants.RPCREQUEST_STATUS_SUCCESS);
       jsonResponse.put(JsonConstants.RESPONSE_STARTROW, startRow);
       jsonResponse.put(JsonConstants.RESPONSE_ENDROW, jsonObjects.size() + startRow - 1);
@@ -54,19 +58,11 @@
     return jsonResult.toString();
   }
 
-  private int getCount(Map<String, String> parameters) {
-    SQLQuery qry = null;
-    if (parameters.get(JsonConstants.DISTINCT_PARAMETER) != null) {
-      qry = OBDal.getInstance().getSession().createSQLQuery(getCountProductQuery(parameters));
-    } else {
-      qry = OBDal.getInstance().getSession().createSQLQuery(getSQLCountQuery(parameters));
-    }
-    OBDal.getInstance().getSession().createSQLQuery(getSQLCountQuery(parameters));
-    Number count = (Number) qry.uniqueResult();
-    return count.intValue();
+  private int getCount(Map<String, String> parameters) throws JSONException {
+    return count;
   }
 
-  private List<JSONObject> fetchJSONObject(Map<String, String> parameters) {
+  private List<JSONObject> fetchJSONObject(Map<String, String> parameters) throws JSONException {
     final String startRowStr = parameters.get(JsonConstants.STARTROW_PARAMETER);
     final String endRowStr = parameters.get(JsonConstants.ENDROW_PARAMETER);
     int startRow = -1;
@@ -85,12 +81,9 @@
   }
 
   protected List<Map<String, Object>> getData(Map<String, String> parameters, int startRow,
-      int endRow) {
+      int endRow) throws JSONException {
     List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
-
-    int offset = startRow;
-    int nRows = endRow - startRow + 1;
-
+    count = 0;
     String fetchType = null;
     SQLQuery qry = null;
     if (parameters.get(JsonConstants.DISTINCT_PARAMETER) != null) {
@@ -100,14 +93,21 @@
       fetchType = "grid";
       qry = OBDal.getInstance().getSession().createSQLQuery(getSQLQuery(parameters));
     }
-    qry.setFirstResult(offset);
-    qry.setMaxResults(nRows);
 
-    for (Object o : qry.list()) {
-      Map<String, Object> row = createRow(o, fetchType);
-      result.add(row);
+    ScrollableResults scrollresult = qry.scroll(ScrollMode.FORWARD_ONLY);
+    boolean addValue;
+    while (scrollresult.next()) {
+      Object resultLine = (Object) scrollresult.get();
+      Map<String, Object> row = createRow(resultLine, fetchType);
+      if (StringUtils.isNotEmpty(parameters.get("criteria"))) {
+        addValue = new ResultMapCriteriaUtils(row, parameters).applyFilter();
+        if (addValue) {
+          result.add(row);
+          count++;
+        }
+      }
+
     }
-
     return result;
   }
 
@@ -271,12 +271,10 @@
     queryBuilder.append(" AND ol.c_order_discount_id IS NULL ");
     queryBuilder.append(" AND COALESCE(rol.ad_client_id,il.ad_client_id) = '" + clientId + "'");
     queryBuilder.append(" AND i.issotrx = 'Y'");
+
     if (sqlWhereClause != null && !sqlWhereClause.isEmpty() && !"null".equals(sqlWhereClause)) {
       queryBuilder.append(" AND (" + sqlWhereClause.toString() + ")");
     }
-    if (filterClause != null && !filterClause.isEmpty() && !"null".equals(filterClause)) {
-      queryBuilder.append(filterClause.toString());
-    }
     if (orgWhereClause != null && !orgWhereClause.isEmpty() && !"null".equals(orgWhereClause)) {
       queryBuilder.append(orgWhereClause.toString());
     }
--- a/src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineRow.java	Wed May 28 13:23:22 2014 +0200
+++ b/src/org/openbravo/common/datasource/ReturnFromCustomerPickEditLineRow.java	Thu May 29 12:35:15 2014 +0200
@@ -45,7 +45,9 @@
   private final SimpleDateFormat xmlDateTimeFormat = JsonUtils.createDateTimeFormat();
 
   public ReturnFromCustomerPickEditLineRow(Object[] values) {
+
     this.c_rm_order_pick_edit_lines_id = (String) values[0];
+
     this.ad_client_id = (String) values[1];
     this.ad_org_id = (String) values[2];
     this.ad_client_identifier = (String) values[3];
@@ -87,12 +89,14 @@
     if (this.cOrderLineId != null && this.cOrderLineId.isEmpty()) {
       this.cOrderLineId = null;
     }
+
   }
 
   public Map<String, Object> toMap() {
     Map<String, Object> row = new LinkedHashMap<String, Object>();
 
     row.put("_identifier", this.c_rm_order_pick_edit_lines_id);
+    row.put("id", this.c_rm_order_pick_edit_lines_id);
     row.put("entityName", "ReturnMaterialOrderPickEditLines");
     row.put("client", this.ad_client_id);
     row.put("client$_identifier", this.ad_client_identifier);