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 @@
+
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 @@
+
+
+
+
+
+
+
+
+
+
+
+
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/LoanDelinquencyPausePeriodMapper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanDelinquencyPausePeriodMapper.java
new file mode 100644
index 000000000..c4b99d34e
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/event/external/service/serialization/mapper/loan/LoanDelinquencyPausePeriodMapper.java
@@ -0,0 +1,31 @@
+/**
+ * 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.external.service.serialization.mapper.loan;
+
+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.DelinquencyPausePeriod;
+import org.mapstruct.Mapper;
+
+@Mapper(config = AvroMapperConfig.class)
+public interface LoanDelinquencyPausePeriodMapper {
+
+ 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 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 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 findMatchingResume(LoanDelinquencyAction pause, List 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,20 +990,27 @@ final class LoansApiResourceSwagger {
@Schema(example = "100.000000")
public Double lastRepaymentAmount;
- @Schema(example = "true")
- public Boolean delinquencyCalculationPaused;
-
- @Schema(example = "[2022, 07, 05]")
- public LocalDate delinquencyPausePeriodStartDate;
-
- @Schema(example = "[2022, 07, 10]")
- public LocalDate delinquencyPausePeriodEndDate;
+ @Schema(description = "List of GetLoansLoanIdDelinquencyPausePeriod")
+ public List delinquencyPausePeriods;
@Schema(description = "List of GetLoansLoanIdLoanInstallmentLevelDelinquency")
public List installmentLevelDelinquency;
}
+ static final class GetLoansLoanIdDelinquencyPausePeriod {
+
+ @Schema(example = "true")
+ public Boolean active;
+
+ @Schema(example = "[2022, 07, 05]")
+ public LocalDate pausePeriodStart;
+
+ @Schema(example = "[2022, 07, 10]")
+ public LocalDate pausePeriodEnd;
+
+ }
+
static final class GetLoansLoanIdLoanInstallmentLevelDelinquency {
private GetLoansLoanIdLoanInstallmentLevelDelinquency() {}
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 delinquencyPausePeriods;
public Collection 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/DelinquencyPausePeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DelinquencyPausePeriod.java
new file mode 100644
index 000000000..0aef796b7
--- /dev/null
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DelinquencyPausePeriod.java
@@ -0,0 +1,36 @@
+/**
+ * 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.data;
+
+import java.time.LocalDate;
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.ToString;
+
+@AllArgsConstructor
+@ToString
+@Getter
+@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 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 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 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 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 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 loanAccountDelinquencyPauseChangedBusinessEvent = new HashMap<>();
+ loanAccountDelinquencyPauseChangedBusinessEvent.put("type", "LoanAccountDelinquencyPauseChangedBusinessEvent");
+ loanAccountDelinquencyPauseChangedBusinessEvent.put("enabled", false);
+ defaults.add(loanAccountDelinquencyPauseChangedBusinessEvent);
+
return defaults;
}