FINERACT-2421: Adjust interest with MIR and CBR results in improper allocations
This commit is contained in:
committed by
Adam Saghy
parent
cc372286fa
commit
7b322481b8
+2
-1
@@ -57,7 +57,8 @@ public class ProgressivePossibleNextRepaymentCalculationServiceImpl extends Abst
|
||||
ProgressiveLoanInterestScheduleModel scheduleModel = optionalScheduleModel.get();
|
||||
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = loan.getRepaymentScheduleInstallments();
|
||||
ProgressiveTransactionCtx ctx = new ProgressiveTransactionCtx(loan.getCurrency(), repaymentScheduleInstallments, Set.of(),
|
||||
new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail(), scheduleModel);
|
||||
new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail(), scheduleModel,
|
||||
loan.getActiveLoanTermVariations());
|
||||
ctx.setChargedOff(loan.isChargedOff());
|
||||
ctx.setWrittenOff(loan.isClosedWrittenOff());
|
||||
ctx.setContractTerminated(loan.isContractTermination());
|
||||
|
||||
+2
-2
@@ -229,7 +229,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
ProgressiveLoanInterestScheduleModel scheduleModel = emiCalculator.generateInstallmentInterestScheduleModel(installments,
|
||||
LoanConfigurationDetailsMapper.map(loan), installmentAmountInMultiplesOf, overpaymentHolder.getMoneyObject().getMc());
|
||||
ProgressiveTransactionCtx ctx = new ProgressiveTransactionCtx(currency, installments, charges, overpaymentHolder,
|
||||
changedTransactionDetail, scheduleModel);
|
||||
changedTransactionDetail, scheduleModel, loan.getActiveLoanTermVariations());
|
||||
|
||||
List<ChangeOperation> changeOperations = createSortedChangeList(loanTermVariations, loanTransactions, charges);
|
||||
|
||||
@@ -571,7 +571,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
.filter(LoanTransaction::isNotReversed).filter(tr -> tr.getId() == null).toList());
|
||||
if (validateInterestRefundTransactionRelation(loanTransaction)) {
|
||||
final Money interestAfterRefund = interestRefundService.totalInterestByTransactions(this, loan.getId(), targetDate,
|
||||
modifiedTransactions, unmodifiedTransactionIds);
|
||||
modifiedTransactions, unmodifiedTransactionIds, ctx.getActiveLoanTermVariations());
|
||||
final Money newAmount = interestBeforeRefund.minus(progCtx.getSumOfInterestRefundAmount()).minus(interestAfterRefund);
|
||||
loanTransaction.updateAmount(newAmount.getAmount());
|
||||
}
|
||||
|
||||
+7
-4
@@ -28,6 +28,7 @@ import org.apache.fineract.organisation.monetary.domain.Money;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.MoneyHolder;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.TransactionCtx;
|
||||
@@ -52,14 +53,16 @@ public class ProgressiveTransactionCtx extends TransactionCtx {
|
||||
|
||||
public ProgressiveTransactionCtx(MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
|
||||
Set<LoanCharge> charges, MoneyHolder overpaymentHolder, ChangedTransactionDetail changedTransactionDetail,
|
||||
ProgressiveLoanInterestScheduleModel model) {
|
||||
this(currency, installments, charges, overpaymentHolder, changedTransactionDetail, model, Money.zero(currency));
|
||||
ProgressiveLoanInterestScheduleModel model, List<LoanTermVariations> activeLoanTermVariations) {
|
||||
this(currency, installments, charges, overpaymentHolder, changedTransactionDetail, model, Money.zero(currency),
|
||||
activeLoanTermVariations);
|
||||
}
|
||||
|
||||
public ProgressiveTransactionCtx(MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
|
||||
Set<LoanCharge> charges, MoneyHolder overpaymentHolder, ChangedTransactionDetail changedTransactionDetail,
|
||||
ProgressiveLoanInterestScheduleModel model, Money sumOfInterestRefundAmount) {
|
||||
super(currency, installments, charges, overpaymentHolder, changedTransactionDetail);
|
||||
ProgressiveLoanInterestScheduleModel model, Money sumOfInterestRefundAmount,
|
||||
List<LoanTermVariations> activeLoanTermVariations) {
|
||||
super(currency, installments, charges, overpaymentHolder, changedTransactionDetail, activeLoanTermVariations);
|
||||
this.sumOfInterestRefundAmount = sumOfInterestRefundAmount;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
+2
-1
@@ -112,7 +112,8 @@ public class InterestScheduleModelRepositoryWrapperImpl implements InterestSched
|
||||
savedModel = extractModel(progressiveLoanModel);
|
||||
if (savedModel.isPresent() && progressiveLoanModel.get().getBusinessDate().isBefore(businessDate)) {
|
||||
ProgressiveTransactionCtx ctx = new ProgressiveTransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(),
|
||||
Set.of(), new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail(), savedModel.get());
|
||||
Set.of(), new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail(), savedModel.get(),
|
||||
loan.getActiveLoanTermVariations());
|
||||
ctx.setChargedOff(loan.isChargedOff());
|
||||
ctx.setWrittenOff(loan.isClosedWrittenOff());
|
||||
ctx.setContractTerminated(loan.isContractTermination());
|
||||
|
||||
+14
-11
@@ -164,8 +164,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
when(charge.updatePaidAmountBy(refEq(chargeAmountMoney), eq(1), refEq(zero))).thenReturn(chargeAmountMoney);
|
||||
when(loanTransaction.isPenaltyPayment()).thenReturn(false);
|
||||
|
||||
underTest.processLatestTransaction(loanTransaction,
|
||||
new TransactionCtx(currency, List.of(installment), Set.of(charge), new MoneyHolder(overpaidAmount), null));
|
||||
underTest.processLatestTransaction(loanTransaction, new TransactionCtx(currency, List.of(installment), Set.of(charge),
|
||||
new MoneyHolder(overpaidAmount), null, loan.getActiveLoanTermVariations()));
|
||||
|
||||
Mockito.verify(installment, times(1)).payFeeChargesComponent(eq(transactionDate), eq(chargeAmountMoney));
|
||||
Mockito.verify(loanTransaction, times(1)).updateComponents(refEq(zero), refEq(zero), refEq(chargeAmountMoney), refEq(zero));
|
||||
@@ -208,8 +208,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
when(charge.updatePaidAmountBy(refEq(transactionAmountMoney), eq(1), refEq(zero))).thenReturn(transactionAmountMoney);
|
||||
when(loanTransaction.isPenaltyPayment()).thenReturn(false);
|
||||
|
||||
underTest.processLatestTransaction(loanTransaction,
|
||||
new TransactionCtx(currency, List.of(installment), Set.of(charge), new MoneyHolder(overpaidAmount), null));
|
||||
underTest.processLatestTransaction(loanTransaction, new TransactionCtx(currency, List.of(installment), Set.of(charge),
|
||||
new MoneyHolder(overpaidAmount), null, loan.getActiveLoanTermVariations()));
|
||||
|
||||
Mockito.verify(installment, times(1)).payFeeChargesComponent(eq(transactionDate), eq(transactionAmountMoney));
|
||||
Mockito.verify(loanTransaction, times(1)).updateComponents(refEq(zero), refEq(zero), refEq(transactionAmountMoney), refEq(zero));
|
||||
@@ -260,8 +260,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
when(loanPaymentAllocationRule.getAllocationTypes()).thenReturn(List.of(PaymentAllocationType.DUE_PRINCIPAL));
|
||||
when(loanTransaction.isOn(transactionDate)).thenReturn(true);
|
||||
|
||||
underTest.processLatestTransaction(loanTransaction,
|
||||
new TransactionCtx(currency, List.of(installment), Set.of(charge), new MoneyHolder(overpaidAmount), null));
|
||||
underTest.processLatestTransaction(loanTransaction, new TransactionCtx(currency, List.of(installment), Set.of(charge),
|
||||
new MoneyHolder(overpaidAmount), null, loan.getActiveLoanTermVariations()));
|
||||
|
||||
Mockito.verify(installment, times(1)).payFeeChargesComponent(transactionDate, chargeAmountMoney);
|
||||
Mockito.verify(loanTransaction, times(1)).updateComponents(refEq(zero), refEq(zero), refEq(chargeAmountMoney), refEq(zero));
|
||||
@@ -289,7 +289,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
installments.add(installment);
|
||||
|
||||
// when
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null);
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null,
|
||||
loan.getActiveLoanTermVariations());
|
||||
underTest.processCreditTransaction(chargebackTransaction, ctx);
|
||||
|
||||
// verify principal
|
||||
@@ -346,7 +347,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
installments.add(installment);
|
||||
|
||||
// when
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null);
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null,
|
||||
loan.getActiveLoanTermVariations());
|
||||
underTest.processCreditTransaction(chargebackTransaction, ctx);
|
||||
|
||||
// verify charges on installment
|
||||
@@ -398,7 +400,8 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
installments.add(installment2);
|
||||
|
||||
// when
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null);
|
||||
TransactionCtx ctx = new TransactionCtx(MONETARY_CURRENCY, installments, null, overpaymentHolder, null,
|
||||
loan.getActiveLoanTermVariations());
|
||||
underTest.processCreditTransaction(chargebackTransaction, ctx);
|
||||
|
||||
// verify principal
|
||||
@@ -491,7 +494,7 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
|
||||
// Set up TransactionCtx with installments and charges
|
||||
TransactionCtx ctx = new ProgressiveTransactionCtx(currency, installments, Set.of(), overpaymentHolder, changedTransactionDetail,
|
||||
model, null);
|
||||
model, loan.getActiveLoanTermVariations());
|
||||
|
||||
// Mock additional necessary methods
|
||||
LoanCharge loanCharge = mock(LoanCharge.class);
|
||||
@@ -570,7 +573,7 @@ class AdvancedPaymentScheduleTransactionProcessorTest {
|
||||
when(model.getMaturityDate()).thenReturn(LocalDate.of(2023, 12, 31));
|
||||
|
||||
TransactionCtx ctx = new ProgressiveTransactionCtx(currency, spyInstallments, Set.of(), new MoneyHolder(Money.zero(currency)),
|
||||
mock(ChangedTransactionDetail.class), model, Money.zero(currency));
|
||||
mock(ChangedTransactionDetail.class), model, Money.zero(currency), loan.getActiveLoanTermVariations());
|
||||
|
||||
underTest.processLatestTransaction(disbursementTransaction, ctx);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user