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


##########
fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanTransactionReadPlatformServiceImpl.java:
##########
@@ -78,52 +95,68 @@ public WorkingCapitalLoanCommandTemplateData 
retrieveLoanTransactionTemplate(fin
                     .build();
         } else if 
(WorkingCapitalLoanConstants.REPAYMENT_LOAN_COMMAND.equals(command)
                 || 
WorkingCapitalLoanConstants.GOODWILL_CREDIT_LOAN_COMMAND.equals(command)) {
-            return WorkingCapitalLoanCommandTemplateData.builder()
-                    .expectedAmount(wcLoan.getBalance() != null ? 
wcLoan.getBalance().getPrincipalOutstanding() : null)
-                    .currency(wcLoan.getLoanProduct().getCurrency().toData())
+            return template.expectedAmount(balance != null ? 
balance.getPrincipalOutstanding() : null)
                     
.paymentTypeOptions(paymentTypeReadPlatformService.retrieveAllPaymentTypes())
                     .classificationOptions(codeValueReadPlatformService
                             
.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.REPAYMENT_CLASSIFICATION_CODE_NAME))
                     .build();
         } else if 
(WorkingCapitalLoanConstants.CREDIT_BALANCE_REFUND_COMMAND.equals(command)) {
-            final BigDecimal overpaymentAmount = wcLoan.getBalance() != null ? 
wcLoan.getBalance().getOverpaymentAmount() : null;
-            return WorkingCapitalLoanCommandTemplateData.builder()
-                    .expectedAmount(overpaymentAmount != null ? 
overpaymentAmount : BigDecimal.ZERO)
-                    .currency(wcLoan.getLoanProduct().getCurrency().toData())
+            final BigDecimal overpaymentAmount = balance != null ? 
balance.getOverpaymentAmount() : null;
+            return template.expectedAmount(overpaymentAmount != null ? 
overpaymentAmount : BigDecimal.ZERO)
                     
.paymentTypeOptions(paymentTypeReadPlatformService.retrieveAllPaymentTypes())
                     .classificationOptions(codeValueReadPlatformService
                             
.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.CREDIT_BALANCE_REFUND_CLASSIFICATION_CODE_NAME))
                     .build();
-        } else if 
(WorkingCapitalLoanConstants.DISCOUNT_FEE_LOAN_COMMAND.equals(command)) {
-            return 
WorkingCapitalLoanCommandTemplateData.builder().currency(wcLoan.getLoanProduct().getCurrency().toData())
-                    .classificationOptions(codeValueReadPlatformService
-                            
.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.DISCOUNT_FEE_CLASSIFICATION_CODE_NAME))
-                    .build();
-        } else if 
(WorkingCapitalLoanConstants.DISCOUNT_FEE_ADJUSTMENT_LOAN_COMMAND.equals(command))
 {
-            return 
WorkingCapitalLoanCommandTemplateData.builder().currency(wcLoan.getLoanProduct().getCurrency().toData())
-                    .classificationOptions(codeValueReadPlatformService
-                            
.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.DISCOUNT_FEE_CLASSIFICATION_CODE_NAME))
-                    .build();
-        } else if 
(WorkingCapitalLoanConstants.CHARGE_OFF_LOAN_COMMAND.equals(command)) {
-            // Charge-off amount is the auto-calculated outstanding balance; 
the date defaults to the business date.
-            return WorkingCapitalLoanCommandTemplateData.builder()
-                    .chargeOffAmount(wcLoan.getBalance() != null ? 
wcLoan.getBalance().getTotalOutstanding() : BigDecimal.ZERO)
-                    
.chargeOffDate(DateUtils.getBusinessLocalDate()).currency(wcLoan.getLoanProduct().getCurrency().toData())
-                    .chargeOffReasonOptions(
-                            
codeValueReadPlatformService.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.CHARGE_OFF_REASONS))
-                    .build();
         } else if 
(WorkingCapitalLoanConstants.RECOVERY_PAYMENT_LOAN_COMMAND.equals(command)) {
             // The amount to pre-fill is what is still recoverable, NOT the 
gross amount written off: a recovery may
             // not exceed it, so offering the gross figure after a partial 
recovery would pre-fill a value the API
             // rejects. Term loan pre-fills the gross figure and has that 
problem.
-            return WorkingCapitalLoanCommandTemplateData.builder()
-                    .expectedAmount(wcLoan.getBalance() != null ? 
wcLoan.getBalance().getWrittenOffOutstanding() : BigDecimal.ZERO)
-                    .currency(wcLoan.getLoanProduct().getCurrency().toData())
+            return template.expectedAmount(balance != null ? 
balance.getWrittenOffOutstanding() : BigDecimal.ZERO)
                     
.paymentTypeOptions(paymentTypeReadPlatformService.retrieveAllPaymentTypes()).build();
+        } else if 
(WorkingCapitalLoanConstants.DISCOUNT_FEE_LOAN_COMMAND.equals(command)
+                || 
WorkingCapitalLoanConstants.DISCOUNT_FEE_ADJUSTMENT_LOAN_COMMAND.equals(command))
 {
+            return template.classificationOptions(codeValueReadPlatformService
+                    
.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.DISCOUNT_FEE_CLASSIFICATION_CODE_NAME)).build();
+        } else if 
(WorkingCapitalLoanConstants.CHARGE_OFF_LOAN_COMMAND.equals(command)) {
+            // Charge-off amount is the auto-calculated outstanding balance; 
the date defaults to the business date.
+            return template.chargeOffAmount(balance != null ? 
balance.getTotalOutstanding() : BigDecimal.ZERO)
+                    
.chargeOffDate(DateUtils.getBusinessLocalDate()).chargeOffReasonOptions(
+                            
codeValueReadPlatformService.retrieveCodeValuesByCode(WorkingCapitalLoanConstants.CHARGE_OFF_REASONS))
+                    .build();
+        } else if 
(WorkingCapitalLoanConstants.PREPAY_LOAN_COMMAND.equals(command)) {
+            return prePaymentTemplate(template, balance, transactionDate);
         }
         return null;
     }
 
+    /**
+     * The payoff quote is read straight off the current balance: a Working 
Capital loan accrues nothing over time - the
+     * whole discount is loaded into principal at disbursement and its 
amortization only moves income recognition - so
+     * the outstanding buckets move on explicit commands alone and the 
snapshot is already the payoff for
+     * {@code transactionDate}. The date is carried into the response so 
callers can echo back the date they quoted for.
+     * <p>
+     * It is typed as a plain Repayment because that is what the caller posts 
it back as, through the ordinary repayment
+     * command, with the repayment allocation and accounting treatment that 
comes with it.
+     */
+    private WorkingCapitalLoanTransactionTemplateData prePaymentTemplate(
+            final 
WorkingCapitalLoanTransactionTemplateData.WorkingCapitalLoanTransactionTemplateDataBuilder
 template,
+            final WorkingCapitalLoanBalance balance, final LocalDate 
transactionDate) {
+        // The balance row is created when the application is submitted, so 
every loan reached through the normal flow
+        // has one and the amounts below are real. Reading it defensively 
anyway reports a missing balance as absent
+        // amounts rather than as a payoff of zero.
+        final Optional<WorkingCapitalLoanBalance> present = 
Optional.ofNullable(balance);
+        return template.transactionDate(transactionDate != null ? 
transactionDate : DateUtils.getBusinessLocalDate())

Review Comment:
   Transaction date matters:
   In case there were any:
   - Disbursement
   - Added charge
   - Discount fee
   - Discount fee adjustment
   - etc.
   
   Those are excluded from the calculation, prepayment amount and balances 
cannot include any of the "future" transactions.



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