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
The following commit(s) were added to refs/heads/develop by this push:
new bef659503 FINERACT-1992 Emit
LoanAccountDelinquencyPauseChangedBusinessEvent
bef659503 is described below
commit bef65950322d630922041c2fb6590dcf42206b96
Author: Peter Bagrij <[email protected]>
AuthorDate: Tue Nov 21 18:26:22 2023 +0100
FINERACT-1992 Emit LoanAccountDelinquencyPauseChangedBusinessEvent
---
.../src/main/avro/loan/v1/CollectionDataV1.avsc | 11 ++++
.../avro/loan/v1/DelinquencyPausePeriodV1.avsc | 31 ++++++++++
...ccountDelinquencyPauseChangedBusinessEvent.java | 35 +++++++++++
.../tenant/module/loan/module-changelog-master.xml | 1 +
...oan_account_delinquency_pause_changed_event.xml | 33 +++++++++++
.../mapper/loan/LoanAccountDataMapper.java | 3 +-
....java => LoanDelinquencyPausePeriodMapper.java} | 19 ++----
.../DelinquencyReadPlatformServiceImpl.java | 27 ++++-----
.../DelinquencyWritePlatformServiceImpl.java | 5 +-
.../loanaccount/api/LoansApiResourceSwagger.java | 19 ++++--
.../portfolio/loanaccount/data/CollectionData.java | 6 +-
...ectionData.java => DelinquencyPausePeriod.java} | 33 ++---------
...nalEventConfigurationValidationServiceTest.java | 6 +-
.../DelinquencyReadPlatformServiceImplTest.java | 69 ++++++++++++++--------
...cyWritePlatformServiceRangeChangeEventTest.java | 10 ++--
.../DelinquencyActionIntegrationTests.java | 32 +++++++---
.../common/ExternalEventConfigurationHelper.java | 5 ++
17 files changed, 237 insertions(+), 108 deletions(-)
diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/CollectionDataV1.avsc
b/fineract-avro-schemas/src/main/avro/loan/v1/CollectionDataV1.avsc
index e424e78e5..36256d227 100644
--- a/fineract-avro-schemas/src/main/avro/loan/v1/CollectionDataV1.avsc
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/CollectionDataV1.avsc
@@ -82,6 +82,17 @@
"null",
"bigdecimal"
]
+ },
+ {
+ "default": null,
+ "name": "delinquencyPausePeriods",
+ "type": [
+ "null",
+ {
+ "type": "array",
+ "items":
"org.apache.fineract.avro.loan.v1.DelinquencyPausePeriodV1"
+ }
+ ]
}
]
}
diff --git
a/fineract-avro-schemas/src/main/avro/loan/v1/DelinquencyPausePeriodV1.avsc
b/fineract-avro-schemas/src/main/avro/loan/v1/DelinquencyPausePeriodV1.avsc
new file mode 100644
index 000000000..8d5d33434
--- /dev/null
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/DelinquencyPausePeriodV1.avsc
@@ -0,0 +1,31 @@
+{
+ "name": "DelinquencyPausePeriodV1",
+ "namespace": "org.apache.fineract.avro.loan.v1",
+ "type": "record",
+ "fields": [
+ {
+ "default": null,
+ "name": "active",
+ "type": [
+ "null",
+ "boolean"
+ ]
+ },
+ {
+ "default": null,
+ "name": "pausePeriodStart",
+ "type": [
+ "null",
+ "string"
+ ]
+ },
+ {
+ "default": null,
+ "name": "pausePeriodEnd",
+ "type": [
+ "null",
+ "string"
+ ]
+ }
+ ]
+}
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/LoanAccountDelinquencyPauseChangedBusinessEvent.java
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/LoanAccountDelinquencyPauseChangedBusinessEvent.java
new file mode 100644
index 000000000..5b3419d53
--- /dev/null
+++
b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/loan/LoanAccountDelinquencyPauseChangedBusinessEvent.java
@@ -0,0 +1,35 @@
+/**
+ * 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.infrastructure.event.business.domain.loan;
+
+import org.apache.fineract.portfolio.loanaccount.domain.Loan;
+
+public class LoanAccountDelinquencyPauseChangedBusinessEvent extends
LoanBusinessEvent {
+
+ private static final String TYPE =
"LoanAccountDelinquencyPauseChangedBusinessEvent";
+
+ public LoanAccountDelinquencyPauseChangedBusinessEvent(Loan value) {
+ super(value);
+ }
+
+ @Override
+ public String getType() {
+ return TYPE;
+ }
+}
diff --git
a/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/module-changelog-master.xml
b/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/module-changelog-master.xml
index 25da71bb5..b08ead78b 100644
---
a/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/module-changelog-master.xml
+++
b/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/module-changelog-master.xml
@@ -35,4 +35,5 @@
<include relativeToChangelogFile="true"
file="parts/1010_introduce_loan_schedule_type_configuration.xml"/>
<include relativeToChangelogFile="true"
file="parts/1011_add_delinquency_actions_table.xml"/>
<include relativeToChangelogFile="true"
file="parts/1012_introduce_loan_schedule_processing_type_configuration.xml"/>
+ <include relativeToChangelogFile="true"
file="parts/1013_add_loan_account_delinquency_pause_changed_event.xml"/>
</databaseChangeLog>
diff --git
a/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/parts/1013_add_loan_account_delinquency_pause_changed_event.xml
b/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/parts/1013_add_loan_account_delinquency_pause_changed_event.xml
new file mode 100644
index 000000000..03851e4ff
--- /dev/null
+++
b/fineract-loan/src/main/resources/db/changelog/tenant/module/loan/parts/1013_add_loan_account_delinquency_pause_changed_event.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+
+ <changeSet author="fineract" id="1">
+ <insert tableName="m_external_event_configuration">
+ <column name="type"
value="LoanAccountDelinquencyPauseChangedBusinessEvent"/>
+ <column name="enabled" valueBoolean="false"/>
+ </insert>
+ </changeSet>
+
+</databaseChangeLog>
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
index 0db349fc8..03b144614 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
@@ -24,7 +24,8 @@ import
org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
-@Mapper(config = AvroMapperConfig.class, uses = {
LoanTransactionDataMapper.class, LoanChargeDataMapper.class })
+@Mapper(config = AvroMapperConfig.class, uses = {
LoanTransactionDataMapper.class, LoanChargeDataMapper.class,
+ LoanDelinquencyPausePeriodMapper.class })
public interface LoanAccountDataMapper {
// TODO: avoid prefix "is" in class attributes; I would recommend to fix
this also in the Avro structures
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanDelinquencyPausePeriodMapper.java
similarity index 51%
copy from
fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
copy to
fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanDelinquencyPausePeriodMapper.java
index 0db349fc8..c4b99d34e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanAccountDataMapper.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanDelinquencyPausePeriodMapper.java
@@ -18,23 +18,14 @@
*/
package
org.apache.fineract.infrastructure.event.external.service.serialization.mapper.loan;
-import org.apache.fineract.avro.loan.v1.LoanAccountDataV1;
+import org.apache.fineract.avro.loan.v1.DelinquencyPausePeriodV1;
import
org.apache.fineract.infrastructure.event.external.service.serialization.mapper.support.AvroMapperConfig;
-import org.apache.fineract.portfolio.loanaccount.data.LoanAccountData;
+import org.apache.fineract.portfolio.loanaccount.data.DelinquencyPausePeriod;
import org.mapstruct.Mapper;
-import org.mapstruct.Mapping;
-@Mapper(config = AvroMapperConfig.class, uses = {
LoanTransactionDataMapper.class, LoanChargeDataMapper.class })
-public interface LoanAccountDataMapper {
+@Mapper(config = AvroMapperConfig.class)
+public interface LoanDelinquencyPausePeriodMapper {
- // TODO: avoid prefix "is" in class attributes; I would recommend to fix
this also in the Avro structures
- @Mapping(source = "loanProductLinkedToFloatingRate", target =
"isLoanProductLinkedToFloatingRate")
- @Mapping(source = "floatingInterestRate", target =
"isFloatingInterestRate")
- @Mapping(source = "topup", target = "isTopup")
- @Mapping(source = "interestRecalculationEnabled", target =
"isInterestRecalculationEnabled")
- @Mapping(target = "externalOwnerId", ignore = true)
- @Mapping(target = "settlementDate", ignore = true)
- @Mapping(target = "purchasePriceRatio", ignore = true)
- LoanAccountDataV1 map(LoanAccountData source);
+ DelinquencyPausePeriodV1 map(DelinquencyPausePeriod source);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImpl.java
index bfbe2b480..d0192d168 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImpl.java
@@ -30,7 +30,6 @@ import java.util.Optional;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
-import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
import org.apache.fineract.portfolio.delinquency.data.DelinquencyBucketData;
@@ -52,6 +51,7 @@ import
org.apache.fineract.portfolio.delinquency.mapper.DelinquencyRangeMapper;
import
org.apache.fineract.portfolio.delinquency.mapper.LoanDelinquencyTagMapper;
import
org.apache.fineract.portfolio.delinquency.validator.LoanDelinquencyActionData;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
+import org.apache.fineract.portfolio.loanaccount.data.DelinquencyPausePeriod;
import
org.apache.fineract.portfolio.loanaccount.data.InstallmentLevelDelinquency;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
@@ -205,23 +205,20 @@ public class DelinquencyReadPlatformServiceImpl
implements DelinquencyReadPlatfo
effective.add(loanDelinquencyActionData);
}
- // order them by start date, filter out the future items
- Optional<LoanDelinquencyActionData> last = effective.stream()
-
.sorted(Comparator.comparing(LoanDelinquencyActionData::getStartDate))
- .filter(e -> !DateUtils.isAfter(e.getStartDate(),
businessDate)) // keep only the present and the
-
// past ones
- .reduce((first, second) -> second);
-
- // enrich collectionData
- last.ifPresent(action -> {
- collectionData
-
.setDelinquencyCalculationPaused(!action.startDate.isAfter(businessDate) &&
!businessDate.isAfter(action.endDate));
-
collectionData.setDelinquencyPausePeriodStartDate(action.getStartDate());
-
collectionData.setDelinquencyPausePeriodEndDate(action.getEndDate());
- });
+ // order them by start date, and convert to DelinquencyPausePeriod
objects
+ List<DelinquencyPausePeriod> result = effective.stream() //
+
.sorted(Comparator.comparing(LoanDelinquencyActionData::getStartDate)) //
+ .map(lda -> toDelinquencyPausePeriod(businessDate,
lda)).toList(); //
+ collectionData.setDelinquencyPausePeriods(result);
}
}
+ @NotNull
+ private static DelinquencyPausePeriod toDelinquencyPausePeriod(LocalDate
businessDate, LoanDelinquencyActionData lda) {
+ return new
DelinquencyPausePeriod(!lda.getStartDate().isAfter(businessDate) &&
!businessDate.isAfter(lda.getEndDate()),
+ lda.getStartDate(), lda.getEndDate());
+ }
+
private Optional<LoanDelinquencyAction>
findMatchingResume(LoanDelinquencyAction pause, List<LoanDelinquencyAction>
resumes) {
if (resumes != null && resumes.size() > 0) {
for (LoanDelinquencyAction resume : resumes) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyWritePlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyWritePlatformServiceImpl.java
index f31ee95da..75bcf3f7d 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyWritePlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyWritePlatformServiceImpl.java
@@ -33,6 +33,7 @@ import
org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import
org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import
org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
+import
org.apache.fineract.infrastructure.event.business.domain.loan.LoanAccountDelinquencyPauseChangedBusinessEvent;
import
org.apache.fineract.infrastructure.event.business.domain.loan.LoanDelinquencyRangeChangeBusinessEvent;
import
org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
import org.apache.fineract.portfolio.delinquency.api.DelinquencyApiConstants;
@@ -62,6 +63,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import
org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRepository;
+import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
@Slf4j
@@ -205,6 +207,7 @@ public class DelinquencyWritePlatformServiceImpl implements
DelinquencyWritePlat
}
@Override
+ @Transactional
public CommandProcessingResult createDelinquencyAction(Long loanId,
JsonCommand command) {
final Loan loan =
this.loanRepository.findOneWithNotFoundDetection(loanId);
final LocalDate businessDate = DateUtils.getBusinessLocalDate();
@@ -216,7 +219,7 @@ public class DelinquencyWritePlatformServiceImpl implements
DelinquencyWritePlat
parsedDelinquencyAction.setLoan(loan);
LoanDelinquencyAction saved =
loanDelinquencyActionRepository.saveAndFlush(parsedDelinquencyAction);
-
+ businessEventNotifierService.notifyPostBusinessEvent(new
LoanAccountDelinquencyPauseChangedBusinessEvent(loan));
return new
CommandProcessingResultBuilder().withCommandId(command.commandId()) //
.withEntityId(saved.getId()) //
.withOfficeId(loan.getOfficeId()) //
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 0f86f1544..a06bcb780 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
@@ -990,17 +990,24 @@ final class LoansApiResourceSwagger {
@Schema(example = "100.000000")
public Double lastRepaymentAmount;
+ @Schema(description = "List of
GetLoansLoanIdDelinquencyPausePeriod")
+ public List<GetLoansLoanIdDelinquencyPausePeriod>
delinquencyPausePeriods;
+
+ @Schema(description = "List of
GetLoansLoanIdLoanInstallmentLevelDelinquency")
+ public List<GetLoansLoanIdLoanInstallmentLevelDelinquency>
installmentLevelDelinquency;
+
+ }
+
+ static final class GetLoansLoanIdDelinquencyPausePeriod {
+
@Schema(example = "true")
- public Boolean delinquencyCalculationPaused;
+ public Boolean active;
@Schema(example = "[2022, 07, 05]")
- public LocalDate delinquencyPausePeriodStartDate;
+ public LocalDate pausePeriodStart;
@Schema(example = "[2022, 07, 10]")
- public LocalDate delinquencyPausePeriodEndDate;
-
- @Schema(description = "List of
GetLoansLoanIdLoanInstallmentLevelDelinquency")
- public List<GetLoansLoanIdLoanInstallmentLevelDelinquency>
installmentLevelDelinquency;
+ public LocalDate pausePeriodEnd;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
index 1b51d221c..f872d6d27 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
@@ -44,14 +44,12 @@ public final class CollectionData {
private LocalDate lastRepaymentDate;
private BigDecimal lastRepaymentAmount;
- public boolean delinquencyCalculationPaused;
- public LocalDate delinquencyPausePeriodStartDate;
- public LocalDate delinquencyPausePeriodEndDate;
+ public Collection<DelinquencyPausePeriod> delinquencyPausePeriods;
public Collection<InstallmentLevelDelinquency> installmentLevelDelinquency;
public static CollectionData template() {
final BigDecimal zero = BigDecimal.ZERO;
- return new CollectionData(zero, 0L, null, 0L, null, zero, null, zero,
null, zero, false, null, null, null);
+ return new CollectionData(zero, 0L, null, 0L, null, zero, null, zero,
null, zero, null, null);
}
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DelinquencyPausePeriod.java
similarity index 50%
copy from
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
copy to
fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DelinquencyPausePeriod.java
index 1b51d221c..0aef796b7 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/CollectionData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DelinquencyPausePeriod.java
@@ -18,40 +18,19 @@
*/
package org.apache.fineract.portfolio.loanaccount.data;
-import java.math.BigDecimal;
import java.time.LocalDate;
-import java.util.Collection;
import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
import lombok.Getter;
-import lombok.Setter;
import lombok.ToString;
@AllArgsConstructor
@ToString
@Getter
-@Setter
-public final class CollectionData {
-
- private BigDecimal availableDisbursementAmount;
- private Long pastDueDays;
- private LocalDate nextPaymentDueDate;
- private Long delinquentDays;
- private LocalDate delinquentDate;
- private BigDecimal delinquentAmount;
- private LocalDate lastPaymentDate;
- private BigDecimal lastPaymentAmount;
-
- private LocalDate lastRepaymentDate;
- private BigDecimal lastRepaymentAmount;
-
- public boolean delinquencyCalculationPaused;
- public LocalDate delinquencyPausePeriodStartDate;
- public LocalDate delinquencyPausePeriodEndDate;
- public Collection<InstallmentLevelDelinquency> installmentLevelDelinquency;
-
- public static CollectionData template() {
- final BigDecimal zero = BigDecimal.ZERO;
- return new CollectionData(zero, 0L, null, 0L, null, zero, null, zero,
null, zero, false, null, null, null);
- }
+@EqualsAndHashCode
+public class DelinquencyPausePeriod {
+ private boolean active;
+ private LocalDate pausePeriodStart;
+ private LocalDate pausePeriodEnd;
}
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
index 7c6c443dc..ca46595cf 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java
@@ -97,7 +97,8 @@ public class ExternalEventConfigurationValidationServiceTest {
"LoanAccountsStayedLockedBusinessEvent", "MockBusinessEvent",
"LoanChargeOffPreBusinessEvent",
"LoanChargeOffPostBusinessEvent",
"LoanUndoChargeOffBusinessEvent", "LoanAccrualTransactionCreatedBusinessEvent",
"LoanRescheduledDueAdjustScheduleBusinessEvent",
"LoanOwnershipTransferBusinessEvent", "LoanAccountSnapshotBusinessEvent",
- "LoanTransactionDownPaymentPostBusinessEvent",
"LoanTransactionDownPaymentPreBusinessEvent");
+ "LoanTransactionDownPaymentPostBusinessEvent",
"LoanTransactionDownPaymentPreBusinessEvent",
+ "LoanAccountDelinquencyPauseChangedBusinessEvent");
List<FineractPlatformTenant> tenants = Arrays
.asList(new FineractPlatformTenant(1L, "default", "Default
Tenant", "Europe/Budapest", null));
@@ -176,7 +177,8 @@ public class
ExternalEventConfigurationValidationServiceTest {
"LoanAccountsStayedLockedBusinessEvent",
"LoanChargeOffPreBusinessEvent", "LoanChargeOffPostBusinessEvent",
"LoanUndoChargeOffBusinessEvent",
"LoanAccrualTransactionCreatedBusinessEvent",
"LoanRescheduledDueAdjustScheduleBusinessEvent",
"LoanOwnershipTransferBusinessEvent", "LoanAccountSnapshotBusinessEvent",
- "LoanTransactionDownPaymentPostBusinessEvent",
"LoanTransactionDownPaymentPreBusinessEvent");
+ "LoanTransactionDownPaymentPostBusinessEvent",
"LoanTransactionDownPaymentPreBusinessEvent",
+ "LoanAccountDelinquencyPauseChangedBusinessEvent");
List<FineractPlatformTenant> tenants = Arrays
.asList(new FineractPlatformTenant(1L, "default", "Default
Tenant", "Europe/Budapest", null));
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImplTest.java
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImplTest.java
index 544ec9498..ea6a186df 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImplTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/delinquency/service/DelinquencyReadPlatformServiceImplTest.java
@@ -23,6 +23,7 @@ import static
org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction
import static
org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.RESUME;
import java.time.LocalDate;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import
org.apache.fineract.portfolio.delinquency.domain.DelinquencyBucketRepository;
@@ -35,6 +36,7 @@ import
org.apache.fineract.portfolio.delinquency.mapper.DelinquencyBucketMapper;
import org.apache.fineract.portfolio.delinquency.mapper.DelinquencyRangeMapper;
import
org.apache.fineract.portfolio.delinquency.mapper.LoanDelinquencyTagMapper;
import org.apache.fineract.portfolio.loanaccount.data.CollectionData;
+import org.apache.fineract.portfolio.loanaccount.data.DelinquencyPausePeriod;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -85,10 +87,7 @@ class DelinquencyReadPlatformServiceImplTest {
// when
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 12));
- // then
-
Assertions.assertFalse(collectionData.isDelinquencyCalculationPaused());
-
Assertions.assertNull(collectionData.getDelinquencyPausePeriodStartDate());
-
Assertions.assertNull(collectionData.getDelinquencyPausePeriodEndDate());
+ Assertions.assertNull(collectionData.getDelinquencyPausePeriods());
}
@Test
@@ -104,9 +103,11 @@ class DelinquencyReadPlatformServiceImplTest {
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 12));
// then
- Assertions.assertTrue(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 12),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 13),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(false, "2023-01-10", "2023-01-11"), //
+ pausePeriod(true, "2023-01-12", "2023-01-13"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
}
@Test
@@ -121,10 +122,11 @@ class DelinquencyReadPlatformServiceImplTest {
// when
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 13));
- // then
- Assertions.assertTrue(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 12),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 13),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(false, "2023-01-10", "2023-01-11"), //
+ pausePeriod(true, "2023-01-12", "2023-01-13"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
}
@Test
@@ -139,10 +141,11 @@ class DelinquencyReadPlatformServiceImplTest {
// when
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 13));
- // then
- Assertions.assertTrue(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 12),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 14),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(false, "2023-01-10", "2023-01-11"), //
+ pausePeriod(true, "2023-01-12", "2023-01-14"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
}
@Test
@@ -158,9 +161,11 @@ class DelinquencyReadPlatformServiceImplTest {
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 12));
// then
-
Assertions.assertFalse(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 10),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 11),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(false, "2023-01-10", "2023-01-11"), //
+ pausePeriod(false, "2023-01-13", "2023-01-14"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
}
@Test
@@ -177,9 +182,11 @@ class DelinquencyReadPlatformServiceImplTest {
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 12));
// then
-
Assertions.assertFalse(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 10),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 11),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(false, "2023-01-10", "2023-01-11"), //
+ pausePeriod(false, "2023-01-13", "2023-01-14"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
}
@Test
@@ -196,9 +203,23 @@ class DelinquencyReadPlatformServiceImplTest {
underTest.enrichWithDelinquencyPausePeriodInfo(collectionData,
delinquencyActions, LocalDate.of(2023, JANUARY, 11));
// then
- Assertions.assertTrue(collectionData.isDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 10),
collectionData.getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.of(2023, JANUARY, 11),
collectionData.getDelinquencyPausePeriodEndDate());
+ verifyPausePeriods(collectionData, //
+ pausePeriod(true, "2023-01-10", "2023-01-11"), //
+ pausePeriod(false, "2023-01-13", "2023-01-14"), //
+ pausePeriod(false, "2023-01-15", "2023-01-20") //
+ );
+ }
+
+ private void verifyPausePeriods(CollectionData collectionData,
DelinquencyPausePeriod... pausePeriods) {
+ if (pausePeriods.length > 0) {
+ Assertions.assertEquals(Arrays.asList(pausePeriods),
collectionData.getDelinquencyPausePeriods());
+ } else {
+ Assertions.assertNull(collectionData.getDelinquencyPausePeriods());
+ }
+ }
+
+ private DelinquencyPausePeriod pausePeriod(boolean active, String
startDate, String endDate) {
+ return new DelinquencyPausePeriod(active, LocalDate.parse(startDate),
LocalDate.parse(endDate));
}
}
diff --git
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/DelinquencyWritePlatformServiceRangeChangeEventTest.java
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/DelinquencyWritePlatformServiceRangeChangeEventTest.java
index 15e542ab5..977cea5e6 100644
---
a/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/DelinquencyWritePlatformServiceRangeChangeEventTest.java
+++
b/fineract-provider/src/test/java/org/apache/fineract/portfolio/deliquency/DelinquencyWritePlatformServiceRangeChangeEventTest.java
@@ -127,7 +127,7 @@ public class
DelinquencyWritePlatformServiceRangeChangeEventTest {
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new
LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO,
2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
- null, null, false, null, null, null);
+ null, null, null, null);
Map<Long, CollectionData> installmentsCollection = new HashMap<>();
@@ -239,10 +239,10 @@ public class
DelinquencyWritePlatformServiceRangeChangeEventTest {
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new
LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO,
2L, null, 2L, overDueSinceDate, BigDecimal.ZERO, null, null,
- null, null, false, null, null, null);
+ null, null, null, null);
CollectionData installmentCollectionData = new
CollectionData(BigDecimal.ZERO, 2L, null, 2L, overDueSinceDate,
- installmentPrincipalAmount, null, null, null, null, false,
null, null, null);
+ installmentPrincipalAmount, null, null, null, null, null,
null);
Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData);
@@ -305,10 +305,10 @@ public class
DelinquencyWritePlatformServiceRangeChangeEventTest {
LoanScheduleDelinquencyData loanScheduleDelinquencyData = new
LoanScheduleDelinquencyData(1L, overDueSinceDate, 1L,
loanForProcessing);
CollectionData collectionData = new CollectionData(BigDecimal.ZERO,
29L, null, 29L, overDueSinceDate, BigDecimal.ZERO, null, null,
- null, null, false, null, null, null);
+ null, null, null, null);
CollectionData installmentCollectionData = new
CollectionData(BigDecimal.ZERO, 29L, null, 29L, overDueSinceDate,
- installmentPrincipalAmount, null, null, null, null, false,
null, null, null);
+ installmentPrincipalAmount, null, null, null, null, null,
null);
Map<Long, CollectionData> installmentsCollection = new HashMap<>();
installmentsCollection.put(1L, installmentCollectionData);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyActionIntegrationTests.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyActionIntegrationTests.java
index aaea011da..1d1fc3fa7 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyActionIntegrationTests.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyActionIntegrationTests.java
@@ -29,12 +29,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.math.BigDecimal;
import java.time.LocalDate;
+import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.GetDelinquencyActionsResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
+import org.apache.fineract.client.models.GetLoansLoanIdDelinquencyPausePeriod;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse;
@@ -172,26 +174,29 @@ public class DelinquencyActionIntegrationTests extends
BaseLoanIntegrationTest {
.dateFormat(DATETIME_PATTERN).locale("en"));
// Validate Loan Delinquency Pause Period on Loan
- validateLoanDelinquencyPausePerios(loanId, "10 January 2023", "15
January 2023", true);
+ validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10
January 2023", "15 January 2023", true));
// Create a Resume for the Loan for the current business date, it
is still expected to be in pause
loanTransactionHelper.createLoanDelinquencyAction(loanId, RESUME,
"14 January 2023");
// Validate Loan Delinquency Pause Period on Loan
- validateLoanDelinquencyPausePerios(loanId, "10 January 2023", "14
January 2023", true);
+ validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10
January 2023", "14 January 2023", true));
// Update business date to 15 January 2023
businessDateHelper.updateBusinessDate(new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023")
.dateFormat(DATETIME_PATTERN).locale("en"));
// Validate Loan Delinquency Pause Period on Loan
- validateLoanDelinquencyPausePerios(loanId, "10 January 2023", "14
January 2023", false);
+ validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10
January 2023", "14 January 2023", false));
// Create a new pause action for the future
loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE,
"20 January 2023", "25 January 2023");
// Validate Loan Delinquency Pause Period on Loan
- validateLoanDelinquencyPausePerios(loanId, "10 January 2023", "14
January 2023", false);
+ validateLoanDelinquencyPausePeriods(loanId, //
+ pausePeriods("10 January 2023", "14 January 2023", false),
//
+ pausePeriods("20 January 2023", "25 January 2023", false)
//
+ );
});
}
@@ -217,13 +222,22 @@ public class DelinquencyActionIntegrationTests extends
BaseLoanIntegrationTest {
});
}
- private void validateLoanDelinquencyPausePerios(Long loanId, String
expectedStart, String expectedEnd, Boolean expectedPauseState) {
+ private void validateLoanDelinquencyPausePeriods(Long loanId,
GetLoansLoanIdDelinquencyPausePeriod... pausePeriods) {
GetLoansLoanIdResponse loan =
loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
Assertions.assertNotNull(loan.getDelinquent());
- Assertions.assertEquals(expectedPauseState,
loan.getDelinquent().getDelinquencyCalculationPaused());
- Assertions.assertEquals(LocalDate.parse(expectedStart,
dateTimeFormatter),
- loan.getDelinquent().getDelinquencyPausePeriodStartDate());
- Assertions.assertEquals(LocalDate.parse(expectedEnd,
dateTimeFormatter), loan.getDelinquent().getDelinquencyPausePeriodEndDate());
+ if (pausePeriods.length > 0) {
+ Assertions.assertEquals(Arrays.asList(pausePeriods),
loan.getDelinquent().getDelinquencyPausePeriods());
+ } else {
+
Assertions.assertNull(loan.getDelinquent().getDelinquencyPausePeriods());
+ }
+ }
+
+ private GetLoansLoanIdDelinquencyPausePeriod pausePeriods(String
startDate, String endDate, boolean active) {
+ GetLoansLoanIdDelinquencyPausePeriod pausePeriod = new
GetLoansLoanIdDelinquencyPausePeriod();
+ pausePeriod.setActive(active);
+ pausePeriod.setPausePeriodStart(LocalDate.parse(startDate,
dateTimeFormatter));
+ pausePeriod.setPausePeriodEnd(LocalDate.parse(endDate,
dateTimeFormatter));
+ return pausePeriod;
}
private Long createLoanProductWith25PctDownPayment(boolean
autoDownPaymentEnabled, boolean multiDisburseEnabled) {
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
index b3c7ad60b..29bdab718 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java
@@ -490,6 +490,11 @@ public class ExternalEventConfigurationHelper {
loanTransactionDownPaymentPostBusinessEvent.put("enabled", false);
defaults.add(loanTransactionDownPaymentPostBusinessEvent);
+ Map<String, Object> loanAccountDelinquencyPauseChangedBusinessEvent =
new HashMap<>();
+ loanAccountDelinquencyPauseChangedBusinessEvent.put("type",
"LoanAccountDelinquencyPauseChangedBusinessEvent");
+ loanAccountDelinquencyPauseChangedBusinessEvent.put("enabled", false);
+ defaults.add(loanAccountDelinquencyPauseChangedBusinessEvent);
+
return defaults;
}