@@ -3171,14 +3171,15 @@ private LoanRepaymentScheduleInstallment createInstallmentWithMovedPaidAmounts(f
31713171 private void reprocessInstallments (final List <LoanRepaymentScheduleInstallment > installments ) {
31723172 final AtomicInteger counter = new AtomicInteger (1 );
31733173 final AtomicReference <LocalDate > previousDueDate = new AtomicReference <>(null );
3174- installments .stream ().sorted (LoanRepaymentScheduleInstallment ::compareToByDueDate ).forEachOrdered (i -> {
3174+ installments .stream ().sorted (LoanRepaymentScheduleInstallment ::compareToByFromDueDate ).forEachOrdered (i -> {
31753175 i .updateInstallmentNumber (counter .getAndIncrement ());
31763176 final LocalDate prev = previousDueDate .get ();
31773177 if (prev != null && (i .isAdditional () || i .isReAged ())) {
31783178 i .updateFromDate (prev );
31793179 }
31803180 previousDueDate .set (i .getDueDate ());
31813181 });
3182+ installments .sort (LoanRepaymentScheduleInstallment ::compareToByFromDueDate );
31823183 }
31833184
31843185 private LocalDate calculateReAgedInstallmentDueDate (final LoanReAgeParameter reAgeParameter , final LocalDate dueDate ) {
@@ -3479,12 +3480,8 @@ private void handleReAgeEqualAmortizationEMICalculator(LoanTransaction loanTrans
34793480 BalancesWithPaidInAdvance paidInAdvanceBalances = liftEarlyRepaidBalances (installments , transactionDate , currency ,
34803481 ctx .getAlreadyProcessedTransactions ());
34813482
3482- // TODO add as Parameter here: paidInAdvanceBalances.getAggregatedFeeChargesPortion().isGreaterThanZero() ||
3483- // paidInAdvanceBalances.getAggregatedPenaltyChargesPortion().isGreaterThanZero()
34843483 emiCalculator .reAgeEqualAmortization (model , transactionDate , loanReAgeParameter ,
3485- outstandingBalances .fees .add (outstandingBalances .penalties ),
3486- new EqualAmortizationValues (calculatedFees .value ().add (calculatedPenalties .value ()),
3487- calculatedFees .adjustment ().add (calculatedPenalties .adjustment ())));
3484+ outstandingBalances .fees .add (outstandingBalances .penalties ), calculatedFees .add (calculatedPenalties ));
34883485
34893486 installments .removeIf (i -> (i .getInstallmentNumber () != null && !i .isDownPayment () && !i .getDueDate ().isBefore (transactionDate )
34903487 && !i .isAdditional ()) || (!i .getDueDate ().isAfter (model .getMaturityDate ()) && i .isAdditional ()));
@@ -3494,6 +3491,7 @@ private void handleReAgeEqualAmortizationEMICalculator(LoanTransaction loanTrans
34943491 i .setInstallmentNumber (model .repaymentPeriods ().size ());
34953492 });
34963493
3494+ int reAgedInstallmentIndex = 0 ;
34973495 for (int index = 0 ; index < model .repaymentPeriods ().size (); index ++) {
34983496 RepaymentPeriod rp = model .repaymentPeriods ().get (index );
34993497 if (rp .getDueDate ().isBefore (transactionDate )) {
@@ -3504,9 +3502,9 @@ private void handleReAgeEqualAmortizationEMICalculator(LoanTransaction loanTrans
35043502 installment .setInterestCharged (installment .getInterestPaid ());
35053503 installment .setPrincipal (installment .getPrincipalCompleted (currency ).getAmount ());
35063504 installment .setInstallmentNumber (index + 1 );
3505+ installment .setCreditedPrincipal (rp .getCreditedPrincipal ().getAmount ());
35073506
35083507 installment .updateObligationsMet (currency , transactionDate );
3509- // TODO add remaining components
35103508 } else {
35113509 LoanRepaymentScheduleInstallment created = LoanRepaymentScheduleInstallment .newReAgedInstallment (loanTransaction .getLoan (),
35123510 index + 1 , rp .getFromDate (), rp .getDueDate (), rp .getDuePrincipal ().getAmount (), rp .getDueInterest ().getAmount (),
@@ -3525,16 +3523,17 @@ private void handleReAgeEqualAmortizationEMICalculator(LoanTransaction loanTrans
35253523
35263524 paidInAdvanceBalances .loanTransactionToRepaymentScheduleMappings .forEach (m -> m .setInstallment (created ));
35273525 } else {
3528- boolean isLastRepaymentPeriod = model .isLastRepaymentPeriod (rp );
3529- created .setFeeChargesCharged (calculatedFees .calculateValueBigDecimal (isLastRepaymentPeriod ));
3530- created .setPenaltyCharges (calculatedPenalties .calculateValueBigDecimal (isLastRepaymentPeriod ));
3526+ created .setFeeChargesCharged (calculatedFees .calculateValueBigDecimal (reAgedInstallmentIndex ));
3527+ created .setPenaltyCharges (calculatedPenalties .calculateValueBigDecimal (reAgedInstallmentIndex ));
35313528
3532- created .setInterestAccrued (calculatedInterestAccrued .calculateValueBigDecimal (isLastRepaymentPeriod ));
3533- created .setFeeAccrued (calculatedFeeAccrued .calculateValueBigDecimal (isLastRepaymentPeriod ));
3534- created .setPenaltyAccrued (calculatedPenaltyAccrued .calculateValueBigDecimal (isLastRepaymentPeriod ));
3529+ created .setInterestAccrued (calculatedInterestAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ));
3530+ created .setFeeAccrued (calculatedFeeAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ));
3531+ created .setPenaltyAccrued (calculatedPenaltyAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ));
35353532
3536- createChargeMappingsForInstallment (created , calculatedCharges , isLastRepaymentPeriod );
3533+ createChargeMappingsForInstallment (created , calculatedCharges , reAgedInstallmentIndex );
3534+ reAgedInstallmentIndex ++;
35373535 }
3536+ created .setCreditedPrincipal (rp .getCreditedPrincipal ().getAmount ());
35383537 created .updateObligationsMet (currency , transactionDate );
35393538 installments .add (created );
35403539 }
@@ -3549,6 +3548,9 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
35493548 List <LoanRepaymentScheduleInstallment > installments = ctx .getInstallments ();
35503549 LoanReAgeParameter loanReAgeParameter = loanTransaction .getLoanReAgeParameter ();
35513550 LocalDate transactionDate = loanTransaction .getTransactionDate ();
3551+ LocalDate originalMaturityDate = installments .stream ()
3552+ .filter (i -> !i .isDownPayment () && !i .isAdditional () && i .getDueDate () != null )
3553+ .map (LoanRepaymentScheduleInstallment ::getDueDate ).max (LocalDate ::compareTo ).orElseThrow ();
35523554
35533555 Integer numberOfReAgeInstallments = loanReAgeParameter .getNumberOfInstallments ();
35543556 Integer installmentAmountInMultiplesOf = loanTransaction .getLoan ().getLoanProductRelatedDetail ()
@@ -3613,8 +3615,7 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
36133615 return res ;
36143616 }).reduce (new BalancesWithPaidInAdvance (currency ), BalancesWithPaidInAdvance ::summarizerAccumulator );
36153617
3616- if (!balances .getPrincipal ().isZero () || !balances .getInterest ().isZero () || !balances .getFee ().isZero ()
3617- || !balances .getPenalty ().isZero ()) {
3618+ if (!transactionDate .isAfter (originalMaturityDate )) {
36183619
36193620 final LoanRepaymentScheduleInstallment earlyRepaidInstallment = LoanRepaymentScheduleInstallment .newReAgedInstallment (loan ,
36203621 firstReAgeInstallmentProps .reAgedInstallmentNumber (), firstReAgeInstallmentProps .fromDate (), transactionDate ,
@@ -3634,37 +3635,39 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
36343635
36353636 InstallmentProcessingHelper .addOneToInstallmentNumberFromInstallment (installments ,
36363637 earlyRepaidInstallment .getInstallmentNumber ());
3637- loan . getRepaymentScheduleInstallments () .add (earlyRepaidInstallment );
3638+ installments .add (earlyRepaidInstallment );
36383639 }
36393640
3641+ // installment index which excludes earlyRepaidInstallment intallment index.
3642+ Integer reAgedInstallmentIndex = 0 ;
36403643 LoanRepaymentScheduleInstallment reAgedInstallment = LoanRepaymentScheduleInstallment .newReAgedInstallment (loan ,
36413644 firstReAgeInstallmentProps .reAgedInstallmentNumber , firstReAgeInstallmentProps .fromDate , loanReAgeParameter .getStartDate (),
36423645 calculatedPrincipal .value ().getAmount (), calculatedInterest .value ().getAmount (), calculatedFees .value ().getAmount (),
36433646 calculatedPenalties .value ().getAmount (), calculatedInterestAccrued .value ().getAmount (),
36443647 calculatedFeeAccrued .value ().getAmount (), calculatedPenaltyAccrued .value ().getAmount ());
36453648
36463649 reAgedInstallment = insertOrReplaceRelatedInstallment (installments , reAgedInstallment , currency , transactionDate );
3647- createChargeMappingsForInstallment (reAgedInstallment , calculatedCharges , false );
3648-
3650+ createChargeMappingsForInstallment (reAgedInstallment , calculatedCharges , reAgedInstallmentIndex );
3651+ reAgedInstallmentIndex ++;
36493652 for (int i = 1 ; i < numberOfReAgeInstallments ; i ++) {
36503653 LocalDate calculatedDueDate = scheduledDateGenerator .getRepaymentPeriodDate (loanReAgeParameter .getFrequencyType (),
36513654 loanReAgeParameter .getFrequencyNumber (), reAgedInstallment .getDueDate ());
36523655 calculateReAgedInstallmentDueDate (loanReAgeParameter , reAgedInstallment .getDueDate ());
36533656 int nextReAgedInstallmentNumber = firstReAgeInstallmentProps .reAgedInstallmentNumber + i ;
3654- boolean isLastInstallment = i + 1 == numberOfReAgeInstallments ;
36553657
36563658 reAgedInstallment = LoanRepaymentScheduleInstallment .newReAgedInstallment (reAgedInstallment .getLoan (),
36573659 nextReAgedInstallmentNumber , reAgedInstallment .getDueDate (), calculatedDueDate ,
3658- calculatedPrincipal .calculateValueBigDecimal (isLastInstallment ),
3659- calculatedInterest .calculateValueBigDecimal (isLastInstallment ),
3660- calculatedFees .calculateValueBigDecimal (isLastInstallment ),
3661- calculatedPenalties .calculateValueBigDecimal (isLastInstallment ),
3662- calculatedInterestAccrued .calculateValueBigDecimal (isLastInstallment ),
3663- calculatedFeeAccrued .calculateValueBigDecimal (isLastInstallment ),
3664- calculatedPenaltyAccrued .calculateValueBigDecimal (isLastInstallment ));
3660+ calculatedPrincipal .calculateValueBigDecimal (reAgedInstallmentIndex ),
3661+ calculatedInterest .calculateValueBigDecimal (reAgedInstallmentIndex ),
3662+ calculatedFees .calculateValueBigDecimal (reAgedInstallmentIndex ),
3663+ calculatedPenalties .calculateValueBigDecimal (reAgedInstallmentIndex ),
3664+ calculatedInterestAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ),
3665+ calculatedFeeAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ),
3666+ calculatedPenaltyAccrued .calculateValueBigDecimal (reAgedInstallmentIndex ));
36653667
36663668 reAgedInstallment = insertOrReplaceRelatedInstallment (installments , reAgedInstallment , currency , transactionDate );
3667- createChargeMappingsForInstallment (reAgedInstallment , calculatedCharges , isLastInstallment );
3669+ createChargeMappingsForInstallment (reAgedInstallment , calculatedCharges , reAgedInstallmentIndex );
3670+ reAgedInstallmentIndex ++;
36683671 }
36693672 int lastReAgedInstallmentNumber = reAgedInstallment .getInstallmentNumber ();
36703673 List <LoanRepaymentScheduleInstallment > toRemove = installments .stream ()
@@ -3676,11 +3679,10 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
36763679 }
36773680
36783681 private void createChargeMappingsForInstallment (final LoanRepaymentScheduleInstallment installment ,
3679- List <ReAgedChargeEqualAmortizationValues > reAgedChargeEqualAmortizationValues , boolean isLastInstallment ) {
3682+ List <ReAgedChargeEqualAmortizationValues > reAgedChargeEqualAmortizationValues , Integer index ) {
36803683 reAgedChargeEqualAmortizationValues .forEach (amortizationValue -> {
3681- installment .getInstallmentCharges ()
3682- .add (new LoanInstallmentCharge (amortizationValue .equalAmortizationValues .calculateValueBigDecimal (isLastInstallment ),
3683- amortizationValue .charge , installment ));
3684+ installment .getInstallmentCharges ().add (new LoanInstallmentCharge (
3685+ amortizationValue .equalAmortizationValues .calculateValueBigDecimal (index ), amortizationValue .charge , installment ));
36843686 });
36853687 }
36863688
0 commit comments