FINERACT-1968: Adv.paym.disbursement
This commit is contained in:
committed by
Arnold Gálovics
parent
2ea23be9a4
commit
5d62cfef04
+43
-3
@@ -49,10 +49,7 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationTransactionType;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
//TODO: remove `test` profile when it is finished
|
||||
@Profile("test")
|
||||
@Slf4j
|
||||
public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRepaymentScheduleTransactionProcessor {
|
||||
|
||||
@@ -182,6 +179,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
public void processLatestTransaction(LoanTransaction loanTransaction, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> installments, Set<LoanCharge> charges, Money overpaidAmount) {
|
||||
switch (loanTransaction.getTypeOf()) {
|
||||
case DISBURSEMENT -> handleDisbursement(loanTransaction, currency, installments);
|
||||
case WRITEOFF -> handleWriteOff(loanTransaction, currency, installments);
|
||||
case REFUND_FOR_ACTIVE_LOAN -> handleRefund(loanTransaction, currency, installments, charges);
|
||||
case CHARGEBACK -> handleChargeback(loanTransaction, currency, overpaidAmount, installments);
|
||||
@@ -197,6 +195,48 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDisbursement(LoanTransaction loanTransaction, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> installments) {
|
||||
updateLoanSchedule(loanTransaction, currency, installments);
|
||||
}
|
||||
|
||||
private void updateLoanSchedule(LoanTransaction disbursementTransaction, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> installments) {
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments = installments.stream()
|
||||
.filter(i -> !i.getDueDate().isBefore(disbursementTransaction.getTransactionDate()) && !i.isDownPayment()).toList();
|
||||
int noCandidateRepaymentInstallments = candidateRepaymentInstallments.size();
|
||||
LoanProductRelatedDetail loanProductRelatedDetail = disbursementTransaction.getLoan().getLoanRepaymentScheduleDetail();
|
||||
Integer installmentAmountInMultiplesOf = disbursementTransaction.getLoan().getLoanProduct().getInstallmentAmountInMultiplesOf();
|
||||
Money downPaymentAmount = Money.zero(currency);
|
||||
if (loanProductRelatedDetail.isEnableDownPayment()) {
|
||||
LoanRepaymentScheduleInstallment downPaymentInstallment = installments.stream()
|
||||
.filter(i -> i.isDownPayment() && i.getPrincipal(currency).isZero()).findFirst().orElseThrow();
|
||||
BigDecimal downPaymentAmt = MathUtil.percentageOf(disbursementTransaction.getAmount(),
|
||||
loanProductRelatedDetail.getDisbursedAmountPercentageForDownPayment(), mc);
|
||||
if (installmentAmountInMultiplesOf != null) {
|
||||
downPaymentAmt = Money.roundToMultiplesOf(downPaymentAmt, installmentAmountInMultiplesOf);
|
||||
}
|
||||
downPaymentAmount = Money.of(currency, downPaymentAmt);
|
||||
downPaymentInstallment.addToPrincipal(disbursementTransaction.getTransactionDate(), downPaymentAmount);
|
||||
|
||||
}
|
||||
Money amortizableAmount = disbursementTransaction.getAmount(currency).minus(downPaymentAmount);
|
||||
Money increasePrincipalBy = amortizableAmount.dividedBy(noCandidateRepaymentInstallments, mc.getRoundingMode());
|
||||
if (installmentAmountInMultiplesOf != null) {
|
||||
increasePrincipalBy = Money.roundToMultiplesOf(increasePrincipalBy, installmentAmountInMultiplesOf);
|
||||
}
|
||||
Money remainingAmount = increasePrincipalBy.multiplyRetainScale(noCandidateRepaymentInstallments, mc.getRoundingMode())
|
||||
.minus(amortizableAmount);
|
||||
|
||||
Money finalIncreasePrincipalBy = increasePrincipalBy;
|
||||
candidateRepaymentInstallments
|
||||
.forEach(i -> i.addToPrincipal(disbursementTransaction.getTransactionDate(), finalIncreasePrincipalBy));
|
||||
// Hence the rounding, we might need to amend the last installment amount
|
||||
candidateRepaymentInstallments.get(noCandidateRepaymentInstallments - 1)
|
||||
.addToPrincipal(disbursementTransaction.getTransactionDate(), remainingAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Money handleRepaymentSchedule(List<LoanTransaction> transactionsPostDisbursement, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> installments, Set<LoanCharge> loanCharges) {
|
||||
|
||||
+18
@@ -1,3 +1,21 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
+18
@@ -1,3 +1,21 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.loanschedule.domain;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
+2
-3
@@ -31,7 +31,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.imp
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.InterestPrincipalPenaltyFeesOrderLoanRepaymentScheduleTransactionProcessor;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.PrincipalInterestPenaltyFeesOrderLoanRepaymentScheduleTransactionProcessor;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.RBILoanRepaymentScheduleTransactionProcessor;
|
||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
@@ -104,8 +103,8 @@ public class LoanAccountAutoStarter {
|
||||
|
||||
@Bean
|
||||
@Conditional(AdvancedPaymentScheduleTransactionProcessorCondition.class)
|
||||
public AdvancedPaymentScheduleTransactionProcessor advancedPaymentScheduleTransactionProcessor(LoanUtilService loanUtilService) {
|
||||
return new AdvancedPaymentScheduleTransactionProcessor(loanUtilService);
|
||||
public AdvancedPaymentScheduleTransactionProcessor advancedPaymentScheduleTransactionProcessor() {
|
||||
return new AdvancedPaymentScheduleTransactionProcessor();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user