Program: 59078
Project: 59078
Buggy source:
/** 
 * Allows to load selected lines (from 1st 02M) to the 2nd O2M and dispatching amounts according to amountRemainnig for the loaded move and the paid amount remaining of the paymentVoucher 
 * @param paymentVoucher
 * @param paymentVoucherContext
 * @return 
 * @return 
 * @return values Map of data
 * @throws AxelorException 
 */
@Transactional(rollbackOn={AxelorException.class,Exception.class}) public PaymentVoucher loadSelectedLines(PaymentVoucher paymentVoucher,PaymentVoucher paymentVoucherContext) throws AxelorException {
  LOG.debug("String_Node_Str");
  List<PaymentInvoice> newPiList=Lists.newArrayList();
  if (paymentVoucherContext.getPaymentInvoiceList() != null) {
    List<PaymentInvoiceToPay> piToPayLine=new ArrayList<PaymentInvoiceToPay>();
    BigDecimal paidAmount=BigDecimal.ZERO;
    if (paymentVoucherContext.getPaidAmount() == null) {
      throw new AxelorException(String.format("String_Node_Str",GeneralService.getExceptionAccountingMsg()),IException.MISSING_FIELD);
    }
 else {
      paidAmount=paymentVoucherContext.getPaidAmount();
      BigDecimal amountToPay=BigDecimal.ZERO;
      int lineSeq=1;
      List<PaymentInvoice> pilSelected=new ArrayList<PaymentInvoice>();
      for (      PaymentInvoice pilContext : paymentVoucherContext.getPaymentInvoiceList()) {
        PaymentInvoice paymentInvoiceFromContext=PaymentInvoice.find(pilContext.getId());
        LOG.debug("String_Node_Str",paymentInvoiceFromContext);
        LOG.debug("String_Node_Str",pilContext.isSelected());
        if (pilContext.isSelected()) {
          pilSelected.add(paymentInvoiceFromContext);
        }
 else {
          PaymentInvoice paymentInvoice=new PaymentInvoice();
          if (paymentInvoiceFromContext.getMoveLine() != null) {
            paymentInvoice.setMoveLine(paymentInvoiceFromContext.getMoveLine());
          }
          paymentInvoice.setInvoiceAmount(paymentInvoiceFromContext.getInvoiceAmount());
          paymentInvoice.setPaidAmount(paymentInvoiceFromContext.getPaidAmount());
          paymentInvoice.setPaymentVoucher(paymentInvoiceFromContext.getPaymentVoucher());
          newPiList.add(paymentInvoice);
        }
      }
      paymentVoucher.getPaymentInvoiceList().clear();
      paymentVoucher.getPaymentInvoiceToPayList().clear();
      if (pilSelected != null && !pilSelected.isEmpty()) {
        if (paymentVoucherContext.getPaymentInvoiceToPayList() != null) {
          for (          PaymentInvoiceToPay pToPay : paymentVoucherContext.getPaymentInvoiceToPayList()) {
            PaymentInvoiceToPay piToPayFromContext=PaymentInvoiceToPay.find(pToPay.getId());
            PaymentInvoiceToPay piToPayOld=new PaymentInvoiceToPay();
            piToPayOld.setSequence(piToPayFromContext.getSequence());
            piToPayOld.setMoveLine(piToPayFromContext.getMoveLine());
            if (piToPayFromContext.getMoveLine() != null && piToPayFromContext.getMoveLine().getId() != null) {
              piToPayOld.setMoveLine(piToPayFromContext.getMoveLine());
            }
            piToPayOld.setTotalAmount(piToPayFromContext.getTotalAmount());
            piToPayOld.setRemainingAmount(piToPayFromContext.getRemainingAmount());
            piToPayOld.setAmountToPay(piToPayFromContext.getAmountToPay());
            piToPayOld.setPaymentVoucher(piToPayFromContext.getPaymentVoucher());
            piToPayLine.add(piToPayOld);
            if (paidAmount.compareTo(BigDecimal.ZERO) > 0) {
              paidAmount=paidAmount.subtract(piToPayFromContext.getAmountToPay());
            }
            lineSeq+=1;
          }
        }
        LOG.debug("String_Node_Str",piToPayLine);
        LOG.debug("String_Node_Str",pilSelected.size());
        for (        PaymentInvoice pil : pilSelected) {
          PaymentInvoiceToPay piToPay=new PaymentInvoiceToPay();
          MoveLine moveLine=pil.getMoveLine();
          Move move=moveLine.getMove();
          BigDecimal amountRemainingConverted=null;
          if (move.getInvoice() != null) {
            amountRemainingConverted=currencyService.getAmountCurrencyConverted(move.getInvoice().getCurrency(),paymentVoucher.getCurrency(),pil.getInvoiceAmount().subtract(pil.getPaidAmount()),paymentVoucher.getPaymentDateTime().toLocalDate());
            piToPay.setCurrency(move.getInvoice().getCurrency());
          }
 else {
            amountRemainingConverted=currencyService.getAmountCurrencyConverted(move.getCurrency(),paymentVoucher.getCurrency(),pil.getInvoiceAmount().subtract(pil.getPaidAmount()),paymentVoucher.getPaymentDateTime().toLocalDate());
            piToPay.setCurrency(move.getCurrency());
          }
          amountToPay=paidAmount.min(amountRemainingConverted);
          piToPay.setSequence(lineSeq);
          piToPay.setMoveLine(moveLine);
          piToPay.setTotalAmount(pil.getInvoiceAmount());
          piToPay.setRemainingAmount(pil.getInvoiceAmount().subtract(pil.getPaidAmount()));
          piToPay.setAmountToPay(amountToPay);
          piToPay.setPaymentVoucher(paymentVoucher);
          piToPayLine.add(piToPay);
          paidAmount=paidAmount.subtract(amountToPay);
          lineSeq+=1;
        }
      }
      if (piToPayLine != null && !piToPayLine.isEmpty()) {
        paymentVoucher.getPaymentInvoiceToPayList().addAll(piToPayLine);
      }
      paymentVoucher.getPaymentInvoiceList().addAll(newPiList);
    }
  }
  paymentVoucher.save();
  LOG.debug("String_Node_Str");
  return paymentVoucher;
}

Fixed version (ground truth):
/** 
 * Allows to load selected lines (from 1st 02M) to the 2nd O2M and dispatching amounts according to amountRemainnig for the loaded move and the paid amount remaining of the paymentVoucher 
 * @param paymentVoucher
 * @param paymentVoucherContext
 * @return 
 * @return 
 * @return values Map of data
 * @throws AxelorException 
 */
@Transactional(rollbackOn={AxelorException.class,Exception.class}) public PaymentVoucher loadSelectedLines(PaymentVoucher paymentVoucher,PaymentVoucher paymentVoucherContext) throws AxelorException {
  LOG.debug("String_Node_Str");
  List<PaymentInvoice> newPiList=Lists.newArrayList();
  if (paymentVoucherContext.getPaymentInvoiceList() != null) {
    List<PaymentInvoiceToPay> piToPayLine=new ArrayList<PaymentInvoiceToPay>();
    BigDecimal paidAmount=BigDecimal.ZERO;
    if (paymentVoucherContext.getPaidAmount() == null) {
      throw new AxelorException(String.format("String_Node_Str",GeneralService.getExceptionAccountingMsg()),IException.MISSING_FIELD);
    }
 else {
      paidAmount=paymentVoucherContext.getPaidAmount();
      BigDecimal amountToPay=BigDecimal.ZERO;
      int lineSeq=1;
      List<PaymentInvoice> paymentInvoiceSelectedList=new ArrayList<PaymentInvoice>();
      for (      PaymentInvoice pilContext : paymentVoucherContext.getPaymentInvoiceList()) {
        PaymentInvoice paymentInvoiceFromContext=PaymentInvoice.find(pilContext.getId());
        LOG.debug("String_Node_Str",paymentInvoiceFromContext);
        LOG.debug("String_Node_Str",pilContext.isSelected());
        if (pilContext.isSelected()) {
          paymentInvoiceSelectedList.add(paymentInvoiceFromContext);
        }
 else {
          PaymentInvoice paymentInvoice=new PaymentInvoice();
          if (paymentInvoiceFromContext.getMoveLine() != null) {
            paymentInvoice.setMoveLine(paymentInvoiceFromContext.getMoveLine());
          }
          paymentInvoice.setInvoiceAmount(paymentInvoiceFromContext.getInvoiceAmount());
          paymentInvoice.setPaidAmount(paymentInvoiceFromContext.getPaidAmount());
          paymentInvoice.setPaymentVoucher(paymentInvoiceFromContext.getPaymentVoucher());
          newPiList.add(paymentInvoice);
        }
      }
      paymentVoucher.getPaymentInvoiceList().clear();
      paymentVoucher.getPaymentInvoiceToPayList().clear();
      if (paymentInvoiceSelectedList != null && !paymentInvoiceSelectedList.isEmpty()) {
        if (paymentVoucherContext.getPaymentInvoiceToPayList() != null) {
          for (          PaymentInvoiceToPay pToPay : paymentVoucherContext.getPaymentInvoiceToPayList()) {
            PaymentInvoiceToPay piToPayFromContext=PaymentInvoiceToPay.find(pToPay.getId());
            PaymentInvoiceToPay piToPayOld=new PaymentInvoiceToPay();
            piToPayOld.setSequence(piToPayFromContext.getSequence());
            piToPayOld.setMoveLine(piToPayFromContext.getMoveLine());
            if (piToPayFromContext.getMoveLine() != null && piToPayFromContext.getMoveLine().getId() != null) {
              piToPayOld.setMoveLine(piToPayFromContext.getMoveLine());
            }
            piToPayOld.setTotalAmount(piToPayFromContext.getTotalAmount());
            piToPayOld.setRemainingAmount(piToPayFromContext.getRemainingAmount());
            piToPayOld.setAmountToPay(piToPayFromContext.getAmountToPay());
            piToPayOld.setPaymentVoucher(piToPayFromContext.getPaymentVoucher());
            piToPayLine.add(piToPayOld);
            if (paidAmount.compareTo(BigDecimal.ZERO) > 0) {
              paidAmount=paidAmount.subtract(piToPayFromContext.getAmountToPay());
            }
            lineSeq+=1;
          }
        }
        LOG.debug("String_Node_Str",piToPayLine);
        LOG.debug("String_Node_Str",paymentInvoiceSelectedList.size());
        for (        PaymentInvoice paymentInvoice : paymentInvoiceSelectedList) {
          PaymentInvoiceToPay paymentInvoiceToPay=new PaymentInvoiceToPay();
          MoveLine moveLine=paymentInvoice.getMoveLine();
          Move move=moveLine.getMove();
          BigDecimal amountRemainingConverted=null;
          paymentInvoiceToPay.setSequence(lineSeq);
          paymentInvoiceToPay.setMoveLine(moveLine);
          paymentInvoiceToPay.setTotalAmount(paymentInvoice.getInvoiceAmount());
          paymentInvoiceToPay.setRemainingAmount(paymentInvoice.getInvoiceAmount().subtract(paymentInvoice.getPaidAmount()));
          paymentInvoiceToPay.setPaymentVoucher(paymentVoucher);
          if (move.getInvoice() != null) {
            paymentInvoiceToPay.setCurrency(move.getInvoice().getCurrency());
          }
 else {
            paymentInvoiceToPay.setCurrency(move.getCurrency());
          }
          BigDecimal paidAmountConverted=currencyService.getAmountCurrencyConverted(paymentVoucher.getCurrency(),paymentInvoiceToPay.getCurrency(),paymentInvoiceToPay.getRemainingAmount(),paymentVoucher.getPaymentDateTime().toLocalDate());
          amountToPay=paidAmountConverted.min(paymentInvoiceToPay.getRemainingAmount());
          paymentInvoiceToPay.setAmountToPay(amountToPay);
          piToPayLine.add(paymentInvoiceToPay);
          paidAmount=paidAmount.subtract(amountToPay);
          lineSeq+=1;
        }
      }
      if (piToPayLine != null && !piToPayLine.isEmpty()) {
        paymentVoucher.getPaymentInvoiceToPayList().addAll(piToPayLine);
      }
      paymentVoucher.getPaymentInvoiceList().addAll(newPiList);
    }
  }
  paymentVoucher.save();
  LOG.debug("String_Node_Str");
  return paymentVoucher;
}