adamsaghy commented on code in PR #3544:
URL: https://github.com/apache/fineract/pull/3544#discussion_r1375230128


##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java:
##########
@@ -176,6 +178,153 @@ private void handleRepayment(LoanTransaction 
loanTransaction, MonetaryCurrency c
             loanTransaction.resetDerivedComponents();
         }
         Money transactionAmountUnprocessed = 
loanTransaction.getAmount(currency);
+        handleOverAmount(loanTransaction, currency, installments, 
transactionAmountUnprocessed, charges);
+    }
+
+    private LoanTransactionToRepaymentScheduleMapping getTransactionMapping(
+            List<LoanTransactionToRepaymentScheduleMapping> 
transactionMappings, LoanTransaction loanTransaction,
+            LoanRepaymentScheduleInstallment currentInstallment, 
MonetaryCurrency currency) {
+        Money zero = Money.zero(currency);
+        LoanTransactionToRepaymentScheduleMapping 
loanTransactionToRepaymentScheduleMapping = transactionMappings.stream()
+                .filter(e -> loanTransaction.equals(e.getLoanTransaction()))
+                .filter(e -> 
currentInstallment.equals(e.getLoanRepaymentScheduleInstallment())).findFirst().orElse(null);
+        if (loanTransactionToRepaymentScheduleMapping == null) {
+            loanTransactionToRepaymentScheduleMapping = 
LoanTransactionToRepaymentScheduleMapping.createFrom(loanTransaction,
+                    currentInstallment, zero, zero, zero, zero);
+            transactionMappings.add(loanTransactionToRepaymentScheduleMapping);
+        }
+        return loanTransactionToRepaymentScheduleMapping;
+    }
+
+    private Money payAllocation(PaymentAllocationType paymentAllocationType, 
LoanRepaymentScheduleInstallment currentInstallment,
+            LoanTransaction loanTransaction, Money 
transactionAmountUnprocessed,
+            LoanTransactionToRepaymentScheduleMapping 
loanTransactionToRepaymentScheduleMapping, Balances balances) {
+        LocalDate transactionDate = loanTransaction.getTransactionDate();
+        Money zero = transactionAmountUnprocessed.zero();
+        return switch (paymentAllocationType.getAllocationType()) {
+            case PENALTY -> {
+                Money subPenaltyPortion = 
currentInstallment.payPenaltyChargesComponent(transactionDate, 
transactionAmountUnprocessed);
+                
balances.setAggregatedPenaltyChargesPortion(balances.getAggregatedPenaltyChargesPortion().add(subPenaltyPortion));
+                
addToTransactionMapping(loanTransactionToRepaymentScheduleMapping, zero, zero, 
zero, subPenaltyPortion);
+                yield subPenaltyPortion;
+            }
+            case FEE -> {
+                Money subFeePortion = 
currentInstallment.payFeeChargesComponent(transactionDate, 
transactionAmountUnprocessed);
+                
balances.setAggregatedFeeChargesPortion(balances.getAggregatedFeeChargesPortion().add(subFeePortion));
+                
addToTransactionMapping(loanTransactionToRepaymentScheduleMapping, zero, zero, 
subFeePortion, zero);
+                yield subFeePortion;
+            }
+            case INTEREST -> {
+                Money subInterestPortion = 
currentInstallment.payInterestComponent(transactionDate, 
transactionAmountUnprocessed);
+                
balances.setAggregatedInterestPortion(balances.getAggregatedInterestPortion().add(subInterestPortion));
+                
addToTransactionMapping(loanTransactionToRepaymentScheduleMapping, zero, 
subInterestPortion, zero, zero);
+                yield subInterestPortion;
+            }
+            case PRINCIPAL -> {
+                Money subPrincipalPortion = 
currentInstallment.payPrincipalComponent(transactionDate, 
transactionAmountUnprocessed);
+                
balances.setAggregatedPrincipalPortion(balances.getAggregatedPrincipalPortion().add(subPrincipalPortion));
+                
addToTransactionMapping(loanTransactionToRepaymentScheduleMapping, 
subPrincipalPortion, zero, zero, zero);
+                yield subPrincipalPortion;
+            }
+        };
+    }
+
+    private void 
addToTransactionMapping(LoanTransactionToRepaymentScheduleMapping 
loanTransactionToRepaymentScheduleMapping,
+            Money principalPortion, Money interestPortion, Money feePortion, 
Money penaltyPortion) {
+        BigDecimal aggregatedPenalty = ObjectUtils
+                
.defaultIfNull(loanTransactionToRepaymentScheduleMapping.getPenaltyChargesPortion(),
 BigDecimal.ZERO)
+                .add(penaltyPortion.getAmount());
+        BigDecimal aggregatedFee = ObjectUtils
+                
.defaultIfNull(loanTransactionToRepaymentScheduleMapping.getFeeChargesPortion(),
 BigDecimal.ZERO)
+                .add(feePortion.getAmount());
+        BigDecimal aggregatedInterest = ObjectUtils
+                
.defaultIfNull(loanTransactionToRepaymentScheduleMapping.getInterestPortion(), 
BigDecimal.ZERO)
+                .add(interestPortion.getAmount());
+        BigDecimal aggregatedPrincipal = ObjectUtils
+                
.defaultIfNull(loanTransactionToRepaymentScheduleMapping.getPrincipalPortion(), 
BigDecimal.ZERO)
+                .add(principalPortion.getAmount());
+        
loanTransactionToRepaymentScheduleMapping.setComponents(aggregatedPrincipal, 
aggregatedInterest, aggregatedFee, aggregatedPenalty);
+    }
+
+    private void handleOverpayment(Money overpaymentPortion, LoanTransaction 
loanTransaction) {
+        if (overpaymentPortion.isGreaterThanZero()) {
+            onLoanOverpayment(loanTransaction, overpaymentPortion);
+            loanTransaction.updateOverPayments(overpaymentPortion);
+        }
+    }
+
+    private void handleChargeOff(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments) {
+        loanTransaction.resetDerivedComponents();
+        // determine how much is outstanding total and breakdown for 
principal, interest and charges
+        Money principalPortion = Money.zero(currency);
+        Money interestPortion = Money.zero(currency);
+        Money feeChargesPortion = Money.zero(currency);
+        Money penaltychargesPortion = Money.zero(currency);
+        for (final LoanRepaymentScheduleInstallment currentInstallment : 
installments) {
+            if (currentInstallment.isNotFullyPaidOff()) {
+                principalPortion = 
principalPortion.plus(currentInstallment.getPrincipalOutstanding(currency));
+                interestPortion = 
interestPortion.plus(currentInstallment.getInterestOutstanding(currency));
+                feeChargesPortion = 
feeChargesPortion.plus(currentInstallment.getFeeChargesOutstanding(currency));
+                penaltychargesPortion = 
penaltychargesPortion.plus(currentInstallment.getPenaltyChargesCharged(currency));
+            }
+        }
+
+        loanTransaction.updateComponentsAndTotal(principalPortion, 
interestPortion, feeChargesPortion, penaltychargesPortion);
+    }
+
+    private void handleChargePayment(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> charges) {
+        Money zero = Money.zero(currency);

Review Comment:
   In line 126-128: There is a logic which copy the details of the loan 
transaction. In case of the LoanTransactionType is CHARGE PAYMENT, we  need to 
copy the charge paid by values as well hence we need to know the charge it is 
about to pay.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to