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


##########
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java:
##########
@@ -74,20 +92,285 @@ protected Money 
handleRefundTransactionPaymentOfInstallment(LoanRepaymentSchedul
     }
 
     @Override
-    public ChangedTransactionDetail reprocessLoanTranactions(LocalDate 
disbursementDate, List<LoanTransaction> transactionsPostDisbursement,
-            MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> 
installments, Set<LoanCharge> charges) {
-        throw new NotImplementedException();
+    public ChangedTransactionDetail reprocessLoanTransactions(LocalDate 
disbursementDate,
+            List<LoanTransaction> transactionsPostDisbursement, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> charges) {
+
+        // TODO: rewrite this whole logic step by step
+        if (charges != null) {
+            for (final LoanCharge loanCharge : charges) {
+                if (!loanCharge.isDueAtDisbursement()) {
+                    loanCharge.resetPaidAmount(currency);
+                }
+            }
+        }
+
+        for (final LoanRepaymentScheduleInstallment currentInstallment : 
installments) {
+            currentInstallment.resetDerivedComponents();
+            currentInstallment.updateDerivedFields(currency, disbursementDate);
+        }
+
+        // TODO: Remove this reprocess and add the charges to the installment 
in chronological order
+        final LoanRepaymentScheduleProcessingWrapper wrapper = new 
LoanRepaymentScheduleProcessingWrapper();
+        wrapper.reprocess(currency, disbursementDate, installments, charges);
+        final ChangedTransactionDetail changedTransactionDetail = new 
ChangedTransactionDetail();
+        for (final LoanTransaction loanTransaction : 
transactionsPostDisbursement) {
+            if (loanTransaction.getId() == null) {
+                processLatestTransaction(loanTransaction, currency, 
installments, charges, null);
+                loanTransaction.adjustInterestComponent(currency);
+            } else {
+                /**
+                 * For existing transactions, check if the re-payment breakup 
(principal, interest, fees, penalties) has
+                 * changed.<br>
+                 **/
+                final LoanTransaction newLoanTransaction = 
LoanTransaction.copyTransactionProperties(loanTransaction);
+
+                // Reset derived component of new loan transaction and
+                // re-process transaction
+                processLatestTransaction(newLoanTransaction, currency, 
installments, charges, null);
+                newLoanTransaction.adjustInterestComponent(currency);
+                /**
+                 * Check if the transaction amounts have changed. If so, 
reverse the original transaction and update
+                 * changedTransactionDetail accordingly
+                 **/
+                if (LoanTransaction.transactionAmountsMatch(currency, 
loanTransaction, newLoanTransaction)) {
+                    
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(
+                            
newLoanTransaction.getLoanTransactionToRepaymentScheduleMappings());
+                } else {
+                    createNewTransaction(loanTransaction, newLoanTransaction, 
changedTransactionDetail);
+                }
+            }
+        }
+        reprocessInstallments(installments, currency);
+        return changedTransactionDetail;
     }
 
     @Override
     public void processLatestTransaction(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
             List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> charges, Money overpaidAmount) {
-        throw new NotImplementedException();
+        switch (loanTransaction.getTypeOf()) {
+            case WRITEOFF -> handleWriteOff(loanTransaction, currency, 
installments);
+            case REFUND_FOR_ACTIVE_LOAN -> handleRefund(loanTransaction, 
currency, installments, charges);
+            case CHARGEBACK -> handleChargeback(loanTransaction, currency, 
overpaidAmount, installments);
+
+            case REPAYMENT, MERCHANT_ISSUED_REFUND, PAYOUT_REFUND, 
GOODWILL_CREDIT, CHARGE_REFUND, CHARGE_ADJUSTMENT, DOWN_PAYMENT,
+                    WAIVE_INTEREST, RECOVERY_REPAYMENT ->
+                handleRepayment(loanTransaction, currency, installments, 
charges);
+            // TODO: Cover rest of the transaction types
+            default -> {
+                log.warn("Unhandled transaction processing for transaction 
type: {}", loanTransaction.getTypeOf());
+            }
+        }
     }
 
     @Override
     public Money handleRepaymentSchedule(List<LoanTransaction> 
transactionsPostDisbursement, MonetaryCurrency currency,
             List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> loanCharges) {
-        return super.handleRepaymentSchedule(transactionsPostDisbursement, 
currency, installments, loanCharges);
+        throw new NotImplementedException();
+    }
+
+    private void handleRepayment(LoanTransaction loanTransaction, 
MonetaryCurrency currency,
+            List<LoanRepaymentScheduleInstallment> installments, 
Set<LoanCharge> charges) {
+        if (loanTransaction.isRepaymentLikeType() || 
loanTransaction.isInterestWaiver() || loanTransaction.isRecoveryRepayment()) {
+            loanTransaction.resetDerivedComponents();
+        }
+        Money transactionAmountUnprocessed = 
loanTransaction.getAmount(currency);
+        Money zero = Money.zero(currency);
+        List<LoanTransactionToRepaymentScheduleMapping> transactionMappings = 
new ArrayList<>();
+
+        List<LoanPaymentAllocationRule> paymentAllocationRules = 
loanTransaction.getLoan().getPaymentAllocationRules();
+        LoanPaymentAllocationRule defaultPaymentAllocationRule = 
paymentAllocationRules.stream()
+                .filter(e -> 
PaymentAllocationTransactionType.DEFAULT.equals(e.getTransactionType())).findFirst().orElseThrow();
+        LoanPaymentAllocationRule paymentAllocationRule = 
paymentAllocationRules.stream()
+                .filter(e -> 
loanTransaction.getTypeOf().equals(e.getTransactionType().getLoanTransactionType())).findFirst()
+                .orElse(defaultPaymentAllocationRule);
+        Balances balances = new Balances(zero, zero, zero, zero);
+        for (PaymentAllocationType paymentAllocationType : 
paymentAllocationRule.getAllocationTypes()) {
+            FutureInstallmentAllocationRule futureInstallmentAllocationRule = 
paymentAllocationRule.getFutureInstallmentAllocationRule();
+            LoanRepaymentScheduleInstallment currentInstallment = null;

Review Comment:
   It must be defined. If it was not set, there shall be a validation error.



-- 
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