Fixes issue 31580: Java Heap Space error when posting payment with many details
authorAlvaro Ferraz <alvaro.ferraz@openbravo.com>
Tue, 01 Dec 2015 16:44:30 +0100
changeset 28180 217fb3a426fe
parent 28179 0759c894c939
child 28181 1817418c55af
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.
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_Utility.java
src/org/openbravo/erpCommon/ad_forms/AcctServer.java
src/org/openbravo/erpCommon/ad_forms/DocFINFinAccTransaction.java
src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java
src/org/openbravo/erpCommon/ad_forms/DocFINReconciliation.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 01 16:44:30 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,39 @@
   }
 
   /**
+   * 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();
+    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());
+      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) {
--- 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 01 16:44:30 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);
           }
         }
       }
--- 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 01 16:44:30 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)
-                .getOrderPaymentSchedule().getOrder().getProject() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getProject().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getProject() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getProject().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cCampaignId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getSalesCampaign() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getSalesCampaign() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getProject().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject().getId() : "")));
-        FieldProviderFactory
-            .setField(
-                data[i],
-                "cCampaignId",
-                paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                    .getInvoicePaymentSchedule() != null
-                    && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getInvoicePaymentSchedule().getInvoice().getSalesCampaign() != null ? paymentDetails
-                    .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-                    .getInvoice().getSalesCampaign().getId()
-                    : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getOrderPaymentSchedule() != null
-                        && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getOrderPaymentSchedule().getOrder().getSalesCampaign() != null ? paymentDetails
-                        .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
-                        .getOrder().getSalesCampaign().getId()
-                        : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getSalesCampaign() != null ? paymentDetails.get(i)
-                            .getFINPaymentScheduleDetailList().get(0).getSalesCampaign().getId()
-                            : "")));
-        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetails.get(i)
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getActivity() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getActivity().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getActivity() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getActivity().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity().getId() : "")));
-        FieldProviderFactory.setField(data[i], "mProductId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getActivity().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getActivity() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getActivity().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity().getId() : "")));
+        FieldProviderFactory.setField(data[i], "mProductId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getProduct().getId() : "");
-        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
+        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
         FieldProviderFactory.setField(data[i], "lineno", transaction.getLineNo().toString());
 
-        FieldProviderFactory.setField(data[i], "user1Id", paymentDetails.get(i)
+        FieldProviderFactory.setField(data[i], "user1Id", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getStDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getStDimension().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getStDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getStDimension().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getStDimension() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getStDimension().getId() : "")));
-        FieldProviderFactory.setField(data[i], "user2Id", paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getStDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getStDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getStDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+            .getStDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getStDimension() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getStDimension().getId() : "")));
+        FieldProviderFactory.setField(data[i], "user2Id", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getNdDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getNdDimension().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getNdDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getNdDimension().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getNdDimension() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getNdDimension().getId() : "")));
-        FieldProviderFactory
-            .setField(
-                data[i],
-                "cCostcenterId",
-                paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                    .getInvoicePaymentSchedule() != null
-                    && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getInvoicePaymentSchedule().getInvoice().getCostcenter() != null ? paymentDetails
-                    .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-                    .getInvoice().getCostcenter().getId()
-                    : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getOrderPaymentSchedule() != null
-                        && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getOrderPaymentSchedule().getOrder().getCostcenter() != null ? paymentDetails
-                        .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
-                        .getOrder().getCostcenter().getId()
-                        : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getCostCenter() != null ? paymentDetails.get(i)
-                            .getFINPaymentScheduleDetailList().get(0).getCostCenter().getId() : "")));
-        FieldProviderFactory.setField(data[i], "recordId2",
-            paymentDetails.get(i).isPrepayment() ? (pso != null ? pso.getId() : "")
-                : (psi != null ? psi.getId() : ""));
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getNdDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getNdDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getNdDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+            .getNdDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getNdDimension() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getNdDimension().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cCostcenterId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getCostcenter() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getCostcenter().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getCostcenter() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+            .getCostcenter().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getCostCenter() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getCostCenter().getId() : "")));
+        FieldProviderFactory.setField(
+            data[i],
+            "recordId2",
+            paymentDetail.isPrepayment() ? (pso != null ? pso.getId() : "") : (psi != null ? psi
+                .getId() : ""));
 
       }
     } finally {
--- a/src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java	Mon Jan 11 13:20:26 2016 +0100
+++ b/src/org/openbravo/erpCommon/ad_forms/DocFINPayment.java	Tue Dec 01 16:44:30 2015 +0100
@@ -86,7 +86,7 @@
 
   public FieldProviderFactory[] loadLinesFieldProvider(String Id) {
     FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class, Id);
-    List<FIN_PaymentDetail> paymentDetails = FIN_Utility.getOrderedPaymentDetailList(payment);
+    List<String> paymentDetails = FIN_Utility.getOrderedPaymentDetailList(Id);
     if (paymentDetails == null)
       return null;
 
@@ -96,28 +96,39 @@
     OBContext.setAdminMode();
     try {
       for (int i = 0; i < data.length; i++) {
+        FIN_PaymentDetail paymentDetail = OBDal.getInstance().get(FIN_PaymentDetail.class,
+            paymentDetails.get(i));
+
         // 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) {
@@ -129,142 +140,123 @@
         }
         ps = psi;
 
-        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());
         // Calculate Business Partner from payment header or from details if header is null or from
         // the PSD in case of GL Item
         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], "DoubtFulDebtAmount", paymentDetails.get(i)
+        FieldProviderFactory.setField(data[i], "DoubtFulDebtAmount", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getDoubtfulDebtAmount().toString());
         FieldProviderFactory.setField(data[i], "WriteOffAmt", writeOff.toString());
         FieldProviderFactory.setField(data[i], "C_GLItem_ID",
-            paymentDetails.get(i).getGLItem() != null ? paymentDetails.get(i).getGLItem().getId()
-                : "");
-        FieldProviderFactory.setField(data[i], "Refund", paymentDetails.get(i).isRefund() ? "Y"
-            : "N");
+            paymentDetail.getGLItem() != null ? paymentDetail.getGLItem().getId() : "");
+        FieldProviderFactory.setField(data[i], "Refund", paymentDetail.isRefund() ? "Y" : "N");
         // Check if payment against invoice is in a previous date than invoice accounting date
-        boolean isPaymentDatePriorToInvoiceDate = isPaymentDatePriorToInvoiceDate(paymentDetails
-            .get(i));
-        FieldProviderFactory.setField(data[i], "isprepayment",
-            paymentDetails.get(i).isPrepayment() ? "Y" : (isPaymentDatePriorToInvoiceDate ? "Y"
-                : "N"));
+        boolean isPaymentDatePriorToInvoiceDate = isPaymentDatePriorToInvoiceDate(paymentDetail);
+        FieldProviderFactory.setField(data[i], "isprepayment", paymentDetail.isPrepayment() ? "Y"
+            : (isPaymentDatePriorToInvoiceDate ? "Y" : "N"));
         FieldProviderFactory.setField(data[i], "isPaymentDatePriorToInvoiceDate",
-            isPaymentDatePriorToInvoiceDate && !paymentDetails.get(i).isPrepayment() ? "Y" : "N");
-        FieldProviderFactory.setField(data[i], "cProjectId", paymentDetails.get(i)
+            isPaymentDatePriorToInvoiceDate && !paymentDetail.isPrepayment() ? "Y" : "N");
+        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)
-                .getOrderPaymentSchedule().getOrder().getProject() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getProject().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getProject() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getProject().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cCampaignId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getSalesCampaign() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getSalesCampaign() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getProject().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject().getId() : "")));
-        FieldProviderFactory
-            .setField(
-                data[i],
-                "cCampaignId",
-                paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                    .getInvoicePaymentSchedule() != null
-                    && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getInvoicePaymentSchedule().getInvoice().getSalesCampaign() != null ? paymentDetails
-                    .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-                    .getInvoice().getSalesCampaign().getId()
-                    : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getOrderPaymentSchedule() != null
-                        && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getOrderPaymentSchedule().getOrder().getSalesCampaign() != null ? paymentDetails
-                        .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
-                        .getOrder().getSalesCampaign().getId()
-                        : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getSalesCampaign() != null ? paymentDetails.get(i)
-                            .getFINPaymentScheduleDetailList().get(0).getSalesCampaign().getId()
-                            : "")));
-        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetails.get(i)
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getActivity() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getActivity().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getActivity() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getActivity().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getActivity() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getActivity().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity().getId() : "")));
+        FieldProviderFactory.setField(data[i], "mProductId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProduct().getId() : "");
+        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
+        FieldProviderFactory.setField(data[i], "cCostcenterId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getCostcenter() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getCostcenter().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getCostcenter() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getActivity().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity().getId() : "")));
-        FieldProviderFactory.setField(data[i], "mProductId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getProduct().getId() : "");
-        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
-        FieldProviderFactory
-            .setField(
-                data[i],
-                "cCostcenterId",
-                paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                    .getInvoicePaymentSchedule() != null
-                    && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getInvoicePaymentSchedule().getInvoice().getCostcenter() != null ? paymentDetails
-                    .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-                    .getInvoice().getCostcenter().getId()
-                    : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getOrderPaymentSchedule() != null
-                        && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getOrderPaymentSchedule().getOrder().getCostcenter() != null ? paymentDetails
-                        .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
-                        .getOrder().getCostcenter().getId()
-                        : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getCostCenter() != null ? paymentDetails.get(i)
-                            .getFINPaymentScheduleDetailList().get(0).getCostCenter().getId() : "")));
+            .getCostcenter().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getCostCenter() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getCostCenter().getId() : "")));
 
-        FieldProviderFactory.setField(data[i], "user1Id", paymentDetails.get(i)
+        FieldProviderFactory.setField(data[i], "user1Id", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getStDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getStDimension().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getStDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getStDimension().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getStDimension() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getStDimension().getId() : "")));
-        FieldProviderFactory.setField(data[i], "user2Id", paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getStDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getStDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getStDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+            .getStDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getStDimension() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getStDimension().getId() : "")));
+        FieldProviderFactory.setField(data[i], "user2Id", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getNdDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getNdDimension().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getNdDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getNdDimension().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getNdDimension() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getNdDimension().getId() : "")));
-        FieldProviderFactory.setField(data[i], "recordId2",
-            paymentDetails.get(i).isPrepayment() ? (pso != null ? pso.getId() : "")
-                : (psi != null ? psi.getId() : ""));
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getNdDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getNdDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getNdDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
+            .getNdDimension().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getNdDimension() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getNdDimension().getId() : "")));
+        FieldProviderFactory.setField(
+            data[i],
+            "recordId2",
+            paymentDetail.isPrepayment() ? (pso != null ? pso.getId() : "") : (psi != null ? psi
+                .getId() : ""));
 
       }
     } finally {
--- a/src/org/openbravo/erpCommon/ad_forms/DocFINReconciliation.java	Mon Jan 11 13:20:26 2016 +0100
+++ b/src/org/openbravo/erpCommon/ad_forms/DocFINReconciliation.java	Tue Dec 01 16:44:30 2015 +0100
@@ -163,35 +163,46 @@
       FIN_FinaccTransaction transaction) {
     FIN_Payment payment = OBDal.getInstance().get(FIN_Payment.class,
         transaction.getFinPayment().getId());
-    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));
+
         // 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) {
@@ -206,12 +217,10 @@
         FieldProviderFactory.setField(data[i], "FIN_Reconciliation_ID", transaction
             .getReconciliation().getId());
         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());
         String dateFormat = OBPropertiesProvider.getInstance().getOpenbravoProperties()
             .getProperty("dateFormat.java");
@@ -222,33 +231,30 @@
             .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], "Refund", paymentDetail.isRefund() ? "Y" : "N");
         FieldProviderFactory.setField(data[i], "adOrgId", transaction.getOrganization().getId());
         FieldProviderFactory.setField(
             data[i],
@@ -257,74 +263,66 @@
                 .getField("cGlItemId"));
         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)
-                .getOrderPaymentSchedule().getOrder().getProject() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getProject().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getProject() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getProject().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProject().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cCampaignId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getSalesCampaign() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getSalesCampaign() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getProject().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-            .getProject().getId() : "")));
-        FieldProviderFactory
-            .setField(
-                data[i],
-                "cCampaignId",
-                paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                    .getInvoicePaymentSchedule() != null
-                    && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getInvoicePaymentSchedule().getInvoice().getSalesCampaign() != null ? paymentDetails
-                    .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-                    .getInvoice().getSalesCampaign().getId()
-                    : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                        .getOrderPaymentSchedule() != null
-                        && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getOrderPaymentSchedule().getOrder().getSalesCampaign() != null ? paymentDetails
-                        .get(i).getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
-                        .getOrder().getSalesCampaign().getId()
-                        : (paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                            .getSalesCampaign() != null ? paymentDetails.get(i)
-                            .getFINPaymentScheduleDetailList().get(0).getSalesCampaign().getId()
-                            : "")));
-        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetails.get(i)
+            .getSalesCampaign().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign() != null ? paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getSalesCampaign().getId() : "")));
+        FieldProviderFactory.setField(data[i], "cActivityId", paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getInvoicePaymentSchedule().getInvoice().getActivity() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
-            .getInvoice().getActivity().getId() : (paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule() != null
-            && paymentDetails.get(i).getFINPaymentScheduleDetailList().get(0)
-                .getOrderPaymentSchedule().getOrder().getActivity() != null ? paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule().getOrder()
-            .getActivity().getId() : (paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity() != null ? paymentDetails.get(i).getFINPaymentScheduleDetailList()
-            .get(0).getActivity().getId() : "")));
-        FieldProviderFactory.setField(data[i], "mProductId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetails.get(i)
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule()
+                .getInvoice().getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getInvoicePaymentSchedule().getInvoice()
+            .getActivity().getId() : (paymentDetail.getFINPaymentScheduleDetailList().get(0)
+            .getOrderPaymentSchedule() != null
+            && paymentDetail.getFINPaymentScheduleDetailList().get(0).getOrderPaymentSchedule()
+                .getOrder().getActivity() != null ? paymentDetail.getFINPaymentScheduleDetailList()
+            .get(0).getOrderPaymentSchedule().getOrder().getActivity().getId() : (paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getActivity().getId() : "")));
+        FieldProviderFactory.setField(data[i], "mProductId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getProduct() != null ? paymentDetail
             .getFINPaymentScheduleDetailList().get(0).getProduct().getId() : "");
-        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
-        FieldProviderFactory
-            .setField(data[i], "cCostcenterId", paymentDetails.get(i)
-                .getFINPaymentScheduleDetailList().get(0).getCostCenter() != null ? paymentDetails
-                .get(i).getFINPaymentScheduleDetailList().get(0).getCostCenter().getId() : "");
+        FieldProviderFactory.setField(data[i], "cSalesregionId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getSalesRegion().getId() : "");
+        FieldProviderFactory.setField(data[i], "cCostcenterId", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getCostCenter() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getCostCenter().getId() : "");
         FieldProviderFactory.setField(data[i], "lineno", transaction.getLineNo().toString());
 
-        FieldProviderFactory.setField(data[i], "user1Id", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getStDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getStDimension().getId() : "");
+        FieldProviderFactory.setField(data[i], "user1Id", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getStDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getStDimension().getId() : "");
 
-        FieldProviderFactory.setField(data[i], "user2Id", paymentDetails.get(i)
-            .getFINPaymentScheduleDetailList().get(0).getNdDimension() != null ? paymentDetails
-            .get(i).getFINPaymentScheduleDetailList().get(0).getNdDimension().getId() : "");
-        FieldProviderFactory.setField(data[i], "recordId2",
-            paymentDetails.get(i).isPrepayment() ? (pso != null ? pso.getId() : "")
-                : (psi != null ? psi.getId() : ""));
+        FieldProviderFactory.setField(data[i], "user2Id", paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getNdDimension() != null ? paymentDetail
+            .getFINPaymentScheduleDetailList().get(0).getNdDimension().getId() : "");
+        FieldProviderFactory.setField(
+            data[i],
+            "recordId2",
+            paymentDetail.isPrepayment() ? (pso != null ? pso.getId() : "") : (psi != null ? psi
+                .getId() : ""));
       }
     } finally {
       OBContext.restorePreviousMode();