# HG changeset patch
# User Alvaro Ferraz <alvaro.ferraz@openbravo.com>
# Date 1449080087 -3600
#      Wed Dec 02 19:14:47 2015 +0100
# Node ID ab29069d423fb0d3c24156f780e47192d10f696c
# Parent  1b7ed6f76806ac1e6fad1f4358d3564aec492d44
Fixes issue 31419: Processing a remittance with many lines is slow

Modify getRemittanceLines method and create a new one in REM_RemittanceProcess to retrieve only remittance line ids and do not load many entities in memory.
Modify existLineInSettledRemittance method in REM_AddRemittance to retrieve only one object.

diff --git a/src/org/openbravo/module/remittance/process/REM_AddRemittance.java b/src/org/openbravo/module/remittance/process/REM_AddRemittance.java
--- a/src/org/openbravo/module/remittance/process/REM_AddRemittance.java
+++ b/src/org/openbravo/module/remittance/process/REM_AddRemittance.java
@@ -817,11 +817,12 @@
     OBCriteria<RemittanceLineCancel> remlc = OBDal.getInstance().createCriteria(
         RemittanceLineCancel.class);
     remlc.add(Restrictions.eq(Remittance.PROPERTY_PAYMENT, payment));
-    List<RemittanceLineCancel> settledLines = remlc.list();
+    remlc.setMaxResults(1);
+    RemittanceLineCancel settledLine = (RemittanceLineCancel) remlc.uniqueResult();
     HashMap<String, String> result = new HashMap<String, String>();
-    if (settledLines.size() > 0) {
-      result.put("documentno", settledLines.get(0).getRemittance().getDocumentNo());
-      result.put("lineno", String.valueOf(settledLines.get(0).getLineNo()));
+    if (settledLine != null) {
+      result.put("documentno", settledLine.getRemittance().getDocumentNo());
+      result.put("lineno", String.valueOf(settledLine.getLineNo()));
     }
     return result;
   }
diff --git a/src/org/openbravo/module/remittance/process/REM_RemittanceProcess.java b/src/org/openbravo/module/remittance/process/REM_RemittanceProcess.java
--- a/src/org/openbravo/module/remittance/process/REM_RemittanceProcess.java
+++ b/src/org/openbravo/module/remittance/process/REM_RemittanceProcess.java
@@ -290,8 +290,9 @@
             }
             paymentIdToRemove.add(payment.getId()); // To be removed later
             // Clean all lines which point to this payment
-            List<RemittanceLine> relatedLines = getRemittanceLines(payment, remittance);
-            for (RemittanceLine relatedLine : relatedLines) {
+            for (String relatedLineId : getRemittanceLines(payment.getId(), remittance.getId())) {
+              RemittanceLine relatedLine = OBDal.getInstance().get(RemittanceLine.class,
+                  relatedLineId);
               relatedLine.setPayment(null);
               OBDal.getInstance().save(relatedLine);
               OBDal.getInstance().flush();
@@ -367,7 +368,8 @@
 
     // Remittance lines of payments cannot be grouped
     // Create new bank instruction line for each one
-    for (RemittanceLine line : remittance.getREMRemittanceLineList()) {
+    for (String lineId : getRemittanceLines(remittance.getId())) {
+      RemittanceLine line = OBDal.getInstance().get(RemittanceLine.class, lineId);
       FIN_Payment payment = line.getPayment();
       if (payment != null) {
         HashMap<String, String> rem = REM_AddRemittance.existLineInSettledRemittance(payment);
@@ -617,8 +619,10 @@
   private void createPayments(Remittance remittance) throws Exception {
     FIN_PaymentMethod pm = remittance.getRemittanceType().getPaymentMethod();
     Currency faCurrency = remittance.getFinancialAccount().getCurrency();
-    List<RemittanceLine> lines = remittance.getREMRemittanceLineList();
-    for (RemittanceLine line : lines) {
+
+    for (String lineId : getRemittanceLines(remittance.getId())) {
+      RemittanceLine line = OBDal.getInstance().get(RemittanceLine.class, lineId);
+
       if (line.getPayment() != null) {
         FIN_Payment payment = line.getPayment();
         HashMap<String, String> rem = REM_AddRemittance.existLineInSettledRemittance(payment);
@@ -1107,20 +1111,23 @@
     }
   }
 
-  private List<RemittanceLine> getRemittanceLines(FIN_Payment payment, Remittance remittance) {
-    List<RemittanceLine> list = new ArrayList<RemittanceLine>();
+  @SuppressWarnings("unchecked")
+  private List<String> getRemittanceLines(String paymentId, String remittanceId) {
     OBContext.setAdminMode();
     try {
-      OBCriteria<RemittanceLine> obcRL = OBDal.getInstance().createCriteria(RemittanceLine.class);
-      obcRL.setFilterOnReadableClients(false);
-      obcRL.setFilterOnReadableOrganization(false);
-      obcRL.add(Restrictions.eq(RemittanceLine.PROPERTY_PAYMENT, payment));
-      obcRL.add(Restrictions.eq(RemittanceLine.PROPERTY_REMITTANCE, remittance));
-      list = obcRL.list();
+      final StringBuilder whereClause = new StringBuilder();
+      whereClause.append(" select rl." + RemittanceLine.PROPERTY_ID);
+      whereClause.append(" from " + RemittanceLine.ENTITY_NAME + " as rl");
+      whereClause.append(" where rl." + RemittanceLine.PROPERTY_PAYMENT + ".id = :paymentId");
+      whereClause.append(" and rl." + RemittanceLine.PROPERTY_REMITTANCE + ".id = :remittanceId");
+      whereClause.append(" and rl." + RemittanceLine.PROPERTY_ACTIVE + " = true");
+      Query query = OBDal.getInstance().getSession().createQuery(whereClause.toString());
+      query.setParameter("paymentId", paymentId);
+      query.setParameter("remittanceId", remittanceId);
+      return query.list();
     } finally {
       OBContext.restorePreviousMode();
     }
-    return list;
   }
 
   private boolean isWrongRemTypePayMethodConfig(Remittance remittance) {
@@ -1240,4 +1247,21 @@
       return "00000000000000000000";
     }
   }
+
+  @SuppressWarnings("unchecked")
+  private List<String> getRemittanceLines(String remittanceId) {
+    OBContext.setAdminMode();
+    try {
+      final StringBuilder whereClause = new StringBuilder();
+      whereClause.append(" select rl." + RemittanceLine.PROPERTY_ID);
+      whereClause.append(" from " + RemittanceLine.ENTITY_NAME + " as rl");
+      whereClause.append(" where rl." + RemittanceLine.PROPERTY_REMITTANCE + ".id = :remittanceId");
+      whereClause.append(" and rl." + RemittanceLine.PROPERTY_ACTIVE + " = true");
+      Query query = OBDal.getInstance().getSession().createQuery(whereClause.toString());
+      query.setParameter("remittanceId", remittanceId);
+      return query.list();
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+  }
 }
