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 15c968bc1b FINERACT-2181: Fix fully paid check on EmiModel
15c968bc1b is described below
commit 15c968bc1bf35501d1f3ce13721c3d689c35f5c7
Author: Adam Saghy <[email protected]>
AuthorDate: Wed May 21 10:43:18 2025 +0200
FINERACT-2181: Fix fully paid check on EmiModel
---
.../api/LoanTransactionsApiResourceSwagger.java | 2 +
.../domain/LoanRepaymentScheduleInstallment.java | 7 +-
.../loanproduct/calc/data/RepaymentPeriod.java | 2 +-
.../api/InternalLoanInformationApiResource.java | 43 +---
.../adjustment/LoanAdjustmentServiceImpl.java | 2 +-
.../integrationtests/BaseLoanIntegrationTest.java | 4 +-
.../integrationtests/LoanInterestPauseApiTest.java | 22 +-
.../LoanInterestRecalculationCOBTest.java | 12 +-
.../LoanRescheduleRequestTest.java | 2 +-
.../integrationtests/common/BatchHelper.java | 2 +-
.../common/BusinessDateHelper.java | 20 +-
.../common/loans/LoanProductTestBuilder.java | 4 +-
.../common/loans/LoanTestLifecycleExtension.java | 87 ++++---
.../common/loans/LoanTransactionHelper.java | 4 +
.../common/organisation/CampaignsTest.java | 266 +++++++++++----------
.../src/test/resources/jsv-messages.properties | 92 +++++++
16 files changed, 349 insertions(+), 222 deletions(-)
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResourceSwagger.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResourceSwagger.java
index 1ee205ae80..9014fd8c92 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResourceSwagger.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanTransactionsApiResourceSwagger.java
@@ -108,6 +108,8 @@ final class LoanTransactionsApiResourceSwagger {
public List<GetLoanProductsChargeOffReasonOptions>
chargeOffReasonOptions;
public List<GetPaymentTypeOptions> paymentTypeOptions;
+ @Schema(example = "200.000000")
+ public Double netDisbursalAmount;
}
public static final class GetLoanCurrency {
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
index 86b828bc11..5789c37dac 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java
@@ -30,6 +30,7 @@ import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import lombok.Getter;
import lombok.Setter;
@@ -1025,7 +1026,7 @@ public class LoanRepaymentScheduleInstallment extends
AbstractAuditableWithUTCDa
}
public void copyFrom(final LoanRepaymentScheduleInstallment installment) {
- if (getId().equals(installment.getId())) {
+ if (nonNullAndEqual(getId(), installment.getId())) {
return;
}
// Reset balances
@@ -1149,4 +1150,8 @@ public class LoanRepaymentScheduleInstallment extends
AbstractAuditableWithUTCDa
}
setLoanTransactionToRepaymentScheduleMappings(retainedTransactionRepaymentScheduleMapping);
}
+
+ private static boolean nonNullAndEqual(Object a, Object b) {
+ return a != null && b != null && Objects.equals(a, b);
+ }
}
diff --git
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/data/RepaymentPeriod.java
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/data/RepaymentPeriod.java
index a921139389..e3faf47910 100644
---
a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/data/RepaymentPeriod.java
+++
b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/data/RepaymentPeriod.java
@@ -253,7 +253,7 @@ public final class RepaymentPeriod {
}
public boolean isFullyPaid() {
- return getEmi().isEqualTo(getTotalPaidAmount());
+ return getEmiPlusChargeback().isEqualTo(getTotalPaidAmount());
}
/**
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/InternalLoanInformationApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/InternalLoanInformationApiResource.java
index ee37e4972a..67f399160f 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/InternalLoanInformationApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/InternalLoanInformationApiResource.java
@@ -18,12 +18,6 @@
*/
package org.apache.fineract.portfolio.loanaccount.api;
-import static
org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_BY;
-import static
org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.CREATED_DATE;
-import static
org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_BY;
-import static
org.apache.fineract.infrastructure.core.domain.AuditableFieldsConstants.LAST_MODIFIED_DATE;
-
-import com.google.gson.Gson;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
@@ -33,17 +27,13 @@ import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.UriInfo;
-import java.util.HashMap;
+import java.time.OffsetDateTime;
import java.util.List;
-import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.api.ApiRequestParameterHelper;
import org.apache.fineract.infrastructure.core.boot.FineractProfiles;
-import
org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSerializationSettings;
-import
org.apache.fineract.infrastructure.core.serialization.ToApiJsonSerializer;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import
org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import
org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
@@ -62,12 +52,8 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
private final LoanRepositoryWrapper loanRepositoryWrapper;
private final LoanTransactionRepository loanTransactionRepository;
- private final ToApiJsonSerializer<Map> toApiJsonSerializerForMap;
- private final ToApiJsonSerializer<List> toApiJsonSerializerForList;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final AdvancedPaymentDataMapper advancedPaymentDataMapper;
- private final LoanAccountDomainService loanAccountDomainService;
- private final Gson gson = new Gson();
@Override
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
@@ -87,7 +73,7 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
- public String getLoanAuditFields(@Context final UriInfo uriInfo,
@PathParam("loanId") Long loanId) {
+ public AuditData getLoanAuditFields(@Context final UriInfo uriInfo,
@PathParam("loanId") Long loanId) {
log.warn("------------------------------------------------------------");
log.warn("
");
log.warn("Fetching loan with {}", loanId);
@@ -95,11 +81,8 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
log.warn("------------------------------------------------------------");
final Loan loan =
loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
- Map<String, Object> auditFields = new HashMap<>(
- Map.of(CREATED_BY, loan.getCreatedBy().orElse(null),
CREATED_DATE, loan.getCreatedDate().orElse(null), LAST_MODIFIED_BY,
- loan.getLastModifiedBy().orElse(null),
LAST_MODIFIED_DATE, loan.getLastModifiedDate().orElse(null)));
- final ApiRequestJsonSerializationSettings settings =
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
- return this.toApiJsonSerializerForMap.serialize(settings, auditFields);
+ return new AuditData(loan.getCreatedBy().orElse(null),
loan.getCreatedDate().orElse(null), loan.getLastModifiedBy().orElse(null),
+ loan.getLastModifiedDate().orElse(null));
}
@GET
@@ -107,7 +90,7 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
- public String getLoanTransactionAuditFields(@Context final UriInfo
uriInfo, @PathParam("loanId") Long loanId,
+ public AuditData getLoanTransactionAuditFields(@Context final UriInfo
uriInfo, @PathParam("loanId") Long loanId,
@PathParam("transactionId") Long transactionId) {
log.warn("------------------------------------------------------------");
log.warn("
");
@@ -116,11 +99,8 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
log.warn("------------------------------------------------------------");
final LoanTransaction transaction =
loanTransactionRepository.findById(transactionId).orElseThrow();
- Map<String, Object> auditFields = new HashMap<>(Map.of(CREATED_BY,
transaction.getCreatedBy().orElse(null), CREATED_DATE,
- transaction.getCreatedDate().orElse(null), LAST_MODIFIED_BY,
transaction.getLastModifiedBy().orElse(null),
- LAST_MODIFIED_DATE,
transaction.getLastModifiedDate().orElse(null)));
- final ApiRequestJsonSerializationSettings settings =
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
- return this.toApiJsonSerializerForMap.serialize(settings, auditFields);
+ return new AuditData(transaction.getCreatedBy().orElse(null),
transaction.getCreatedDate().orElse(null),
+ transaction.getLastModifiedBy().orElse(null),
transaction.getLastModifiedDate().orElse(null));
}
@GET
@@ -128,16 +108,14 @@ public class InternalLoanInformationApiResource
implements InitializingBean {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@SuppressFBWarnings("SLF4J_SIGN_ONLY_FORMAT")
- public String getLoansByStatus(@Context final UriInfo uriInfo,
@PathParam("statusId") Integer statusId) {
+ public List<Long> getLoansByStatus(@Context final UriInfo uriInfo,
@PathParam("statusId") Integer statusId) {
log.warn("------------------------------------------------------------");
log.warn("
");
log.warn("Fetching loans by status {}", statusId);
log.warn("
");
log.warn("------------------------------------------------------------");
- final List<Long> loanIds =
loanRepositoryWrapper.findLoanIdsByStatusId(statusId);
- final ApiRequestJsonSerializationSettings settings =
this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
- return this.toApiJsonSerializerForList.serialize(settings, loanIds);
+ return loanRepositoryWrapper.findLoanIdsByStatusId(statusId);
}
@GET
@@ -156,4 +134,7 @@ public class InternalLoanInformationApiResource implements
InitializingBean {
final Loan loan =
loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
return
advancedPaymentDataMapper.mapLoanPaymentAllocationRule(loan.getPaymentAllocationRules());
}
+
+ private record AuditData(Long createdBy, OffsetDateTime createdDate, Long
lastModifiedBy, OffsetDateTime lastModifiedDate) {
+ }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/adjustment/LoanAdjustmentServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/adjustment/LoanAdjustmentServiceImpl.java
index 339d4f3580..1992eef926 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/adjustment/LoanAdjustmentServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/adjustment/LoanAdjustmentServiceImpl.java
@@ -279,7 +279,7 @@ public class LoanAdjustmentServiceImpl implements
LoanAdjustmentService {
writeOffTransaction.reverse();
}
- if (newTransactionDetail.isRepaymentLikeType() ||
newTransactionDetail.isInterestWaiver()) {
+ if (newTransactionDetail.isRepaymentLikeType() ||
newTransactionDetail.isWaiver()) {
loanDownPaymentHandlerService.handleRepaymentOrRecoveryOrWaiverTransaction(loan,
newTransactionDetail, transactionForAdjustment,
scheduleGeneratorDTO);
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index c696a1fbbc..40030968b4 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -345,8 +345,8 @@ public abstract class BaseLoanIntegrationTest extends
IntegrationTest {
.isInterestRecalculationEnabled(true)//
.interestRecalculationCompoundingMethod(0)//
.rescheduleStrategyMethod(RescheduleStrategyMethod.ADJUST_LAST_UNPAID_PERIOD)//
-
.recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD)//
- .recalculationRestFrequencyInterval(0)//
+
.recalculationRestFrequencyType(RecalculationRestFrequencyType.DAILY)//
+ .recalculationRestFrequencyInterval(1)//
.isArrearsBasedOnOriginalSchedule(false)//
.isCompoundingToBePostedAsTransaction(false)//
.preClosureInterestCalculationStrategy(1)//
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
index e0cd6de3d5..e2a6b23709 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestPauseApiTest.java
@@ -301,7 +301,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void testUpdateInterestPauseByLoanId_overlapping_shouldFail3() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByLoanId("2023-01-02", "2023-01-06",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByLoanId("2023-01-03", "2023-01-06",
"yyyy-MM-dd", "en", loanId);
PostLoansLoanIdTransactionsResponse createResponse2 =
LOAN_TRANSACTION_HELPER.createInterestPauseByLoanId("2023-01-07",
"2023-01-12", "yyyy-MM-dd", "en", loanId);
@@ -495,7 +495,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void testUpdateInterestPauseByExternalId_overlapping_shouldFail3() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-02",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-03",
"2023-01-06", "yyyy-MM-dd", "en", externalId);
PostLoansLoanIdTransactionsResponse createResponse2 =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-07",
"2023-01-12", "yyyy-MM-dd", "en", externalId);
@@ -517,7 +517,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void
testUpdateInterestPauseByExternalId_endDateBeforeStartDate_shouldFail() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-01",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-03",
"2023-01-12", "yyyy-MM-dd", "en", externalId);
Assertions.assertNotNull(createResponse);
@@ -538,7 +538,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void
testUpdateInterestPauseByExternalId_startDateBeforeLoanStart_shouldFail() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-01",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-03",
"2023-01-12", "yyyy-MM-dd", "en", externalId);
Assertions.assertNotNull(createResponse);
@@ -559,7 +559,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void
testDeleteInterestPauseByExternalId_validRequest_shouldSucceed() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-01",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-03",
"2023-01-12", "yyyy-MM-dd", "en", externalId);
Assertions.assertNotNull(createResponse, "Create response should not
be null");
@@ -591,7 +591,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
@Test
public void
testDeleteInterestPauseByExternalId_invalidExternalId_shouldFail() {
- PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-01",
+ PostLoansLoanIdTransactionsResponse createResponse =
LOAN_TRANSACTION_HELPER.createInterestPauseByExternalId("2023-01-03",
"2023-01-12", "yyyy-MM-dd", "en", externalId);
Assertions.assertNotNull(createResponse);
@@ -698,7 +698,7 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
AdvancedPaymentData defaultAllocation =
createDefaultPaymentAllocation(futureInstallmentAllocationRule);
String loanProductJSON = new
LoanProductTestBuilder().withPrincipal(loanPrincipalAmount).withNumberOfRepayments(numberOfRepayments)
.withRepaymentAfterEvery("1").withRepaymentTypeAsMonth().withinterestRatePerPeriod(interestRatePerPeriod)
-
.withInterestRateFrequencyTypeAsMonths().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
+
.withInterestRateFrequencyTypeAsYear().withAmortizationTypeAsEqualInstallments().withInterestTypeAsDecliningBalance()
.withAccountingRulePeriodicAccrual(new Account[] {
assetAccount, incomeAccount, expenseAccount, overpaymentAccount })
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true).addAdvancedPaymentAllocation(defaultAllocation)
.withLoanScheduleType(LoanScheduleType.PROGRESSIVE).withLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL)
@@ -719,10 +719,10 @@ public class LoanInterestPauseApiTest extends
BaseLoanIntegrationTest {
String loanApplicationJSON = new
LoanApplicationTestBuilder().withPrincipal(loanPrincipalAmount)
.withLoanTermFrequency(numberOfRepayments).withLoanTermFrequencyAsDays().withNumberOfRepayments(numberOfRepayments)
.withRepaymentEveryAfter("1").withRepaymentFrequencyTypeAsDays().withInterestRatePerPeriod(interestRatePerPeriod)
-
.withInterestTypeAsFlatBalance().withAmortizationTypeAsEqualPrincipalPayments()
-
.withInterestCalculationPeriodTypeSameAsRepaymentPeriod().withExpectedDisbursementDate(dateString)
-
.withSubmittedOnDate(dateString).withLoanType("individual").withExternalId(externalId)
-
.withRepaymentStrategy("advanced-payment-allocation-strategy").build(clientId.toString(),
loanProductId.toString(), null);
+
.withInterestTypeAsDecliningBalance().withAmortizationTypeAsEqualInstallments().withInterestCalculationPeriodTypeAsDays()
+
.withExpectedDisbursementDate(dateString).withSubmittedOnDate(dateString).withLoanType("individual")
+
.withExternalId(externalId).withRepaymentStrategy("advanced-payment-allocation-strategy")
+ .build(clientId.toString(), loanProductId.toString(), null);
loanId = LOAN_TRANSACTION_HELPER.getLoanId(loanApplicationJSON);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRecalculationCOBTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRecalculationCOBTest.java
index 343e5063b3..83473953ec 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRecalculationCOBTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanInterestRecalculationCOBTest.java
@@ -455,7 +455,8 @@ public class LoanInterestRecalculationCOBTest extends
BaseLoanIntegrationTest {
public void
verifyLoanInstallmentRecalculatedIfThereIsOverdueInstallmentOn4IProgressiveLoanCOBStep()
{
AtomicReference<Long> loanIdRef = new AtomicReference<>();
runAt("1 January 2023", () -> {
- PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(create4IProgressive());
+ PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(
+
create4IProgressive().recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD));
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(),
loanProduct.getResourceId(), "1 January 2023", 8000.0, 10.0,
4, null);
@@ -532,7 +533,8 @@ public class LoanInterestRecalculationCOBTest extends
BaseLoanIntegrationTest {
public void
verifyLoanInstallmentRecalculatedIfThereIsOverdueInstallmentOn4IProgressiveLoanCOBStepLatePaidPaidOnTimeLatePaidPayoffOnTime()
{
AtomicReference<Long> loanIdRef = new AtomicReference<>();
runAt("1 January 2023", () -> {
- PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(create4IProgressive());
+ PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(
+
create4IProgressive().recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD));
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(),
loanProduct.getResourceId(), "1 January 2023", 8000.0, 10.0,
4, null);
@@ -875,7 +877,8 @@ public class LoanInterestRecalculationCOBTest extends
BaseLoanIntegrationTest {
public void
verifyLoanInstallmentRecalculatedIfThereIsOverdueInstallmentOn4IProgressiveLoanCOBStepOnePaid()
{
AtomicReference<Long> loanIdRef = new AtomicReference<>();
runAt("1 January 2023", () -> {
- PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(create4IProgressive());
+ PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(
+
create4IProgressive().recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD));
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(),
loanProduct.getResourceId(), "1 January 2023", 8000.0, 10.0,
4, null);
@@ -997,7 +1000,8 @@ public class LoanInterestRecalculationCOBTest extends
BaseLoanIntegrationTest {
public void
verifyLoanInstallmentRecalculatedIfThereIsOverdueInstallmentOnProgressiveLoanJob()
{
AtomicReference<Long> loanIdRef = new AtomicReference<>();
runAt("1 January 2023", () -> {
- PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(create4IProgressive());
+ PostLoanProductsResponse loanProduct =
loanProductHelper.createLoanProduct(
+
create4IProgressive().recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD));
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(),
loanProduct.getResourceId(), "1 January 2023", 8000.0, 10.0,
4, null);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
index 89b8e41670..0c5a9551eb 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java
@@ -265,7 +265,7 @@ public class LoanRescheduleRequestTest extends
BaseLoanIntegrationTest {
runAt("15 February 2023", () -> {
loanResponse.set(applyForLoanApplication(client.getClientId(),
commonLoanProductId, BigDecimal.valueOf(500.0), 45, 15, 3,
- BigDecimal.ZERO, "01 January 2023", "01 January 2023"));
+ BigDecimal.TEN, "01 January 2023", "01 January 2023"));
loanTransactionHelper.approveLoan(loanResponse.get().getLoanId(),
new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(500)).dateFormat(DATETIME_PATTERN)
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
index 3f1592b315..3978155628 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BatchHelper.java
@@ -469,7 +469,7 @@ public final class BatchHelper {
final String dateString =
LocalDate.now(Utils.getZoneIdOfTenant()).format(DateTimeFormatter.ofPattern(dateFormat));
final String body = String.format(
- "{\"chargeId\": \"%d\", \"locale\": \"en\", \"amount\":
\"11.15\", " + "\"dateFormat\": \"%s\", \"dueDate\": \"%s\"}",
+ "{\"chargeId\": \"%d\", \"locale\": \"en\", \"amount\":
\"100.0\", " + "\"dateFormat\": \"%s\", \"dueDate\": \"%s\"}",
chargeId, dateFormat, dateString);
br.setBody(body);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessDateHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessDateHelper.java
index d94eb3e9b7..0ae7d0764b 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessDateHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/BusinessDateHelper.java
@@ -18,6 +18,8 @@
*/
package org.apache.fineract.integrationtests.common;
+import static
org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
+
import com.google.gson.Gson;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
@@ -28,13 +30,16 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateData;
import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.BusinessDateResponse;
+import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.client.util.Calls;
import org.apache.fineract.client.util.JSON;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
+import
org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
@Slf4j
public final class BusinessDateHelper {
+ private static final String DATETIME_PATTERN = "dd MMMM yyyy";
private static final Gson GSON = new JSON().getGson();
public BusinessDateHelper() {}
@@ -51,7 +56,7 @@ public final class BusinessDateHelper {
return Utils.performServerPost(requestSpec, responseSpec,
BUSINESS_DATE_API, buildBusinessDateRequest(type, date), "changes");
}
- public BusinessDateResponse updateBusinessDate(final BusinessDateRequest
request) {
+ public static BusinessDateResponse updateBusinessDate(final
BusinessDateRequest request) {
log.info("------------------UPDATE BUSINESS
DATE----------------------");
log.info("------------------Type: {}, date: {}----------------------",
request.getType(), request.getDate());
return
Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.updateBusinessDate(request));
@@ -91,4 +96,17 @@ public final class BusinessDateHelper {
return new Gson().toJson(map);
}
+ public static void runAt(String date, Runnable runnable) {
+ try {
+ new
GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
+ new PutGlobalConfigurationsRequest().enabled(true));
+ updateBusinessDate(
+ new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
+ runnable.run();
+ } finally {
+ new
GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
+ new PutGlobalConfigurationsRequest().enabled(false));
+ }
+ }
+
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index 1d4f389ea0..847bec4ba9 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -127,8 +127,8 @@ public class LoanProductTestBuilder {
private String interestRecalculationCompoundingMethod = "0";
private String preCloseInterestCalculationStrategy =
INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE;
private String rescheduleStrategyMethod = "1";
- private String recalculationRestFrequencyType = "1";
- private String recalculationRestFrequencyInterval = "0";
+ private String recalculationRestFrequencyType = "2";
+ private String recalculationRestFrequencyInterval = "1";
private String recalculationCompoundingFrequencyType = null;
private String recalculationCompoundingFrequencyInterval = null;
private String minimumDaysBetweenDisbursalAndFirstRepayment = null;
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTestLifecycleExtension.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTestLifecycleExtension.java
index e3d9b0f168..e19019aad0 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTestLifecycleExtension.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTestLifecycleExtension.java
@@ -18,62 +18,73 @@
*/
package org.apache.fineract.integrationtests.common.loans;
-import io.restassured.builder.RequestSpecBuilder;
-import io.restassured.builder.ResponseSpecBuilder;
-import io.restassured.http.ContentType;
-import io.restassured.specification.RequestSpecification;
-import io.restassured.specification.ResponseSpecification;
+import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
-import java.util.HashMap;
import java.util.List;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
+import
org.apache.fineract.client.models.GetLoansLoanIdTransactionsTemplateResponse;
import org.apache.fineract.client.models.PostLoansLoanIdRequest;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
+import org.apache.fineract.client.util.Calls;
+import org.apache.fineract.integrationtests.common.BusinessDateHelper;
+import org.apache.fineract.integrationtests.common.FineractClientHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
public class LoanTestLifecycleExtension implements AfterEachCallback {
- private ResponseSpecification responseSpec;
- private RequestSpecification requestSpec;
private LoanTransactionHelper loanTransactionHelper;
- private DateTimeFormatter dateFormatter = new
DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter();
+ public static final String DATE_FORMAT = "dd MMMM yyyy";
+ private final DateTimeFormatter dateFormatter = new
DateTimeFormatterBuilder().appendPattern(DATE_FORMAT).toFormatter();
@Override
public void afterEach(ExtensionContext context) {
- this.requestSpec = new
RequestSpecBuilder().setContentType(ContentType.JSON).build();
- this.requestSpec.header("Authorization", "Basic " +
Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
- this.responseSpec = new
ResponseSpecBuilder().expectStatusCode(200).build();
- this.requestSpec.header("Fineract-Platform-TenantId", "default");
- this.loanTransactionHelper = new
LoanTransactionHelper(this.requestSpec, this.responseSpec);
+
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()),
() -> {
+ this.loanTransactionHelper = new LoanTransactionHelper(null, null);
- // Fully repay ACTIVE loans, so it will not be picked up by any jobs
- List<Integer> loanIds =
LoanTransactionHelper.getLoanIdsByStatusId(requestSpec, responseSpec, 300);
- loanIds.forEach(loanId -> {
- HashMap prepayDetail =
this.loanTransactionHelper.getPrepayAmount(this.requestSpec, this.responseSpec,
loanId);
- LocalDate transactionDate = LocalDate.of((Integer) ((List)
prepayDetail.get("date")).get(0),
- (Integer) ((List) prepayDetail.get("date")).get(1),
(Integer) ((List) prepayDetail.get("date")).get(2));
- Double amount =
Double.parseDouble(String.valueOf(prepayDetail.get("amount")));
- Double netDisbursalAmount =
Double.parseDouble(String.valueOf(prepayDetail.get("netDisbursalAmount")));
- Double repayAmount = Double.compare(amount, 0.0) > 0 ? amount :
netDisbursalAmount;
- loanTransactionHelper.makeLoanRepayment((long) loanId, new
PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy")
-
.transactionDate(dateFormatter.format(transactionDate)).locale("en").transactionAmount(repayAmount));
- });
- // Undo APPROVED loans, so the next step can REJECT them, so it will
not be picked up by any jobs
- loanIds = LoanTransactionHelper.getLoanIdsByStatusId(requestSpec,
responseSpec, 200);
- loanIds.forEach(loanId -> {
- loanTransactionHelper.undoApproval(loanId);
- });
- // Mark SUBMITTED loans, as REJECTED, so it will not be picked up by
any jobs
- loanIds = LoanTransactionHelper.getLoanIdsByStatusId(requestSpec,
responseSpec, 100);
- loanIds.forEach(loanId -> {
- GetLoansLoanIdResponse details =
loanTransactionHelper.getLoanDetails((long) loanId);
- loanTransactionHelper.rejectLoan((long) loanId,
- new
PostLoansLoanIdRequest().rejectedOnDate(dateFormatter.format(details.getTimeline().getSubmittedOnDate()))
- .locale("en").dateFormat("dd MMMM yyyy"));
+ // Fully repay ACTIVE loans, so it will not be picked up by any
jobs
+ List<Long> loanIds =
LoanTransactionHelper.getLoanIdsByStatusId(300);
+ loanIds.forEach(loanId -> {
+ GetLoansLoanIdResponse loanResponse = Calls
+
.ok(FineractClientHelper.getFineractClient().loans.retrieveLoan((long) loanId,
null, "all", null, null));
+
loanResponse.getDisbursementDetails().forEach(disbursementDetail -> {
+ if (disbursementDetail.getActualDisbursementDate() ==
null) {
+ loanTransactionHelper.disburseLoan((long) loanId,
+ new PostLoansLoanIdRequest()
+
.actualDisbursementDate(dateFormatter.format(disbursementDetail.getExpectedDisbursementDate()))
+ .dateFormat(DATE_FORMAT).locale("en")
+
.transactionAmount(BigDecimal.valueOf(disbursementDetail.getPrincipal())));
+ }
+ });
+ loanResponse = Calls
+
.ok(FineractClientHelper.getFineractClient().loans.retrieveLoan((long) loanId,
null, "all", null, null));
+ GetLoansLoanIdTransactionsTemplateResponse prepayDetail =
this.loanTransactionHelper.getPrepaymentAmount(loanId,
+ dateFormatter.format(Utils.getLocalDateOfTenant()),
DATE_FORMAT);
+ LocalDate transactionDate = prepayDetail.getDate();
+ Double amount = prepayDetail.getAmount();
+ Double netDisbursalAmount =
prepayDetail.getNetDisbursalAmount();
+ Double repayAmount = Double.compare(amount, 0.0) > 0 ? amount
: netDisbursalAmount;
+ loanTransactionHelper.makeLoanRepayment(loanId, new
PostLoansLoanIdTransactionsRequest().dateFormat(DATE_FORMAT)
+
.transactionDate(dateFormatter.format(transactionDate)).locale("en").transactionAmount(repayAmount));
+ });
+ // Undo APPROVED loans, so the next step can REJECT them, so it
will not be picked up by any jobs
+ loanIds = LoanTransactionHelper.getLoanIdsByStatusId(200);
+ loanIds.forEach(loanId -> {
+ loanTransactionHelper.undoApprovalForLoan(loanId, new
PostLoansLoanIdRequest());
+ });
+ // Mark SUBMITTED loans, as REJECTED, so it will not be picked up
by any jobs
+ loanIds = LoanTransactionHelper.getLoanIdsByStatusId(100);
+ loanIds.forEach(loanId -> {
+ GetLoansLoanIdResponse details =
loanTransactionHelper.getLoanDetails((long) loanId);
+ loanTransactionHelper.rejectLoan(loanId,
+ new
PostLoansLoanIdRequest().rejectedOnDate(dateFormatter.format(details.getTimeline().getSubmittedOnDate()))
+ .locale("en").dateFormat(DATE_FORMAT));
+ });
+ // loanIds = LoanTransactionHelper.getLoanIdsByStatusId(300);
+ // assertEquals(0, loanIds.size());
});
}
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index 87e78d3b5b..8918a5a146 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -2983,6 +2983,10 @@ public class LoanTransactionHelper {
return new Gson().fromJson(get, new TypeToken<ArrayList<Integer>>()
{}.getType());
}
+ public static List<Long> getLoanIdsByStatusId(Integer statusId) {
+ return
Calls.ok(FineractClientHelper.getFineractClient().legacy.getLoansByStatus(statusId));
+ }
+
public PutLoanProductsProductIdResponse updateLoanProduct(Long id,
PutLoanProductsProductIdRequest requestModifyLoan) {
return
Calls.ok(FineractClientHelper.getFineractClient().loanProducts.updateLoanProduct(id,
requestModifyLoan));
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/organisation/CampaignsTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/organisation/CampaignsTest.java
index 8e704927a2..cb9d378350 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/organisation/CampaignsTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/organisation/CampaignsTest.java
@@ -30,6 +30,7 @@ import io.restassured.specification.ResponseSpecification;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
+import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.CommonConstants;
import org.apache.fineract.integrationtests.common.Utils;
import org.junit.jupiter.api.BeforeEach;
@@ -42,7 +43,6 @@ import org.mockserver.model.MediaType;
@ExtendWith(MockServerExtension.class)
@MockServerSettings(ports = { 9191 })
-
public class CampaignsTest {
private RequestSpecification requestSpec;
@@ -93,145 +93,155 @@ public class CampaignsTest {
@Test
public void testSupportedActionsForCampaignWithTriggerTypeAsDirect() {
- // creating new campaign
- Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
DIRECT_TRIGGER_TYPE);
- this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
-
- // updating campaign
- Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
- NON_TRIGGERED_REPORT_NAME, DIRECT_TRIGGER_TYPE);
- assertEquals(campaignId, updatedCampaignId);
-
- // activating campaign
- Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- ACTIVATE_COMMAND);
- assertEquals(activatedCampaignId, campaignId);
-
- // closing campaign
- Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // reactivating campaign
- Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- REACTIVATE_COMMAND);
- assertEquals(reactivateCampaignId, campaignId);
-
- // closing campaign again for deletion
- closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId, CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // deleting campaign
- Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
- assertEquals(deletedCampaignId, campaignId);
+
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()),
() -> {
+ // creating new campaign
+ Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
DIRECT_TRIGGER_TYPE);
+
this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
+
+ // updating campaign
+ Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
+ NON_TRIGGERED_REPORT_NAME, DIRECT_TRIGGER_TYPE);
+ assertEquals(campaignId, updatedCampaignId);
+
+ // activating campaign
+ Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ ACTIVATE_COMMAND);
+ assertEquals(activatedCampaignId, campaignId);
+
+ // closing campaign
+ Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // reactivating campaign
+ Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ REACTIVATE_COMMAND);
+ assertEquals(reactivateCampaignId, campaignId);
+
+ // closing campaign again for deletion
+ closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // deleting campaign
+ Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
+ assertEquals(deletedCampaignId, campaignId);
+ });
}
@Test
public void testSupportedActionsForCampaignWithTriggerTypeAsScheduled() {
- // creating new campaign
- Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
SCHEDULED_TRIGGER_TYPE);
- this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
-
- // updating campaign
- Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
- NON_TRIGGERED_REPORT_NAME, SCHEDULED_TRIGGER_TYPE);
- assertEquals(campaignId, updatedCampaignId);
-
- // activating campaign
- Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- ACTIVATE_COMMAND);
- assertEquals(activatedCampaignId, campaignId);
-
- // closing campaign
- Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // reactivating campaign
- Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- REACTIVATE_COMMAND);
- assertEquals(reactivateCampaignId, campaignId);
-
- // closing campaign again for deletion
- closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId, CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // deleting campaign
- Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
- assertEquals(deletedCampaignId, campaignId);
+
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()),
() -> {
+ // creating new campaign
+ Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
SCHEDULED_TRIGGER_TYPE);
+
this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
+
+ // updating campaign
+ Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
+ NON_TRIGGERED_REPORT_NAME, SCHEDULED_TRIGGER_TYPE);
+ assertEquals(campaignId, updatedCampaignId);
+
+ // activating campaign
+ Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ ACTIVATE_COMMAND);
+ assertEquals(activatedCampaignId, campaignId);
+
+ // closing campaign
+ Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // reactivating campaign
+ Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ REACTIVATE_COMMAND);
+ assertEquals(reactivateCampaignId, campaignId);
+
+ // closing campaign again for deletion
+ closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // deleting campaign
+ Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
+ assertEquals(deletedCampaignId, campaignId);
+ });
}
@Test
public void testSupportedActionsForCampaignWithTriggerTypeAsTriggered() {
- // creating new campaign
- Integer campaignId =
this.campaignsHelper.createCampaign(TRIGGERED_REPORT_NAME,
TRIGGERED_TRIGGER_TYPE);
- this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
-
- // updating campaign
- Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
- TRIGGERED_REPORT_NAME, TRIGGERED_TRIGGER_TYPE);
- assertEquals(campaignId, updatedCampaignId);
-
- // activating campaign
- Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- ACTIVATE_COMMAND);
- assertEquals(activatedCampaignId, campaignId);
-
- // closing campaign
- Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // reactivating campaign
- Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- REACTIVATE_COMMAND);
- assertEquals(reactivateCampaignId, campaignId);
-
- // closing campaign again for deletion
- closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId, CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // deleting campaign
- Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
- assertEquals(deletedCampaignId, campaignId);
+
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()),
() -> {
+ // creating new campaign
+ Integer campaignId =
this.campaignsHelper.createCampaign(TRIGGERED_REPORT_NAME,
TRIGGERED_TRIGGER_TYPE);
+
this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
+
+ // updating campaign
+ Integer updatedCampaignId =
this.campaignsHelper.updateCampaign(this.requestSpec, this.responseSpec,
campaignId,
+ TRIGGERED_REPORT_NAME, TRIGGERED_TRIGGER_TYPE);
+ assertEquals(campaignId, updatedCampaignId);
+
+ // activating campaign
+ Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ ACTIVATE_COMMAND);
+ assertEquals(activatedCampaignId, campaignId);
+
+ // closing campaign
+ Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // reactivating campaign
+ Integer reactivateCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ REACTIVATE_COMMAND);
+ assertEquals(reactivateCampaignId, campaignId);
+
+ // closing campaign again for deletion
+ closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // deleting campaign
+ Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
+ assertEquals(deletedCampaignId, campaignId);
+ });
}
@SuppressWarnings("unchecked")
@Test
public void testSupportedActionsForCampaignWithError() {
- final ResponseSpecification responseSpecWithError = new
ResponseSpecBuilder().expectStatusCode(400).build();
- CampaignsHelper campaignsHelperWithError = new
CampaignsHelper(this.requestSpec, responseSpecWithError);
- // creating new campaign
- Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
DIRECT_TRIGGER_TYPE);
- this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
-
- // activating campaign with failure
- ArrayList<HashMap<String, Object>> campaignDateValidationData =
(ArrayList<HashMap<String, Object>>) campaignsHelperWithError
- .performActionsOnCampaignWithFailure(campaignId,
ACTIVATE_COMMAND,
-
Utils.getLocalDateOfTenant().plusDays(1).format(DateTimeFormatter.ofPattern(DATE_FORMAT)),
- CommonConstants.RESPONSE_ERROR);
- assertEquals("error.msg.campaign.activationDate.in.the.future",
-
campaignDateValidationData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
-
- // activating campaign
- Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- ACTIVATE_COMMAND);
- assertEquals(activatedCampaignId, campaignId);
-
- // activating campaign with failure
- ArrayList<HashMap<String, Object>> campaignErrorData =
(ArrayList<HashMap<String, Object>>) campaignsHelperWithError
- .performActionsOnCampaignWithFailure(activatedCampaignId,
ACTIVATE_COMMAND,
-
Utils.getLocalDateOfTenant().format(DateTimeFormatter.ofPattern(DATE_FORMAT)),
CommonConstants.RESPONSE_ERROR);
- assertEquals("error.msg.campaign.already.active",
campaignErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
-
- // closing campaign again for deletion
- Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
- CLOSE_COMMAND);
- assertEquals(closedCampaignId, campaignId);
-
- // deleting campaign
- Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
- assertEquals(deletedCampaignId, campaignId);
-
+
BusinessDateHelper.runAt(DateTimeFormatter.ofPattern(DATE_FORMAT).format(Utils.getLocalDateOfTenant()),
() -> {
+ final ResponseSpecification responseSpecWithError = new
ResponseSpecBuilder().expectStatusCode(400).build();
+ CampaignsHelper campaignsHelperWithError = new
CampaignsHelper(this.requestSpec, responseSpecWithError);
+ // creating new campaign
+ Integer campaignId =
this.campaignsHelper.createCampaign(NON_TRIGGERED_REPORT_NAME,
DIRECT_TRIGGER_TYPE);
+
this.campaignsHelper.verifyCampaignCreatedOnServer(this.requestSpec,
this.responseSpec, campaignId);
+
+ // activating campaign with failure
+ ArrayList<HashMap<String, Object>> campaignDateValidationData =
(ArrayList<HashMap<String, Object>>) campaignsHelperWithError
+ .performActionsOnCampaignWithFailure(campaignId,
ACTIVATE_COMMAND,
+
Utils.getLocalDateOfTenant().plusDays(1).format(DateTimeFormatter.ofPattern(DATE_FORMAT)),
+ CommonConstants.RESPONSE_ERROR);
+ assertEquals("error.msg.campaign.activationDate.in.the.future",
+
campaignDateValidationData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ // activating campaign
+ Integer activatedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ ACTIVATE_COMMAND);
+ assertEquals(activatedCampaignId, campaignId);
+
+ // activating campaign with failure
+ ArrayList<HashMap<String, Object>> campaignErrorData =
(ArrayList<HashMap<String, Object>>) campaignsHelperWithError
+ .performActionsOnCampaignWithFailure(activatedCampaignId,
ACTIVATE_COMMAND,
+
Utils.getLocalDateOfTenant().format(DateTimeFormatter.ofPattern(DATE_FORMAT)),
CommonConstants.RESPONSE_ERROR);
+ assertEquals("error.msg.campaign.already.active",
campaignErrorData.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE));
+
+ // closing campaign again for deletion
+ Integer closedCampaignId =
this.campaignsHelper.performActionsOnCampaign(this.requestSpec,
this.responseSpec, campaignId,
+ CLOSE_COMMAND);
+ assertEquals(closedCampaignId, campaignId);
+
+ // deleting campaign
+ Integer deletedCampaignId =
this.campaignsHelper.deleteCampaign(this.requestSpec, this.responseSpec,
campaignId);
+ assertEquals(deletedCampaignId, campaignId);
+ });
}
}
diff --git a/integration-tests/src/test/resources/jsv-messages.properties
b/integration-tests/src/test/resources/jsv-messages.properties
new file mode 100644
index 0000000000..e87defdade
--- /dev/null
+++ b/integration-tests/src/test/resources/jsv-messages.properties
@@ -0,0 +1,92 @@
+#
+# 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.
+#
+
+additionalProperties=Additional properties are not allowed: {0}
+allOf=One or more conditions in allOf failed: {0}
+anyOf=Value does not match any of the required schemas: {0}
+const=Value must be exactly: {0}
+contains=Array does not contain required item: {0}
+crossEdits=Cross edits are not allowed: {0}
+dependencies=Missing dependencies: {0}
+dependentRequired=Missing dependent properties: {0}
+edits=Invalid edits: {0}
+enum=Value {0} is not allowed. Allowed values are: {1}
+exclusiveMaximum=Value {0} must be less than (exclusive): {1}
+exclusiveMinimum=Value {0} must be greater than (exclusive): {1}
+format=Value {0} does not match required format: {1}
+items=Invalid item in array: {0}
+maxItems=Array has too many items: {0}, maximum: {1}
+maxLength=String is too long: {0}, maximum length: {1}
+maxProperties=Too many properties: {0}, maximum allowed: {1}
+maximum=Value {0} exceeds maximum: {1}
+minItems=Array has too few items: {0}, minimum: {1}
+minLength=String is too short: {0}, minimum length: {1}
+minProperties=Too few properties: {0}, minimum required: {1}
+minimum=Value {0} is below minimum: {1}
+multipleOf=Value {0} is not a multiple of {1}
+not=Value matches schema when it should not: {0}
+notAllowed=The value is not allowed: {0}
+oneOf=Value matches more than one schema in oneOf: {0}
+pattern=String does not match pattern: {0}
+prefixItems=Array does not match prefixItems validation rules: {0}
+properties=Invalid property: {0}
+propertyNames=Invalid property name: {0}
+readOnly=Property is read-only: {0}
+required=Required field is missing: {0}
+then='then' schema failed validation
+type=Expected type: {0}, found: {1}
+unionType=Value does not match any of the expected types: {0}
+uniqueItems=Array has duplicate items: {0}
+writeOnly=Property is write-only: {0}
+$ref=Reference {0} could not be resolved or is invalid
+if=Condition 'if' failed
+else='else' schema failed validation
+allErrors=Multiple validation errors occurred: {0}
+default=Validation failed for value: {0}
+patternProperties=Pattern property not matched: {0}
+
+# Format-specific
+date=Value does not match date format: {0}
+dateTime=Value does not match date-time format: {0}
+time=Value does not match time format: {0}
+email=Value is not a valid email address: {0}
+hostname=Value is not a valid hostname: {0}
+ipv4=Value is not a valid IPv4 address: {0}
+ipv6=Value is not a valid IPv6 address: {0}
+uri=Value is not a valid URI: {0}
+uuid=Value is not a valid UUID: {0}
+uriReference=Value is not a valid URI reference: {0}
+iri=Value is not a valid IRI: {0}
+iriReference=Value is not a valid IRI reference: {0}
+jsonPointer=Value is not a valid JSON Pointer: {0}
+relativeJsonPointer=Value is not a valid Relative JSON Pointer: {0}
+regex=Value is not a valid regular expression: {0}
+byte=Value is not a valid base64 string: {0}
+int32=Value is not a valid 32-bit integer: {0}
+int64=Value is not a valid 64-bit integer: {0}
+float=Value is not a valid float: {0}
+double=Value is not a valid double: {0}
+binary=Value is not a valid binary: {0}
+password=Password format validation failed
+contentEncoding=Value does not match expected encoding: {0}
+contentMediaType=Value does not match expected media type: {0}
+id=Invalid ID value: {0}
+false=Schema explicitly disallows all values
+dependentSchemas=Object does not satisfy dependent schemas: {0}
+unevaluatedProperties=Object has unevaluated properties that are not allowed:
{0}