details:   https://code.openbravo.com/erp/devel/pi/rev/9bb00b5b71ad
changeset: 35248:9bb00b5b71ad
user:      Asier Lostalé <asier.lostale <at> openbravo.com>
date:      Fri Dec 14 15:22:51 2018 +0100
summary:   fixed bug 39644: P&E doesn't set selected records on top

  In P&E selected records in UI were not set on top of non selected ones.

  Now they are sorted in backend, also we ensure that the whole selection is
  returned in the page even if it didn't originally fit on it.

diffstat:

 
modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceUtils.java
 |   49 ++--
 
modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
        |    4 +
 
modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java
      |  101 +++++++++-
 3 files changed, 122 insertions(+), 32 deletions(-)

diffs (237 lines):

diff -r 9f06f79b75a9 -r 9bb00b5b71ad 
modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceUtils.java
--- 
a/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceUtils.java
        Mon Dec 17 12:54:18 2018 +0100
+++ 
b/modules/org.openbravo.service.datasource/src/org/openbravo/service/datasource/DataSourceUtils.java
        Fri Dec 14 15:22:51 2018 +0100
@@ -18,19 +18,19 @@
  */
 package org.openbravo.service.datasource;
 
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 import org.codehaus.jettison.json.JSONArray;
 import org.codehaus.jettison.json.JSONException;
 import org.codehaus.jettison.json.JSONObject;
 import org.openbravo.dal.core.OBContext;
 import org.openbravo.service.json.JsonUtils;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
 
 /**
  * This class contains utility methods for dataSource related classes
@@ -80,35 +80,36 @@
    * according to that criteria.
    */
   public static int getNumberOfSelectedRecords(Map<String, String> parameters) 
{
-    List<String> selectedRecords = new ArrayList<String>();
     boolean hasCriteria = parameters.containsKey("criteria");
-    if (hasCriteria) {
-      try {
-        selectedRecords = 
getSelectedRecordsFromCriteria(JsonUtils.buildCriteria(parameters));
-      } catch (JSONException jsonex) {
-        log.error("Error retrieving number of selected records", jsonex);
-      }
+    if (!hasCriteria) {
+      return 0;
     }
-    return selectedRecords.size();
+    return 
getSelectedRecordsFromCriteria(JsonUtils.buildCriteria(parameters)).size();
   }
 
   /**
-   * Returns a list of selected record IDs from a criteria included in the 
JSONObject received as
+   * Returns a set of selected record IDs from a criteria included in the 
JSONObject received as
    * parameter.
    */
-  public static List<String> getSelectedRecordsFromCriteria(JSONObject 
buildCriteria)
-      throws JSONException {
-    List<String> selectedRecords = new ArrayList<String>();
-    JSONArray criteriaArray = buildCriteria.getJSONArray("criteria");
-    for (int i = 0; i < criteriaArray.length(); i++) {
-      JSONObject criteria = criteriaArray.getJSONObject(i);
-      if (criteria.has("fieldName") && 
criteria.getString("fieldName").equals("id")
-          && criteria.has("value")) {
-        String value = criteria.getString("value");
-        for (String recordId : value.split(",")) {
-          selectedRecords.add(recordId.trim());
+  public static Set<String> getSelectedRecordsFromCriteria(JSONObject 
buildCriteria) {
+    if (buildCriteria == null) {
+      return Collections.emptySet();
+    }
+    Set<String> selectedRecords = new HashSet<>();
+    try {
+      JSONArray criteriaArray = buildCriteria.getJSONArray("criteria");
+      for (int i = 0; i < criteriaArray.length(); i++) {
+        JSONObject criteria = criteriaArray.getJSONObject(i);
+        if (criteria.has("fieldName") && 
criteria.getString("fieldName").equals("id")
+            && criteria.has("value")) {
+          String value = criteria.getString("value");
+          for (String recordId : value.split(",")) {
+            selectedRecords.add(recordId.trim());
+          }
         }
       }
+    } catch (JSONException e) {
+      log.error("Error getting selected records from criteria {}", 
buildCriteria, e);
     }
     return selectedRecords;
   }
diff -r 9f06f79b75a9 -r 9bb00b5b71ad 
modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
--- 
a/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
       Mon Dec 17 12:54:18 2018 +0100
+++ 
b/modules/org.openbravo.service.json/src/org/openbravo/service/json/AdvancedQueryBuilder.java
       Fri Dec 14 15:22:51 2018 +0100
@@ -1948,6 +1948,10 @@
 
   public void setCriteria(JSONObject criteria) {
     this.criteria = criteria;
+    whereClause = null;
+    aliasIndex = 0;
+    orNesting = 0;
+    typedParameters = new ArrayList<>();
   }
 
   public boolean isJoinAssociatedEntities() {
diff -r 9f06f79b75a9 -r 9bb00b5b71ad 
modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java
--- 
a/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java
     Mon Dec 17 12:54:18 2018 +0100
+++ 
b/modules/org.openbravo.service.json/src/org/openbravo/service/json/DefaultJsonDataService.java
     Fri Dec 14 15:22:51 2018 +0100
@@ -18,6 +18,7 @@
  */
 package org.openbravo.service.json;
 
+import static java.util.stream.Collectors.toList;
 import static 
org.openbravo.userinterface.selector.SelectorConstants.includeOrgFilter;
 
 import java.util.ArrayList;
@@ -25,6 +26,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.enterprise.inject.Any;
 import javax.enterprise.inject.Instance;
@@ -253,13 +255,17 @@
 
           // If the request is done from a P&E window, then we should adapt 
the page size to include
           // all selected records into the response
-          if (isPickAndEdit && shouldIncreasePageSize(parameters, bobs, 
startRowStr, endRowStr)) {
-            String newEndRow = Integer.toString(Integer.parseInt(endRowStr)
-                + JsonConstants.PAE_DATA_PAGE_SIZE);
-            parameters.put(JsonConstants.ENDROW_PARAMETER, newEndRow);
-            log.debug("The amount of selected records is higher than the page 
size, increasing page size to "
-                + newEndRow);
-            return fetch(parameters, filterOnReadableOrganizations);
+          if (isPickAndEdit) {
+            if (shouldIncreasePageSize(parameters, bobs, startRowStr, 
endRowStr)) {
+              String newEndRow = Integer.toString(Integer.parseInt(endRowStr)
+                  + JsonConstants.PAE_DATA_PAGE_SIZE);
+              parameters.put(JsonConstants.ENDROW_PARAMETER, newEndRow);
+              log.debug("The amount of selected records is higher than the 
page size, increasing page size to "
+                  + newEndRow);
+              return fetch(parameters, filterOnReadableOrganizations);
+            }
+
+            bobs = getFixedPNESelection(queryService, bobs);
           }
         }
 
@@ -272,7 +278,7 @@
           count = bobs.size() + startRow;
           // computedMaxResults is one too much, if we got one to much then 
correct
           // the result and up the count so that the grid knows that there are 
more
-          if (bobs.size() == computedMaxResults) {
+          if (bobs.size() >= computedMaxResults) {
             bobs = bobs.subList(0, bobs.size() - 1);
             count++;
           }
@@ -318,6 +324,85 @@
   }
 
   /**
+   * Fixes selected records for P&E datasource requests ensuring all selected 
records are placed on
+   * top of not selected ones. If the complete selection was not initially 
fetched in current page,
+   * an additional query to retrieve it will be executed.
+   */
+  private List<BaseOBObject> getFixedPNESelection(DataEntityQueryService 
queryService,
+      List<BaseOBObject> bobs) {
+    JSONObject criteria = queryService.getQueryBuilder().getCriteria();
+    Set<String> selectedIds = 
DataSourceUtils.getSelectedRecordsFromCriteria(criteria);
+    if (selectedIds.isEmpty()) {
+      return bobs;
+    }
+
+    List<BaseOBObject> selected = new ArrayList<>(bobs.size());
+    List<BaseOBObject> unselected = new ArrayList<>(bobs.size());
+
+    for (BaseOBObject row : bobs) {
+      if (selectedIds.contains(row.getId())) {
+        selected.add(row);
+      } else {
+        unselected.add(row);
+      }
+    }
+
+    int selectionInCurrentPage = selected.size();
+    boolean completeSelectionInCurrentPage = selectionInCurrentPage == 
selectedIds.size();
+    if (completeSelectionInCurrentPage) {
+      selected.addAll(unselected);
+      return selected;
+    }
+
+    log.debug("P&E doesn't contain all selection, querying again to get it 
{}", criteria);
+
+    List<BaseOBObject> gridRows = bobs;
+    try {
+      selected = getAllSelectedRecords(queryService, criteria);
+      int idsOutOfCurrentPage = selected.size() - selectionInCurrentPage;
+      selected.addAll(unselected);
+
+      if (queryService.getFirstResult() > 0 && idsOutOfCurrentPage > 0) {
+        // fix pagination to prevent selection appearing in all pages
+        log.trace("Skipping {} rows for {}", idsOutOfCurrentPage, criteria);
+        gridRows = 
selected.stream().skip(idsOutOfCurrentPage).collect(toList());
+      } else {
+        gridRows = selected;
+      }
+    } catch (JSONException e) {
+      log.error("failed selecting ids {}", criteria, e);
+    }
+
+    return gridRows;
+  }
+
+  /** Note side effect: criteria gets modified */
+  private List<BaseOBObject> getAllSelectedRecords(DataEntityQueryService 
queryService,
+      JSONObject criteria) throws JSONException {
+    JSONArray criteriaFields = criteria.getJSONArray("criteria");
+    JSONArray crieriaIdFields = new JSONArray();
+    for (int i = 0; i < criteriaFields.length(); i++) {
+      JSONObject field = criteriaFields.getJSONObject(i);
+      if (field.has("fieldName") && "id".equals(field.getString("fieldName"))
+          && field.has("operator") && 
"equals".equals(field.getString("operator"))) {
+        crieriaIdFields.put(field);
+      }
+    }
+    log.trace("Old criteria {}", criteria);
+    criteria.put("criteria", crieriaIdFields);
+
+    log.trace("New criteria {}", criteria);
+
+    Integer originalFirstResult = queryService.getFirstResult();
+    queryService.setCriteria(criteria);
+    queryService.setFirstResult(0);
+    queryService.setMaxResults(JsonConstants.PAE_MAX_PAGE_SIZE);
+    List<BaseOBObject> rows = queryService.list();
+    queryService.setFirstResult(originalFirstResult);
+    return rows;
+  }
+
+  /**
    * Used on requests received from pick and execute windows in order to avoid 
losing the selection.
    * It checks if the request has a criteria that contains the selected 
records. In that case, if
    * the amount of selected records is higher than the page size, then the end 
row is increased so


_______________________________________________
Openbravo-commits mailing list
Openbravo-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to