details:   https://code.openbravo.com/erp/devel/pi/rev/217fb3a426fe
changeset: 28180:217fb3a426fe
user:      Alvaro Ferraz <alvaro.ferraz <at> openbravo.com>
date:      Tue Dec 01 16:44:30 2015 +0100
summary:   Fixes issue 31580: Java Heap Space error when posting payment with 
many details

Add a new FIN_Utility.getOrderedPaymentDetailList method and deprecate the old 
one, to return a List<String> instead of a List<FIN_PaymentDetail> and avoid 
loading all the entities in memory.
Adapt loadLines methods in DocFINFinAccTransaction, DocFINPayment and 
DocFINReconciliation to the new FIN_Utility.getOrderedPaymentDetailList method.
Create a new getPaymentDetailWriteOffAndAmount method in AcctServer to adapt it 
to new parameters.

details:   https://code.openbravo.com/erp/devel/pi/rev/1817418c55af
changeset: 28181:1817418c55af
user:      Víctor Martínez Romanos <victor.martinez <at> openbravo.com>
date:      Tue Dec 29 11:32:34 2015 +0100
summary:   Fixed bug 31580: code review improvements
Properly passing parameter to the HQL query
Force to check client+org when using admin mode

diffstat:

 
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
 |   39 +-
 src/org/openbravo/erpCommon/ad_forms/AcctServer.java                           
                |   82 ++-
 src/org/openbravo/erpCommon/ad_forms/DocFINFinAccTransaction.java              
                |  245 ++++-----
 src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java                        
                |  244 ++++-----
 src/org/openbravo/erpCommon/ad_forms/DocFINReconciliation.java                 
                |  182 +++---
 5 files changed, 429 insertions(+), 363 deletions(-)

diffs (truncated from 1029 to 300 lines):

diff -r 0759c894c939 -r 1817418c55af 
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
--- 
a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
    Mon Jan 11 13:20:26 2016 +0100
+++ 
b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
    Tue Dec 29 11:32:34 2015 +0100
@@ -1310,8 +1310,11 @@
   }
 
   /**
-   * Returns Payment Details from a Payment ordered by Invoice and Order
+   * Returns Payment Details from a Payment ordered by Invoice and Order. This 
method is deprecated
+   * as it does not perform well. Use {@link 
#getOrderedPaymentDetailList(String paymentId)} instead
+   * 
    */
+  @Deprecated
   public static List<FIN_PaymentDetail> 
getOrderedPaymentDetailList(FIN_Payment payment) {
 
     List<FIN_PaymentDetail> pdList = null;
@@ -1343,6 +1346,40 @@
   }
 
   /**
+   * Returns Payment Details from a Payment ordered by Invoice and Order
+   */
+  @SuppressWarnings("unchecked")
+  public static List<String> getOrderedPaymentDetailList(String paymentId) {
+
+    List<String> pdList = null;
+
+    OBContext.setAdminMode(true);
+    try {
+      final StringBuilder whereClause = new StringBuilder();
+      whereClause.append(" select pd." + FIN_PaymentDetail.PROPERTY_ID);
+      whereClause.append(" from " + FIN_PaymentDetail.ENTITY_NAME + " as pd");
+      whereClause.append(" left join pd." + 
FIN_PaymentDetail.PROPERTY_FINPAYMENTSCHEDULEDETAILLIST
+          + " as psd");
+      whereClause
+          .append(" where pd." + FIN_PaymentDetail.PROPERTY_FINPAYMENT + ".id 
= :paymentId ");
+      whereClause.append(" and pd." + FIN_PaymentDetail.PROPERTY_ACTIVE + " = 
true");
+      whereClause.append(" order by psd."
+          + FIN_PaymentScheduleDetail.PROPERTY_INVOICEPAYMENTSCHEDULE);
+      whereClause.append(", coalesce(psd."
+          + FIN_PaymentScheduleDetail.PROPERTY_ORDERPAYMENTSCHEDULE + ",'0')");
+
+      Query query = 
OBDal.getInstance().getSession().createQuery(whereClause.toString());
+      query.setParameter("paymentId", paymentId);
+      pdList = query.list();
+
+    } finally {
+      OBContext.restorePreviousMode();
+    }
+
+    return pdList;
+  }
+
+  /**
    * Returns true if the payment is a reverse payment not a reversed one.
    */
   public static boolean isReversePayment(FIN_Payment payment) {
diff -r 0759c894c939 -r 1817418c55af 
src/org/openbravo/erpCommon/ad_forms/AcctServer.java
--- a/src/org/openbravo/erpCommon/ad_forms/AcctServer.java      Mon Jan 11 
13:20:26 2016 +0100
+++ b/src/org/openbravo/erpCommon/ad_forms/AcctServer.java      Tue Dec 29 
11:32:34 2015 +0100
@@ -2954,24 +2954,74 @@
   public HashMap<String, BigDecimal> getPaymentDetailWriteOffAndAmount(
       List<FIN_PaymentDetail> paymentDetails, FIN_PaymentSchedule ps, 
FIN_PaymentSchedule psi,
       FIN_PaymentSchedule pso, int currentPaymentDetailIndex, final 
FieldProvider fieldProvider) {
+    FIN_PaymentDetail paymentDetail = 
OBDal.getInstance().get(FIN_PaymentDetail.class,
+        paymentDetails.get(currentPaymentDetailIndex));
+    String paymentDetailNextId = null;
+    String paymentDetailPreviousId = null;
+    if (currentPaymentDetailIndex < paymentDetails.size() - 1) {
+      paymentDetailNextId = paymentDetails.get(currentPaymentDetailIndex + 
1).getId();
+    }
+    if (currentPaymentDetailIndex > 0) {
+      paymentDetailPreviousId = paymentDetails.get(currentPaymentDetailIndex - 
1).getId();
+    }
+    return getPaymentDetailWriteOffAndAmount(paymentDetail, 
paymentDetailNextId,
+        paymentDetailPreviousId, ps, psi, pso, fieldProvider);
+  }
+
+  /**
+   * Returns the writeoff and the amount of a Payment Detail. In case the 
related Payment Schedule
+   * Detail was generated for compensate the difference between an Order and a 
related Invoice, it
+   * merges it's amount with the next Payment Schedule Detail. Issue 19567:
+   * https://issues.openbravo.com/view.php?id=19567 <br />
+   * It does exactly the same as the
+   * {@link #getPaymentDetailWriteOffAndAmount(List, FIN_PaymentSchedule, 
FIN_PaymentSchedule, FIN_PaymentSchedule, int)}
+   * method, but it also stores a new field "MergedPaymentDetailId" inside the 
fieldProvider with
+   * the merged payment detail id (if any).
+   * 
+   * @param paymentDetail
+   *          Payment Detail
+   * @param paymentDetailNextId
+   *          Next Payment Detail id
+   * @param paymentDetailPreviousId
+   *          Previous Payment Detail id
+   * @param ps
+   *          Previous Payment Schedule
+   * @param psi
+   *          Invoice Payment Schedule of actual Payment Detail
+   * @param pso
+   *          Order Payment Schedule of actual Payment Detail
+   * @param fieldProvider
+   *          contains the FieldProvider with the Payment Detail currently 
being processed. Used to
+   *          store the "MergedPaymentDetailId" (if any) as a new field of the 
fieldProvider
+   */
+  public HashMap<String, BigDecimal> getPaymentDetailWriteOffAndAmount(
+      FIN_PaymentDetail paymentDetail, String paymentDetailNextId, String 
paymentDetailPreviousId,
+      FIN_PaymentSchedule ps, FIN_PaymentSchedule psi, FIN_PaymentSchedule pso,
+      final FieldProvider fieldProvider) {
     HashMap<String, BigDecimal> amountAndWriteOff = new HashMap<String, 
BigDecimal>();
 
     // Default return values
-    amountAndWriteOff.put("amount", 
paymentDetails.get(currentPaymentDetailIndex).getAmount());
-    amountAndWriteOff.put("writeoff", 
paymentDetails.get(currentPaymentDetailIndex)
-        .getWriteoffAmount());
+    amountAndWriteOff.put("amount", paymentDetail.getAmount());
+    amountAndWriteOff.put("writeoff", paymentDetail.getWriteoffAmount());
 
     // If the Payment Detail has either an Invoice or an Order associated to it
     if (psi != null || pso != null) {
       // If the Payment Detail has no Order associated to it, or it has an 
Invoice associated and is
       // the same one as the previous Payment Detail
       if ((psi != null && psi.equals(ps)) || pso == null) {
-        FIN_PaymentScheduleDetail psdNext = (currentPaymentDetailIndex == 
paymentDetails.size() - 1) ? null
-            : paymentDetails.get(currentPaymentDetailIndex + 
1).getFINPaymentScheduleDetailList()
-                .get(0);
-        FIN_PaymentScheduleDetail psdPrevious = (currentPaymentDetailIndex == 
0) ? null
-            : paymentDetails.get(currentPaymentDetailIndex - 
1).getFINPaymentScheduleDetailList()
-                .get(0);
+        FIN_PaymentDetail paymentDetailNext = null;
+        FIN_PaymentDetail paymentDetailPrevious = null;
+        FIN_PaymentScheduleDetail psdNext = null;
+        FIN_PaymentScheduleDetail psdPrevious = null;
+        if (paymentDetailNextId != null) {
+          paymentDetailNext = OBDal.getInstance().get(FIN_PaymentDetail.class, 
paymentDetailNextId);
+          psdNext = paymentDetailNext.getFINPaymentScheduleDetailList().get(0);
+        }
+        if (paymentDetailPreviousId != null) {
+          paymentDetailPrevious = 
OBDal.getInstance().get(FIN_PaymentDetail.class,
+              paymentDetailPreviousId);
+          psdPrevious = 
paymentDetailPrevious.getFINPaymentScheduleDetailList().get(0);
+        }
         // If the Payment Detail has no Order associated, and the next Payment 
Detail belongs to the
         // same Invoice and it has an Order related, then return null
         if (pso == null && psdNext != null && 
psdNext.getInvoicePaymentSchedule() == psi
@@ -2982,15 +3032,13 @@
           // related to it, return the sum of amounts.
         } else if (psdPrevious != null && 
psdPrevious.getInvoicePaymentSchedule() == psi
             && psdPrevious.getOrderPaymentSchedule() == null) {
-          amountAndWriteOff.put("amount", 
paymentDetails.get(currentPaymentDetailIndex).getAmount()
-              .add(paymentDetails.get(currentPaymentDetailIndex - 
1).getAmount()));
-          amountAndWriteOff.put(
-              "writeoff",
-              paymentDetails.get(currentPaymentDetailIndex).getWriteoffAmount()
-                  .add(paymentDetails.get(currentPaymentDetailIndex - 
1).getWriteoffAmount()));
+          amountAndWriteOff.put("amount",
+              
paymentDetail.getAmount().add(paymentDetailPrevious.getAmount()));
+          amountAndWriteOff.put("writeoff",
+              
paymentDetail.getWriteoffAmount().add(paymentDetailPrevious.getWriteoffAmount()));
           if (fieldProvider != null) {
-            FieldProviderFactory.setField(fieldProvider, 
"MergedPaymentDetailId", paymentDetails
-                .get(currentPaymentDetailIndex - 1).getId());
+            FieldProviderFactory.setField(fieldProvider, 
"MergedPaymentDetailId",
+                paymentDetailPreviousId);
           }
         }
       }
diff -r 0759c894c939 -r 1817418c55af 
src/org/openbravo/erpCommon/ad_forms/DocFINFinAccTransaction.java
--- a/src/org/openbravo/erpCommon/ad_forms/DocFINFinAccTransaction.java Mon Jan 
11 13:20:26 2016 +0100
+++ b/src/org/openbravo/erpCommon/ad_forms/DocFINFinAccTransaction.java Tue Dec 
29 11:32:34 2015 +0100
@@ -114,38 +114,48 @@
   public FieldProviderFactory[] loadLinesPaymentDetailsFieldProvider(
       FIN_FinaccTransaction transaction) {
     FIN_Payment payment = transaction.getFinPayment();
-    List<FIN_PaymentDetail> paymentDetails = 
FIN_Utility.getOrderedPaymentDetailList(payment);
+    List<String> paymentDetails = 
FIN_Utility.getOrderedPaymentDetailList(payment.getId());
     FieldProviderFactory[] data = new 
FieldProviderFactory[paymentDetails.size()];
     FIN_PaymentSchedule ps = null;
     FIN_PaymentDetail pd = null;
     OBContext.setAdminMode();
     try {
       for (int i = 0; i < data.length; i++) {
+        FIN_PaymentDetail paymentDetail = 
OBDal.getInstance().get(FIN_PaymentDetail.class,
+            paymentDetails.get(i));
         /*
          * if (!getPaymentConfirmation(payment)) continue;
          */
         // Details refunded used credit are excluded as the entry will be 
created using the credit
         // used
-        if (paymentDetails.get(i).isRefund() && 
paymentDetails.get(i).isPrepayment()) {
+        if (paymentDetail.isRefund() && paymentDetail.isPrepayment()) {
           continue;
         }
 
         // If the Payment Detail has already been processed, skip it
-        if (paymentDetails.get(i).equals(pd)) {
+        if (paymentDetail.equals(pd)) {
           continue;
         }
-        pd = paymentDetails.get(i);
+        pd = paymentDetail;
 
         data[i] = new FieldProviderFactory(null);
-        FIN_PaymentSchedule psi = 
paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
+        FIN_PaymentSchedule psi = 
paymentDetail.getFINPaymentScheduleDetailList().get(0)
             .getInvoicePaymentSchedule();
-        FIN_PaymentSchedule pso = 
paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
+        FIN_PaymentSchedule pso = 
paymentDetail.getFINPaymentScheduleDetailList().get(0)
             .getOrderPaymentSchedule();
         // Related to Issue Issue 19567. Some Payment Detail's amount and 
writeoff amount are merged
         // into one.
         // https://issues.openbravo.com/view.php?id=19567
+        String paymentDetailNextId = null;
+        String paymentDetailPreviousId = null;
+        if (i < paymentDetails.size() - 1) {
+          paymentDetailNextId = paymentDetails.get(i + 1);
+        }
+        if (i > 0) {
+          paymentDetailPreviousId = paymentDetails.get(i - 1);
+        }
         HashMap<String, BigDecimal> amountAndWriteOff = 
getPaymentDetailWriteOffAndAmount(
-            paymentDetails, ps, psi, pso, i, data[i]);
+            paymentDetail, paymentDetailNextId, paymentDetailPreviousId, ps, 
psi, pso, data[i]);
         BigDecimal amount = amountAndWriteOff.get("amount");
         BigDecimal writeOff = amountAndWriteOff.get("writeoff");
         if (amount == null) {
@@ -158,150 +168,131 @@
         ps = psi;
 
         FieldProviderFactory.setField(data[i], "FIN_Finacc_Transaction_ID", 
transaction.getId());
-        FieldProviderFactory.setField(data[i], "AD_Client_ID", 
paymentDetails.get(i).getClient()
-            .getId());
-        FieldProviderFactory.setField(data[i], "AD_Org_ID", 
paymentDetails.get(i).getOrganization()
-            .getId());
-        FieldProviderFactory.setField(data[i], "FIN_Payment_Detail_ID", 
paymentDetails.get(i)
-            .getId());
+        FieldProviderFactory.setField(data[i], "AD_Client_ID", 
paymentDetail.getClient().getId());
+        FieldProviderFactory
+            .setField(data[i], "AD_Org_ID", 
paymentDetail.getOrganization().getId());
+        FieldProviderFactory.setField(data[i], "FIN_Payment_Detail_ID", 
paymentDetail.getId());
         FieldProviderFactory.setField(data[i], "FIN_Payment_ID", 
payment.getId());
         FieldProviderFactory.setField(data[i], "DepositAmount", 
transaction.getDepositAmount()
             .toString());
         FieldProviderFactory.setField(data[i], "PaymentAmount", 
transaction.getPaymentAmount()
             .toString());
-        FieldProviderFactory.setField(data[i], "DoubtFulDebtAmount", 
paymentDetails.get(i)
+        FieldProviderFactory.setField(data[i], "DoubtFulDebtAmount", 
paymentDetail
             
.getFINPaymentScheduleDetailList().get(0).getDoubtfulDebtAmount().toString());
-        FieldProviderFactory.setField(data[i], "isprepayment",
-            paymentDetails.get(i).isPrepayment() ? "Y" : "N");
+        FieldProviderFactory.setField(data[i], "isprepayment", 
paymentDetail.isPrepayment() ? "Y"
+            : "N");
         // Check if payment against invoice is in a previous date than invoice 
accounting date
-        boolean isPaymentDatePriorToInvoiceDate = 
isPaymentDatePriorToInvoiceDate(paymentDetails
-            .get(i));
+        boolean isPaymentDatePriorToInvoiceDate = 
isPaymentDatePriorToInvoiceDate(paymentDetail);
         FieldProviderFactory.setField(data[i], 
"isPaymentDatePriorToInvoiceDate",
-            isPaymentDatePriorToInvoiceDate && 
!paymentDetails.get(i).isPrepayment() ? "Y" : "N");
+            isPaymentDatePriorToInvoiceDate && !paymentDetail.isPrepayment() ? 
"Y" : "N");
         FieldProviderFactory.setField(data[i], "WriteOffAmt", 
writeOff.toString());
         FieldProviderFactory.setField(data[i], "cGlItemId",
-            paymentDetails.get(i).getGLItem() != null ? 
paymentDetails.get(i).getGLItem().getId()
-                : "");
+            paymentDetail.getGLItem() != null ? 
paymentDetail.getGLItem().getId() : "");
         // Calculate Business Partner from payment header or from details if 
header is null
         BusinessPartner bPartner = payment.getBusinessPartner() != null ? 
payment
-            .getBusinessPartner() : 
(paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getInvoicePaymentSchedule() != null ? paymentDetails.get(i)
-            
.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
-            .getBusinessPartner() : 
(paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getOrderPaymentSchedule() != null ? paymentDetails.get(i)
-            
.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getBusinessPartner() : 
(paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getBusinessPartner())));
+            .getBusinessPartner()
+            : 
(paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
 != null ? paymentDetail
+                
.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+                .getBusinessPartner()
+                : 
(paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
 != null ? paymentDetail
+                    
.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+                    .getBusinessPartner()
+                    : 
(paymentDetail.getFINPaymentScheduleDetailList().get(0).getBusinessPartner())));
         FieldProviderFactory.setField(data[i], "cBpartnerId", bPartner != null 
? bPartner.getId()
             : "");
-        FieldProviderFactory.setField(data[i], "Refund", 
paymentDetails.get(i).isRefund() ? "Y"
-            : "N");
-        FieldProviderFactory.setField(data[i], "adOrgId", 
paymentDetails.get(i).getOrganization()
-            .getId());
+        FieldProviderFactory.setField(data[i], "Refund", 
paymentDetail.isRefund() ? "Y" : "N");
+        FieldProviderFactory.setField(data[i], "adOrgId", 
paymentDetail.getOrganization().getId());
         FieldProviderFactory.setField(data[i], "description", 
transaction.getDescription());
         FieldProviderFactory.setField(data[i], "cCurrencyId", 
transaction.getCurrency().getId());
-        FieldProviderFactory.setField(data[i], "cProjectId", 
paymentDetails.get(i)
+        FieldProviderFactory.setField(data[i], "cProjectId", paymentDetail
             
.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getProject() != null 
? paymentDetails
-            
.get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getProject().getId() : (paymentDetails.get(i)
-            
.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=267308311&iu=/4140
_______________________________________________
Openbravo-commits mailing list
Openbravo-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to