Program: 59158
Project: 59158
Buggy source:
/** 
 * Utiliser le trop perçu entre deux listes de lignes d'écritures (une en débit, une en crédit) Si cette methode doit être utilisée, penser à ordonner les listes qui lui sont passées par date croissante Ceci permet de payer les facture de manière chronologique.
 * @param debitMoveLines = dûs
 * @param creditMoveLines = trop-perçu
 * @return
 * @throws AxelorException 
 */
public void useExcessPaymentOnMoveLines(List<MoveLine> debitMoveLines,List<MoveLine> creditMoveLines,boolean updateCustomerAccount) throws AxelorException {
  if (debitMoveLines != null && creditMoveLines != null) {
    LOG.debug("String_Node_Str",new Object[]{debitMoveLines.size(),creditMoveLines.size()});
    BigDecimal amount=null;
    Reconcile reconcile=null;
    BigDecimal debitTotalRemaining=BigDecimal.ZERO;
    BigDecimal creditTotalRemaining=BigDecimal.ZERO;
    for (    MoveLine creditMoveLine : creditMoveLines) {
      creditTotalRemaining=creditTotalRemaining.add(creditMoveLine.getAmountRemaining());
    }
    for (    MoveLine debitMoveLine : debitMoveLines) {
      debitTotalRemaining=debitTotalRemaining.add(debitMoveLine.getAmountRemaining());
    }
    for (    MoveLine creditMoveLine : creditMoveLines) {
      if (creditMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1) {
        for (        MoveLine debitMoveLine : debitMoveLines) {
          if ((debitMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1) && (creditMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1)) {
            if (debitMoveLine.getMaxAmountToReconcile() != null && debitMoveLine.getMaxAmountToReconcile().compareTo(BigDecimal.ZERO) > 0) {
              amount=debitMoveLine.getMaxAmountToReconcile().min(creditMoveLine.getAmountRemaining());
              debitMoveLine.setMaxAmountToReconcile(null);
            }
 else {
              amount=creditMoveLine.getAmountRemaining().min(debitMoveLine.getAmountRemaining());
            }
            LOG.debug("String_Node_Str",amount);
            LOG.debug("String_Node_Str",debitTotalRemaining);
            LOG.debug("String_Node_Str",creditTotalRemaining);
            BigDecimal nextDebitTotalRemaining=debitTotalRemaining.subtract(amount);
            BigDecimal nextCreditTotalRemaining=creditTotalRemaining.subtract(amount);
            if (nextDebitTotalRemaining.compareTo(BigDecimal.ZERO) <= 0 || nextCreditTotalRemaining.compareTo(BigDecimal.ZERO) <= 0) {
              LOG.debug("String_Node_Str");
              if (creditMoveLine.getPaymentScheduleLine() != null && !pss.isLastSchedule(creditMoveLine.getPaymentScheduleLine())) {
                reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,false,false,false);
              }
 else {
                reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,true,false,false);
              }
            }
 else {
              reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,false,false,false);
            }
            rcs.confirmReconcile(reconcile,updateCustomerAccount);
            debitTotalRemaining=debitTotalRemaining.subtract(amount);
            creditTotalRemaining=creditTotalRemaining.subtract(amount);
            LOG.debug("String_Node_Str",reconcile);
          }
        }
      }
    }
  }
}

Fixed version (ground truth):
/** 
 * Utiliser le trop perçu entre deux listes de lignes d'écritures (une en débit, une en crédit) Si cette methode doit être utilisée, penser à ordonner les listes qui lui sont passées par date croissante Ceci permet de payer les facture de manière chronologique.
 * @param debitMoveLines = dûs
 * @param creditMoveLines = trop-perçu
 * @return
 * @throws AxelorException 
 */
public void useExcessPaymentOnMoveLines(List<MoveLine> debitMoveLines,List<MoveLine> creditMoveLines,boolean updateCustomerAccount) throws AxelorException {
  if (debitMoveLines != null && creditMoveLines != null) {
    LOG.debug("String_Node_Str",new Object[]{debitMoveLines.size(),creditMoveLines.size()});
    BigDecimal amount=null;
    Reconcile reconcile=null;
    BigDecimal debitTotalRemaining=BigDecimal.ZERO;
    BigDecimal creditTotalRemaining=BigDecimal.ZERO;
    for (    MoveLine creditMoveLine : creditMoveLines) {
      LOG.debug("String_Node_Str",creditMoveLine);
      LOG.debug("String_Node_Str",creditMoveLine.getAmountRemaining());
      creditTotalRemaining=creditTotalRemaining.add(creditMoveLine.getAmountRemaining());
    }
    for (    MoveLine debitMoveLine : debitMoveLines) {
      LOG.debug("String_Node_Str",debitMoveLine);
      LOG.debug("String_Node_Str",debitMoveLine.getAmountRemaining());
      debitTotalRemaining=debitTotalRemaining.add(debitMoveLine.getAmountRemaining());
    }
    for (    MoveLine creditMoveLine : creditMoveLines) {
      if (creditMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1) {
        for (        MoveLine debitMoveLine : debitMoveLines) {
          if ((debitMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1) && (creditMoveLine.getAmountRemaining().compareTo(BigDecimal.ZERO) == 1)) {
            if (debitMoveLine.getMaxAmountToReconcile() != null && debitMoveLine.getMaxAmountToReconcile().compareTo(BigDecimal.ZERO) > 0) {
              amount=debitMoveLine.getMaxAmountToReconcile().min(creditMoveLine.getAmountRemaining());
              debitMoveLine.setMaxAmountToReconcile(null);
            }
 else {
              amount=creditMoveLine.getAmountRemaining().min(debitMoveLine.getAmountRemaining());
            }
            LOG.debug("String_Node_Str",amount);
            LOG.debug("String_Node_Str",debitTotalRemaining);
            LOG.debug("String_Node_Str",creditTotalRemaining);
            BigDecimal nextDebitTotalRemaining=debitTotalRemaining.subtract(amount);
            BigDecimal nextCreditTotalRemaining=creditTotalRemaining.subtract(amount);
            if (nextDebitTotalRemaining.compareTo(BigDecimal.ZERO) <= 0 || nextCreditTotalRemaining.compareTo(BigDecimal.ZERO) <= 0) {
              LOG.debug("String_Node_Str");
              if (creditMoveLine.getPaymentScheduleLine() != null && !pss.isLastSchedule(creditMoveLine.getPaymentScheduleLine())) {
                reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,false,false,false);
              }
 else {
                reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,true,false,false);
              }
            }
 else {
              reconcile=rcs.createGenericReconcile(debitMoveLine,creditMoveLine,amount,false,false,false);
            }
            rcs.confirmReconcile(reconcile,updateCustomerAccount);
            debitTotalRemaining=debitTotalRemaining.subtract(amount);
            creditTotalRemaining=creditTotalRemaining.subtract(amount);
            LOG.debug("String_Node_Str",reconcile);
          }
        }
      }
    }
  }
}