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;
 
     }


Reply via email to