This is an automated email from the ASF dual-hosted git repository.
arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new ee72978a4 FINERACT-1840: Fee income is not realised if the loan got
fully repaid
ee72978a4 is described below
commit ee72978a49a89f641fb5b9322485f3e06c5d1523
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Feb 27 19:45:07 2023 +0100
FINERACT-1840: Fee income is not realised if the loan got fully repaid
---
.../portfolio/loanaccount/domain/Loan.java | 43 ++--------
.../domain/LoanAccountDomainService.java | 2 +
.../domain/LoanAccountDomainServiceJpa.java | 92 ++++++++++++++++++++++
.../portfolio/loanaccount/domain/LoanCharge.java | 2 +-
.../loanaccount/domain/LoanInstallmentCharge.java | 2 +-
.../LoanStatusChangePlatformServiceImpl.java | 9 ++-
...AccountDelinquencyRangeEventSerializerTest.java | 2 +-
.../ClientLoanIntegrationTest.java | 88 +++++++++++++++++++++
8 files changed, 195 insertions(+), 45 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index f65136457..eca63486e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -3506,43 +3506,6 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom {
updateLoanOutstandingBalances();
}
- public void applyIncomeAccrualTransaction(LocalDate closedDate) {
- ExternalId externalId = ExternalId.empty();
- boolean isExternalIdAutoGenerationEnabled =
TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled();
- if (isPeriodicAccrualAccountingEnabledOnLoanProduct()
- // to avoid collision with
processIncomeAccrualTransactionOnLoanClosure()
- // TODO: review after interest calculation implemented
- && !(this.loanInterestRecalculationDetails != null
- &&
this.loanInterestRecalculationDetails.isCompoundingToBePostedAsTransaction())) {
- List<LoanTransaction> updatedAccrualTransactions =
retrieveListOfAccrualTransactions();
- LocalDate lastAccruedDate = this.getDisbursementDate();
- if (!updatedAccrualTransactions.isEmpty()) {
- lastAccruedDate =
updatedAccrualTransactions.get(updatedAccrualTransactions.size() -
1).getTransactionDate();
- }
- HashMap<String, Object> feeDetails = new HashMap<>();
- determineFeeDetails(lastAccruedDate, closedDate, feeDetails);
- if (isExternalIdAutoGenerationEnabled) {
- externalId = ExternalId.generate();
- }
- BigDecimal fee = (BigDecimal) feeDetails.get(FEE);
- if (fee == null) {
- fee = BigDecimal.ZERO;
- }
- BigDecimal penalty = (BigDecimal) feeDetails.get(PENALTIES);
- if (penalty == null) {
- penalty = BigDecimal.ZERO;
- }
- BigDecimal total = fee.add(penalty);
- // TODO: calculate interest?
- if (total.compareTo(BigDecimal.ZERO) > 0) {
- LoanTransaction accrualTransaction =
LoanTransaction.accrueTransaction(this, this.getOffice(), closedDate, total,
null, fee,
- penalty, externalId);
- updateLoanChargesPaidBy(accrualTransaction, feeDetails, null);
- addLoanTransaction(accrualTransaction);
- }
- }
- }
-
private void determineCumulativeIncomeFromInstallments(HashMap<String,
BigDecimal> cumulativeIncomeFromInstallments) {
BigDecimal interest = BigDecimal.ZERO;
BigDecimal fee = BigDecimal.ZERO;
@@ -5484,7 +5447,7 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom {
for (LoanInstallmentCharge loanInstallmentCharge :
loanInstallmentCharges) {
Integer installmentNumber = null ==
loanInstallmentCharge.getInstallment() ? null
:
loanInstallmentCharge.getInstallment().getInstallmentNumber();
- final LoanChargePaidBy loanChargePaidBy = new
LoanChargePaidBy(accrual, loanInstallmentCharge.getLoancharge(),
+ final LoanChargePaidBy loanChargePaidBy = new
LoanChargePaidBy(accrual, loanInstallmentCharge.getLoanCharge(),
loanInstallmentCharge.getAmount(getCurrency()).getAmount(), installmentNumber);
accrual.getLoanChargesPaid().add(loanChargePaidBy);
}
@@ -7060,4 +7023,8 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom {
public LocalDate getChargedOffOnDate() {
return chargedOffOnDate;
}
+
+ public LoanInterestRecalculationDetails
getLoanInterestRecalculationDetails() {
+ return loanInterestRecalculationDetails;
+ }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
index e10c3a841..1eb1bb464 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainService.java
@@ -98,4 +98,6 @@ public interface LoanAccountDomainService {
LoanTransaction creditBalanceRefund(Loan loan, LocalDate transactionDate,
BigDecimal transactionAmount, String noteText,
ExternalId externalId, PaymentDetail paymentDetail);
+
+ void applyIncomeAccrualTransaction(Loan loan);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
index c402fc1a9..8351a8070 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
@@ -25,6 +25,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -61,6 +62,7 @@ import
org.apache.fineract.infrastructure.event.business.domain.loan.transaction
import
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionRecoveryPaymentPostBusinessEvent;
import
org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionRecoveryPaymentPreBusinessEvent;
import
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
+import org.apache.fineract.interoperation.util.MathUtil;
import org.apache.fineract.organisation.holiday.domain.Holiday;
import org.apache.fineract.organisation.holiday.domain.HolidayRepository;
import org.apache.fineract.organisation.holiday.domain.HolidayStatusType;
@@ -865,4 +867,94 @@ public class LoanAccountDomainServiceJpa implements
LoanAccountDomainService {
}
}
+ @Override
+ public void applyIncomeAccrualTransaction(Loan loan) {
+ if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()
+ // to avoid collision with
processIncomeAccrualTransactionOnLoanClosure()
+ && !(loan.getLoanInterestRecalculationDetails() != null
+ &&
loan.getLoanInterestRecalculationDetails().isCompoundingToBePostedAsTransaction()))
{
+
+ MonetaryCurrency currency = loan.getCurrency();
+ Money interestPortion = Money.zero(currency);
+ Money feePortion = Money.zero(currency);
+ Money penaltyPortion = Money.zero(currency);
+
+ for (LoanRepaymentScheduleInstallment
loanRepaymentScheduleInstallment : loan.getRepaymentScheduleInstallments()) {
+ interestPortion =
interestPortion.add(loanRepaymentScheduleInstallment.getInterestCharged(currency))
+
.minus(loanRepaymentScheduleInstallment.getInterestAccrued(currency))
+
.minus(loanRepaymentScheduleInstallment.getInterestWaived(currency));
+ feePortion =
feePortion.add(loanRepaymentScheduleInstallment.getFeeChargesCharged(currency))
+
.minus(loanRepaymentScheduleInstallment.getFeeAccrued(currency))
+
.minus(loanRepaymentScheduleInstallment.getFeeChargesWaived(currency));
+ penaltyPortion =
penaltyPortion.add(loanRepaymentScheduleInstallment.getPenaltyChargesCharged(currency))
+
.minus(loanRepaymentScheduleInstallment.getPenaltyAccrued(currency))
+
.minus(loanRepaymentScheduleInstallment.getPenaltyChargesWaived(currency));
+ }
+ Money total =
interestPortion.plus(feePortion).plus(penaltyPortion);
+
+ if (total.isGreaterThanZero()) {
+ ExternalId externalId = externalIdFactory.create();
+
+ LoanTransaction accrualTransaction =
LoanTransaction.accrueTransaction(loan, loan.getOffice(),
loan.getClosedOnDate(),
+ total.getAmount(), interestPortion.getAmount(),
feePortion.getAmount(), penaltyPortion.getAmount(), externalId);
+
+ Set<LoanChargePaidBy> accrualCharges =
accrualTransaction.getLoanChargesPaid();
+
+ Map<Long, Money> accrualDetails =
loan.getActiveCharges().stream()
+ .collect(Collectors.toMap(LoanCharge::getId, v ->
Money.zero(currency)));
+
+
loan.getLoanTransactions(LoanTransaction::isAccrual).forEach(transaction -> {
+ transaction.getLoanChargesPaid().forEach(loanChargePaid ->
{
+
accrualDetails.computeIfPresent(loanChargePaid.getLoanCharge().getId(),
+ (mappedKey, mappedValue) ->
mappedValue.add(Money.of(currency, loanChargePaid.getAmount())));
+ });
+ });
+
+ loan.getActiveCharges().forEach(loanCharge -> {
+ Money amount =
loanCharge.getAmount(currency).minus(loanCharge.getAmountWaived(currency));
+ if (!loanCharge.isInstalmentFee() && loanCharge.isActive()
+ &&
accrualDetails.get(loanCharge.getId()).isLessThan(amount)) {
+ Money amountToBeAccrued =
amount.minus(accrualDetails.get(loanCharge.getId()));
+ final LoanChargePaidBy loanChargePaidBy = new
LoanChargePaidBy(accrualTransaction, loanCharge,
+ amountToBeAccrued.getAmount(), null);
+ accrualCharges.add(loanChargePaidBy);
+ }
+ });
+
+ for (LoanRepaymentScheduleInstallment
loanRepaymentScheduleInstallment : loan.getRepaymentScheduleInstallments()) {
+ for (LoanInstallmentCharge installmentCharge :
loanRepaymentScheduleInstallment.getInstallmentCharges()) {
+ if (installmentCharge.getLoanCharge().isActive()) {
+ Money notWaivedAmount =
installmentCharge.getAmount(currency)
+
.minus(installmentCharge.getAmountWaived(currency));
+ if (notWaivedAmount.isGreaterThanZero()) {
+ Money amountToBeAccrued = notWaivedAmount
+
.minus(accrualDetails.get(installmentCharge.getLoanCharge().getId()));
+ if (amountToBeAccrued.isGreaterThanZero()) {
+ final LoanChargePaidBy loanChargePaidBy =
new LoanChargePaidBy(accrualTransaction,
+ installmentCharge.getLoanCharge(),
amountToBeAccrued.getAmount(),
+
installmentCharge.getInstallment().getInstallmentNumber());
+ accrualCharges.add(loanChargePaidBy);
+
accrualDetails.computeIfPresent(installmentCharge.getLoanCharge().getId(),
+ (mappedKey, mappedValue) ->
mappedValue.add(amountToBeAccrued));
+ }
+
accrualDetails.computeIfPresent(installmentCharge.getLoanCharge().getId(),
+ (mappedKey, mappedValue) -> MathUtil
+
.negativeToZero(mappedValue.minus(Money.of(currency,
installmentCharge.getAmount()))));
+ }
+ }
+ }
+ }
+
saveLoanTransactionWithDataIntegrityViolationChecks(accrualTransaction);
+ loan.addLoanTransaction(accrualTransaction);
+
+ loan.getRepaymentScheduleInstallments().forEach(installment ->
{
+ installment.updateAccrualPortion(
+
installment.getInterestCharged(currency).minus(installment.getInterestWaived(currency)),
+
installment.getFeeChargesCharged(currency).minus(installment.getFeeChargesWaived(currency)),
+
installment.getPenaltyChargesCharged(currency).minus(installment.getPenaltyChargesWaived(currency)));
+ });
+ }
+ }
+ }
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
index 3ab6dbb79..601c0bacd 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java
@@ -140,7 +140,7 @@ public class LoanCharge extends AbstractPersistableCustom {
private LoanTrancheDisbursementCharge loanTrancheDisbursementCharge;
@OneToMany(mappedBy = "loanCharge", cascade = CascadeType.ALL,
orphanRemoval = true, fetch = FetchType.EAGER)
- private Set<LoanChargePaidBy> loanChargePaidBySet;
+ private Set<LoanChargePaidBy> loanChargePaidBySet = new HashSet<>();
protected LoanCharge() {
//
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
index ca1190b6e..e40d98247 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java
@@ -312,7 +312,7 @@ public class LoanInstallmentCharge extends
AbstractPersistableCustom implements
return amountToDeductOnThisCharge;
}
- public LoanCharge getLoancharge() {
+ public LoanCharge getLoanCharge() {
return this.loancharge;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanStatusChangePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanStatusChangePlatformServiceImpl.java
index d34c98f8b..4f3dab667 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanStatusChangePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanStatusChangePlatformServiceImpl.java
@@ -25,6 +25,7 @@ import
org.apache.fineract.infrastructure.event.business.BusinessEventListener;
import
org.apache.fineract.infrastructure.event.business.domain.loan.LoanStatusChangedBusinessEvent;
import
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+import
org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainServiceJpa;
import org.springframework.stereotype.Service;
@Slf4j
@@ -33,22 +34,22 @@ import org.springframework.stereotype.Service;
public class LoanStatusChangePlatformServiceImpl implements
LoanStatusChangePlatformService {
private final BusinessEventNotifierService businessEventNotifierService;
+ private final LoanAccountDomainServiceJpa loanAccountDomainService;
@PostConstruct
public void addListeners() {
businessEventNotifierService.addPostBusinessEventListener(LoanStatusChangedBusinessEvent.class,
new LoanStatusChangedListener());
}
- private static class LoanStatusChangedListener implements
BusinessEventListener<LoanStatusChangedBusinessEvent> {
+ private class LoanStatusChangedListener implements
BusinessEventListener<LoanStatusChangedBusinessEvent> {
@Override
public void onBusinessEvent(LoanStatusChangedBusinessEvent event) {
final Loan loan = event.get();
log.debug("Loan Status change for loan {}", loan.getId());
- // Apply common actions on Loan account closed
- if (loan.isClosed()) {
+ if (loan.getStatus().isClosedObligationsMet()) {
log.debug("Loan Status {} for loan {}",
loan.getStatus().getCode(), loan.getId());
- loan.applyIncomeAccrualTransaction(loan.getClosedOnDate());
+ loanAccountDomainService.applyIncomeAccrualTransaction(loan);
}
if (loan.isOpen()) {
loan.handleMaturityDateActivate();
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java
index c92d22c4b..22995aaa7 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanAccountDelinquencyRangeEventSerializerTest.java
@@ -133,7 +133,7 @@ public class LoanAccountDelinquencyRangeEventSerializerTest
{
BigDecimal.valueOf(30), BigDecimal.valueOf(50),
BigDecimal.valueOf(185), new BigDecimal("100.5"), new BigDecimal("200.3")));
when(loanForProcessing.getRepaymentScheduleInstallments()).thenReturn(repaymentScheduleInstallments);
when(loanChargeReadPlatformService.retrieveLoanCharges(anyLong())).thenAnswer(a
-> repaymentScheduleInstallments.get(0)
- .getInstallmentCharges().stream().map(c ->
c.getLoancharge().toData()).collect(Collectors.toList()));
+ .getInstallmentCharges().stream().map(c ->
c.getLoanCharge().toData()).collect(Collectors.toList()));
moneyHelper.when(() ->
MoneyHelper.getRoundingMode()).thenReturn(RoundingMode.UP);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index 64cf20c4a..b410ca345 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -7669,6 +7669,94 @@ public class ClientLoanIntegrationTest {
}
}
+ @Test
+ public void accrualIsCalculatedWhenTheLoanIsClosed() {
+ try {
+
GlobalConfigurationHelper.updateIsAutomaticExternalIdGenerationEnabled(this.requestSpec,
this.responseSpec, true);
+
GlobalConfigurationHelper.updateIsBusinessDateEnabled(this.requestSpec,
this.responseSpec, true);
+ businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName())
+ .date("2022.10.10").dateFormat("yyyy.MM.dd").locale("en"));
+
+ final Account assetAccount =
this.accountHelper.createAssetAccount();
+ final Account incomeAccount =
this.accountHelper.createIncomeAccount();
+ final Account expenseAccount =
this.accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
this.accountHelper.createLiabilityAccount();
+
+ final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccountingNoInterest(assetAccount,
incomeAccount,
+ expenseAccount, overpaymentAccount);
+
+ final Integer clientID = ClientHelper.createClient(requestSpec,
responseSpec, "01 January 2011");
+ List<HashMap> charges = new ArrayList<>();
+ Integer installmentFee = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanInstallmentJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+ addCharges(charges, installmentFee, "10", null);
+
+ final Integer loanID = applyForLoanApplication(clientID,
loanProductID, charges);
+
+ HashMap<String, Object> loanStatusHashMap =
LoanStatusChecker.getStatusOfLoan(requestSpec, responseSpec, loanID);
+ LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap);
+
+ loanStatusHashMap = this.loanTransactionHelper.approveLoan("02
September 2022", loanID);
+ LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap);
+
LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap);
+
+ loanStatusHashMap =
this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount("03 September
2022", loanID, "1000");
+ LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
+
+ this.loanTransactionHelper.makeRepayment("04 September 2022",
Float.parseFloat("5"), loanID);
+
+
this.periodicAccrualAccountingHelper.runPeriodicAccrualAccounting("04 September
2022");
+
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"11", true));
+ LocalDate targetDate = LocalDate.of(2022, 9, 6);
+ final String penaltyCharge1AddedDate =
dateFormatter.format(targetDate);
+
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanID,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "11"));
+
+ this.loanTransactionHelper.waiveLoanCharge((long) loanID, (long)
penalty1LoanChargeId,
+ new PostLoansLoanIdChargesChargeIdRequest());
+
+ this.loanTransactionHelper.makeRepayment("08 September 2022",
Float.parseFloat("1010"), loanID);
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanID);
+
+ GetLoansLoanIdTransactions lastAccrualTransaction =
loanDetails.getTransactions().stream()
+ .filter(t ->
Boolean.TRUE.equals(t.getType().getAccrual())).findFirst().get();
+ assertEquals(15, lastAccrualTransaction.getAmount());
+ assertEquals(5, lastAccrualTransaction.getPenaltyChargesPortion());
+ assertEquals(10, lastAccrualTransaction.getFeeChargesPortion());
+
+ GetLoansLoanIdTransactionsTransactionIdResponse
accrualTransactionDetails = this.loanTransactionHelper
+ .getLoanTransactionDetails((long) loanID,
lastAccrualTransaction.getId());
+
+ assertEquals(2,
accrualTransactionDetails.getLoanChargePaidByList().size());
+
accrualTransactionDetails.getLoanChargePaidByList().forEach(loanCharge -> {
+ if (loanCharge.getChargeId().equals((long)
penalty1LoanChargeId)) {
+ assertEquals(5, loanCharge.getAmount());
+ } else {
+ assertEquals(10, loanCharge.getAmount());
+ }
+ });
+
+ } finally {
+
GlobalConfigurationHelper.updateIsAutomaticExternalIdGenerationEnabled(this.requestSpec,
this.responseSpec, false);
+
GlobalConfigurationHelper.updateIsBusinessDateEnabled(this.requestSpec,
this.responseSpec, false);
+ }
+ }
+
+ private Integer applyForLoanApplication(final Integer clientID, final
Integer loanProductID, final List<HashMap> charges) {
+ LOG.info("--------------------------------APPLYING FOR LOAN
APPLICATION--------------------------------");
+ final String loanApplicationJSON = new
LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")
+
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1")
+
.withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance()
+
.withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod()
+ .withCharges(charges).withExpectedDisbursementDate("03
September 2022").withSubmittedOnDate("01 September 2022")
+ .withLoanType("individual").build(clientID.toString(),
loanProductID.toString(), null);
+ return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
+ }
+
private Integer applyForLoanApplication(final Integer clientID, final
Integer loanProductID) {
LOG.info("--------------------------------APPLYING FOR LOAN
APPLICATION--------------------------------");
final String loanApplicationJSON = new
LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")