This is an automated email from the ASF dual-hosted git repository. adamsaghy pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 1b31d932ca143d239cdec84cc25af46ea8a1b812 Author: taskain7 <[email protected]> AuthorDate: Tue Sep 12 07:58:09 2023 +0200 [FINERACT-1958] Business events for down payment installments --- .../avro/loan/v1/LoanSchedulePeriodDataV1.avsc | 8 ++++ .../portfolio/loanaccount/domain/Loan.java | 45 ++++++++++------------ .../loanschedule/data/LoanSchedulePeriodData.java | 8 ++++ .../loanaccount/api/LoansApiResourceSwagger.java | 2 + .../domain/LoanAccountDomainServiceJpa.java | 6 +-- .../LoanWritePlatformServiceJpaRepositoryImpl.java | 11 +++++- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/LoanSchedulePeriodDataV1.avsc b/fineract-avro-schemas/src/main/avro/loan/v1/LoanSchedulePeriodDataV1.avsc index cb6b8492f..74967a6fe 100644 --- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanSchedulePeriodDataV1.avsc +++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanSchedulePeriodDataV1.avsc @@ -330,6 +330,14 @@ "null", "bigdecimal" ] + }, + { + "default": null, + "name": "downPaymentPeriod", + "type": [ + "null", + "boolean" + ] } ] } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 1e628634b..58f6d5143 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -2946,34 +2946,31 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom { } - public void handleDownPayment(final BigDecimal disbursedAmount, final JsonCommand command, + public LoanTransaction handleDownPayment(final BigDecimal disbursedAmount, final JsonCommand command, final ScheduleGeneratorDTO scheduleGeneratorDTO) { - if (isAutoRepaymentForDownPaymentEnabled()) { - LocalDate disbursedOn = command.localDateValueOfParameterNamed(ACTUAL_DISBURSEMENT_DATE); - BigDecimal disbursedAmountPercentageForDownPayment = this.loanRepaymentScheduleDetail - .getDisbursedAmountPercentageForDownPayment(); - ExternalId externalId = ExternalId.empty(); - if (TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) { - externalId = ExternalId.generate(); - } - Money downPaymentMoney = Money.of(getCurrency(), - MathUtil.percentageOf(disbursedAmount, disbursedAmountPercentageForDownPayment, 19)); - LoanTransaction downPaymentTransaction = LoanTransaction.downPayment(getOffice(), downPaymentMoney, null, disbursedOn, - externalId); - - LoanEvent event = LoanEvent.LOAN_REPAYMENT_OR_WAIVER; - validateRepaymentTypeAccountStatus(downPaymentTransaction, event); - HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO(); - validateRepaymentDateIsOnHoliday(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(), - holidayDetailDTO.getHolidays()); - validateRepaymentDateIsOnNonWorkingDay(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(), - holidayDetailDTO.isAllowTransactionsOnNonWorkingDay()); - - handleRepaymentOrRecoveryOrWaiverTransaction(downPaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO); + LocalDate disbursedOn = command.localDateValueOfParameterNamed(ACTUAL_DISBURSEMENT_DATE); + BigDecimal disbursedAmountPercentageForDownPayment = this.loanRepaymentScheduleDetail.getDisbursedAmountPercentageForDownPayment(); + ExternalId externalId = ExternalId.empty(); + if (TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) { + externalId = ExternalId.generate(); } + Money downPaymentMoney = Money.of(getCurrency(), + MathUtil.percentageOf(disbursedAmount, disbursedAmountPercentageForDownPayment, 19)); + LoanTransaction downPaymentTransaction = LoanTransaction.downPayment(getOffice(), downPaymentMoney, null, disbursedOn, externalId); + + LoanEvent event = LoanEvent.LOAN_REPAYMENT_OR_WAIVER; + validateRepaymentTypeAccountStatus(downPaymentTransaction, event); + HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO(); + validateRepaymentDateIsOnHoliday(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(), + holidayDetailDTO.getHolidays()); + validateRepaymentDateIsOnNonWorkingDay(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(), + holidayDetailDTO.isAllowTransactionsOnNonWorkingDay()); + + handleRepaymentOrRecoveryOrWaiverTransaction(downPaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO); + return downPaymentTransaction; } - private boolean isAutoRepaymentForDownPaymentEnabled() { + public boolean isAutoRepaymentForDownPaymentEnabled() { return this.loanRepaymentScheduleDetail.isEnableDownPayment() && this.loanRepaymentScheduleDetail.isEnableAutoRepaymentForDownPayment(); } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java index cbd789b02..1cc8c958b 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/data/LoanSchedulePeriodData.java @@ -72,6 +72,7 @@ public final class LoanSchedulePeriodData { private final BigDecimal totalActualCostOfLoanForPeriod; private final BigDecimal totalInstallmentAmountForPeriod; private final BigDecimal totalCredits; + private final Boolean downPaymentPeriod; public static LoanSchedulePeriodData disbursementOnlyPeriod(final LocalDate disbursementDate, final BigDecimal principalDisbursed, final BigDecimal feeChargesDueAtTimeOfDisbursement, final boolean isDisbursed) { @@ -205,6 +206,7 @@ public final class LoanSchedulePeriodData { this.totalOverdue = null; } this.totalCredits = BigDecimal.ZERO; + this.downPaymentPeriod = false; } /* @@ -268,9 +270,13 @@ public final class LoanSchedulePeriodData { this.totalOverdue = null; } this.totalCredits = BigDecimal.ZERO; + this.downPaymentPeriod = false; } // TODO refactor the class to builder pattern + /* + * used for down payment only period when creating an empty loan schedule for preview etc + */ private LoanSchedulePeriodData(Integer periodNumber, LocalDate fromDate, LocalDate dueDate, BigDecimal principalDue, BigDecimal principalOutstanding) { this.period = periodNumber; @@ -323,6 +329,7 @@ public final class LoanSchedulePeriodData { this.totalOverdue = null; } this.totalCredits = BigDecimal.ZERO; + this.downPaymentPeriod = true; } /* @@ -396,6 +403,7 @@ public final class LoanSchedulePeriodData { this.totalOverdue = null; } this.totalCredits = totalCredits; + this.downPaymentPeriod = false; } private BigDecimal defaultToZeroIfNull(final BigDecimal possibleNullValue) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java index f558eebbf..e71f4203e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java @@ -375,6 +375,8 @@ final class LoansApiResourceSwagger { public Double totalInstallmentAmountForPeriod; @Schema(example = "2.000000") public Double totalCredits; + @Schema(example = "true") + public Boolean downPaymentPeriod; } static final class GetLoansLoanIdDisbursementDetails { 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 604e5804f..ecfcd5f0f 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 @@ -53,8 +53,6 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanRefundPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanRefundPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionBusinessEvent; -import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPostBusinessEvent; -import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionDownPaymentPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionGoodwillCreditPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionGoodwillCreditPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionMakeRepaymentPostBusinessEvent; @@ -292,7 +290,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } else if (isRecoveryRepayment) { repaymentEvent = new LoanTransactionRecoveryPaymentPreBusinessEvent(loan); } else if (repaymentTransactionType.isDownPayment()) { - repaymentEvent = new LoanTransactionDownPaymentPreBusinessEvent(loan); + repaymentEvent = new LoanTransactionMakeRepaymentPreBusinessEvent(loan); } return repaymentEvent; } @@ -313,7 +311,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } else if (isRecoveryRepayment) { repaymentEvent = new LoanTransactionRecoveryPaymentPostBusinessEvent(transaction); } else if (repaymentTransactionType.isDownPayment()) { - repaymentEvent = new LoanTransactionDownPaymentPostBusinessEvent(transaction); + repaymentEvent = new LoanTransactionMakeRepaymentPostBusinessEvent(transaction); } return repaymentEvent; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 1e623bfbd..007cb31bd 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -82,6 +82,8 @@ import org.apache.fineract.infrastructure.event.business.domain.loan.transaction import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPostBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanChargeOffPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanDisbursalTransactionBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionMakeRepaymentPostBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanTransactionMakeRepaymentPreBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanUndoChargeOffBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanUndoWrittenOffBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.loan.transaction.LoanWaiveInterestBusinessEvent; @@ -456,7 +458,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null, downPaymentEnabled); } loan.adjustNetDisbursalAmount(amountToDisburse.getAmount()); - loan.handleDownPayment(amountToDisburse.getAmount(), command, scheduleGeneratorDTO); + if (loan.isAutoRepaymentForDownPaymentEnabled()) { + businessEventNotifierService.notifyPreBusinessEvent(new LoanTransactionMakeRepaymentPreBusinessEvent(loan)); + LoanTransaction downPaymentTransaction = loan.handleDownPayment(amountToDisburse.getAmount(), command, + scheduleGeneratorDTO); + businessEventNotifierService + .notifyPostBusinessEvent(new LoanTransactionMakeRepaymentPostBusinessEvent(downPaymentTransaction)); + businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); + } } if (!changes.isEmpty()) { if (changedTransactionDetail != null) {
