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 7bb4840d7ad2be93dded3ac145ff0386dbcc4328 Author: Soma Sörös <[email protected]> AuthorDate: Fri Jan 23 11:00:56 2026 +0100 FINERACT-2412: full term tranche - get loan API changes & add to LoanAccountDataV1 (events) --- .../src/main/avro/loan/v1/LoanAccountDataV1.avsc | 8 ++++++++ .../apache/fineract/test/messaging/event/EventCheckHelper.java | 3 +++ .../fineract/portfolio/loanaccount/data/LoanAccountData.java | 1 + .../domain/LoanRepaymentScheduleInstallmentRepository.java | 3 +++ .../portfolio/loanaccount/service/LoanReadPlatformService.java | 2 ++ .../serializer/loan/LoanBusinessEventSerializer.java | 4 ++++ .../fineract/portfolio/loanaccount/api/LoansApiResource.java | 2 ++ .../portfolio/loanaccount/api/LoansApiResourceSwagger.java | 2 ++ .../loanaccount/service/LoanReadPlatformServiceImpl.java | 5 +++++ .../loanaccount/service/LoanRepaymentScheduleService.java | 5 +++++ 10 files changed, 35 insertions(+) diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc b/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc index de0455b0f1..048dee0573 100644 --- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc +++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanAccountDataV1.avsc @@ -853,6 +853,14 @@ "items": "org.apache.fineract.avro.loan.v1.OriginatorDetailsV1" } ] + }, + { + "default": null, + "name": "actualNoTerm", + "type": [ + "null", + "int" + ] } ] } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java index 94449abdcd..a3c6762a2a 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/messaging/event/EventCheckHelper.java @@ -201,6 +201,8 @@ public class EventCheckHelper { BigDecimal delinquentFeeExpected = body.getDelinquent().getDelinquentFee(); BigDecimal delinquentPenaltyActual = loanAccountDataV1.getDelinquent().getDelinquentPenalty(); BigDecimal delinquentPenaltyExpected = body.getDelinquent().getDelinquentPenalty(); + Integer actualNoTermActual = loanAccountDataV1.getActualNoTerm(); + Integer actualNoTermExpected = body.getActualNoTerm(); assertThat(idActual).isEqualTo(idExpected); assertThat(statusIdActual).isEqualTo(statusIdExpected); @@ -217,6 +219,7 @@ public class EventCheckHelper { assertThat(areBigDecimalValuesEqual(delinquentInterestActual, delinquentInterestExpected)).isTrue(); assertThat(areBigDecimalValuesEqual(delinquentFeeActual, delinquentFeeExpected)).isTrue(); assertThat(areBigDecimalValuesEqual(delinquentPenaltyActual, delinquentPenaltyExpected)).isTrue(); + assertThat(actualNoTermActual).isEqualTo(actualNoTermExpected); return null; }); diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java index 7507129d8a..26d5a05361 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java @@ -104,6 +104,7 @@ public class LoanAccountData { private Integer termFrequency; private EnumOptionData termPeriodFrequencyType; private Integer numberOfRepayments; + private Integer actualNoTerm; private Integer repaymentEvery; private Integer fixedLength; private EnumOptionData repaymentFrequencyType; diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallmentRepository.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallmentRepository.java index c7c7af96e2..325fbb360a 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallmentRepository.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallmentRepository.java @@ -72,4 +72,7 @@ public interface LoanRepaymentScheduleInstallmentRepository """) List<LoanRepaymentScheduleInstallment> findByLoanId(@Param("loanId") Long loanId); + long countLoanRepaymentScheduleInstallmentsByLoan_IdAndAdditionalAndIsDownPayment(Long loanId, boolean additional, + boolean isDownPayment); + } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java index f8c5e0294d..f372b117b3 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformService.java @@ -168,4 +168,6 @@ public interface LoanReadPlatformService { LoanTransactionData retrieveLoanReAgeTemplate(Long loanId); LoanTransactionData retrieveLoanReAmortizationTemplate(Long loanId); + + Integer countInstallmentsByLoanIdWhereIsAdditionalFalseAndIsDownPaymentFalse(Long loanId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java index 792d60809a..52b1c0a977 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/serializer/loan/LoanBusinessEventSerializer.java @@ -102,6 +102,10 @@ public class LoanBusinessEventSerializer extends AbstractBusinessEventWithCustom data.setLoanTermVariations(activeLoanTermVariations.stream().map(LoanTermVariations::toData).toList()); } + Integer actualNoTerms = Math.toIntExact( + event.get().getRepaymentScheduleInstallments().stream().filter(i -> !i.isAdditional() && !i.isDownPayment()).count()); + data.setActualNoTerm(actualNoTerms); + final LoanAccountDataV1 result = mapper.map(data); result.getDelinquent().setInstallmentDelinquencyBuckets(installmentsDelinquencyData); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java index 306230d682..c7c3c0bdc8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResource.java @@ -1024,6 +1024,8 @@ public class LoansApiResource { loanBasicDetails = loanBasicDetails.setMeeting(calendarData); } } + loanBasicDetails.setActualNoTerm( + loanReadPlatformService.countInstallmentsByLoanIdWhereIsAdditionalFalseAndIsDownPaymentFalse(resolvedLoanId)); Collection<InterestRatePeriodData> interestRatesPeriods = this.loanReadPlatformService .retrieveLoanInterestRatePeriodData(loanBasicDetails); Collection<LoanTransactionData> loanRepayments = null; 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 1ef9b7ce9b..a2349178a5 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 @@ -1286,6 +1286,8 @@ final class LoansApiResourceSwagger { public StringEnumOptionData buyDownFeeStrategy; @Schema(example = "FEE") public StringEnumOptionData buyDownFeeIncomeType; + @Schema(example = "6") + public Integer actualNoTerm; } @Schema(description = "GetLoansResponse") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 46e86e88ad..711f1a8785 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -1796,6 +1796,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa .reAmortizationInterestHandlingOptions(LoanReAmortizationInterestHandlingType.getValuesAsEnumOptionDataList()).build(); } + @Override + public Integer countInstallmentsByLoanIdWhereIsAdditionalFalseAndIsDownPaymentFalse(Long loanId) { + return loanRepaymentScheduleService.countInstallmentsByLoanIdWhereIsAdditionalFalseAndIsDownPaymentFalse(loanId); + } + @Override public LoanTransactionData retrieveLoanChargeOffTemplate(final Long loanId) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanRepaymentScheduleService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanRepaymentScheduleService.java index 9943a626a7..7844b54e97 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanRepaymentScheduleService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanRepaymentScheduleService.java @@ -60,6 +60,11 @@ public class LoanRepaymentScheduleService { isInterestRecalculationEnabled, loanScheduleType); } + public Integer countInstallmentsByLoanIdWhereIsAdditionalFalseAndIsDownPaymentFalse(Long loanId) { + return Math.toIntExact(loanRepaymentScheduleInstallmentRepository + .countLoanRepaymentScheduleInstallmentsByLoan_IdAndAdditionalAndIsDownPayment(loanId, false, false)); + } + public LoanScheduleData extractLoanScheduleData(final List<LoanRepaymentScheduleInstallment> installments, final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData, Collection<DisbursementData> disbursementData, Collection<LoanTransactionRepaymentPeriodData> capitalizedIncomeData, boolean isInterestRecalculationEnabled,
