FINERACT-2238: New command processing - Business Date Management (org.apache.fineract.infrastructure.businessdate)

This commit is contained in:
viktorpavlenko
2025-06-26 00:49:05 +02:00
committed by Aleksandar Vidakovic
parent d5958f36c7
commit bb46397daa
81 changed files with 1385 additions and 1099 deletions
+18 -2
View File
@@ -28,6 +28,7 @@ buildscript {
[ [
'fineract-api', 'fineract-api',
'fineract-core', 'fineract-core',
'fineract-validation',
'fineract-command', 'fineract-command',
'fineract-accounting', 'fineract-accounting',
'fineract-provider', 'fineract-provider',
@@ -57,6 +58,7 @@ buildscript {
'fineract-api', 'fineract-api',
'fineract-client', 'fineract-client',
'fineract-core', 'fineract-core',
'fineract-validation',
'fineract-command', 'fineract-command',
'fineract-accounting', 'fineract-accounting',
'fineract-provider', 'fineract-provider',
@@ -159,6 +161,10 @@ allprojects {
} }
configurations { configurations {
implementation {
exclude group: 'commons-logging', module: 'commons-logging'
}
api { api {
canBeResolved = true canBeResolved = true
} }
@@ -370,8 +376,18 @@ configure(project.fineractJavaProjects) {
withJavadocJar() withJavadocJar()
} }
tasks.withType(ProcessResources) { // TODO: we are forcing Gradle to do something it shouldn't! This effects Gradle caching AND breaks Liquibase!
destinationDir = layout.buildDirectory.dir('classes/java/main').get().asFile // tasks.withType(ProcessResources) {
// destinationDir = layout.buildDirectory.dir('classes/java/main').get().asFile
// }
processResources {
destinationDir = file("${buildDir}/resources/main")
doLast {
delete fileTree(dir: "${buildDir}/classes/java/main/db")
delete fileTree(dir: "${buildDir}/classes/java/main/META-INF")
}
} }
// Add performance optimizations // Add performance optimizations
+1 -1
View File
@@ -20,7 +20,7 @@
import static org.slf4j.LoggerFactory.* import static org.slf4j.LoggerFactory.*
plugins { plugins {
id 'io.spring.dependency-management' version '1.1.6' id 'io.spring.dependency-management' version '1.1.7'
id 'groovy' id 'groovy'
id 'java-gradle-plugin' id 'java-gradle-plugin'
id 'groovy-gradle-plugin' id 'groovy-gradle-plugin'
@@ -38,6 +38,7 @@ dependencyManagement {
mavenBom 'software.amazon.awssdk:bom:2.29.9' mavenBom 'software.amazon.awssdk:bom:2.29.9'
mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0' mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
mavenBom 'org.testcontainers:testcontainers-bom:1.20.4' mavenBom 'org.testcontainers:testcontainers-bom:1.20.4'
mavenBom 'org.glassfish.jersey:jersey-bom:3.1.10'
} }
dependencies { dependencies {
@@ -51,7 +52,6 @@ dependencyManagement {
dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5' dependency 'ch.qos.logback.contrib:logback-jackson:0.1.5'
dependency 'org.codehaus.janino:janino:3.1.12' dependency 'org.codehaus.janino:janino:3.1.12'
dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.2' dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:4.0.2'
dependency 'com.google.guava:guava:33.1.0-jre' dependency 'com.google.guava:guava:33.1.0-jre'
dependency 'com.google.code.gson:gson:2.11.0' dependency 'com.google.code.gson:gson:2.11.0'
@@ -76,8 +76,13 @@ dependencyManagement {
dependency 'org.ehcache:ehcache:3.10.8' dependency 'org.ehcache:ehcache:3.10.8'
dependency 'com.github.spullara.mustache.java:compiler:0.9.14' dependency 'com.github.spullara.mustache.java:compiler:0.9.14'
dependency 'com.jayway.jsonpath:json-path:2.9.0' dependency 'com.jayway.jsonpath:json-path:2.9.0'
dependency 'org.apache.tika:tika-core:2.9.3' dependency ('org.apache.tika:tika-core:2.9.3') {
dependency ('org.apache.tika:tika-parser-microsoft-module:2.9.3') { exclude 'commons-logging:commons-logging'
}
dependency ('org.apache.tika:tika-core:2.9.3') {
exclude 'commons-logging:commons-logging'
}
dependency ('org.apache.tika:tika-parser-miscoffice-module:2.9.3') {
exclude 'org.bouncycastle:bcprov-jdk15on' exclude 'org.bouncycastle:bcprov-jdk15on'
exclude 'org.bouncycastle:bcmail-jdk15on' exclude 'org.bouncycastle:bcmail-jdk15on'
exclude 'org.bouncycastle:bcprov-jdk18on' exclude 'org.bouncycastle:bcprov-jdk18on'
@@ -94,7 +99,7 @@ dependencyManagement {
exclude 'org.apache.commons:commons-compress' exclude 'org.apache.commons:commons-compress'
exclude 'xml-apis:xml-apis' exclude 'xml-apis:xml-apis'
} }
dependency ('org.apache.tika:tika-parser-miscoffice-module:2.9.3') { dependency ('org.apache.tika:tika-parser-microsoft-module:2.9.3') {
exclude 'org.bouncycastle:bcprov-jdk15on' exclude 'org.bouncycastle:bcprov-jdk15on'
exclude 'org.bouncycastle:bcmail-jdk15on' exclude 'org.bouncycastle:bcmail-jdk15on'
exclude 'org.bouncycastle:bcprov-jdk18on' exclude 'org.bouncycastle:bcprov-jdk18on'
@@ -117,7 +122,6 @@ dependencyManagement {
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4' dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
dependency 'jakarta.jms:jakarta.jms-api:3.1.0' dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0' dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.10'
dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
dependency 'org.apache.bval:org.apache.bval.bundle:3.0.2' dependency 'org.apache.bval:org.apache.bval.bundle:3.0.2'
dependency 'joda-time:joda-time:2.13.1' dependency 'joda-time:joda-time:2.13.1'
@@ -195,6 +199,8 @@ dependencyManagement {
dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.2') { dependency ('jakarta.xml.bind:jakarta.xml.bind-api:4.0.2') {
exclude 'jakarta.activation:jakarta.activation-api' exclude 'jakarta.activation:jakarta.activation-api'
} }
dependency 'jakarta.validation:jakarta.validation-api:3.1.1'
dependency 'org.hibernate.validator:hibernate-validator:8.0.2.Final'
dependency ('org.liquibase:liquibase-core:4.31.1') { dependency ('org.liquibase:liquibase-core:4.31.1') {
exclude 'javax.xml.bind:jaxb-api' exclude 'javax.xml.bind:jaxb-api'
@@ -243,6 +249,7 @@ dependencyManagement {
dependency 'org.assertj:assertj-core:3.26.3' dependency 'org.assertj:assertj-core:3.26.3'
dependency 'org.apache.commons:commons-math3:3.6.1' dependency 'org.apache.commons:commons-math3:3.6.1'
dependency 'commons-beanutils:commons-beanutils:1.11.0'
dependency 'org.mockito:mockito-inline:5.2.0' dependency 'org.mockito:mockito-inline:5.2.0'
+1 -2
View File
@@ -38,8 +38,6 @@ dependencies {
'com.github.spotbugs:spotbugs-annotations', 'com.github.spotbugs:spotbugs-annotations',
'org.mapstruct:mapstruct', 'org.mapstruct:mapstruct',
'com.lmax:disruptor', 'com.lmax:disruptor',
'com.ibm.icu:icu4j',
'org.yakworks:spring-icu4j',
) )
implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') { implementation('org.eclipse.persistence:org.eclipse.persistence.jpa') {
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence' exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
@@ -62,6 +60,7 @@ dependencies {
exclude group: 'org.skyscreamer' exclude group: 'org.skyscreamer'
} }
testImplementation ( testImplementation (
project(':fineract-validation'),
'org.springframework.boot:spring-boot-starter-web', 'org.springframework.boot:spring-boot-starter-web',
'org.mockito:mockito-inline', 'org.mockito:mockito-inline',
'org.openjdk.jmh:jmh-core', 'org.openjdk.jmh:jmh-core',
@@ -34,6 +34,8 @@ public class Command<T> implements Serializable {
private UUID id; private UUID id;
private String idempotencyKey;
private OffsetDateTime createdAt; private OffsetDateTime createdAt;
private String tenantId; private String tenantId;
@@ -16,9 +16,8 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.fineract.command.persistence; package org.apache.fineract.command.persistence.domain;
import org.apache.fineract.command.persistence.domain.CommandEntity;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
@@ -29,7 +29,7 @@ import org.springframework.stereotype.Component;
@Slf4j @Slf4j
@RequiredArgsConstructor @RequiredArgsConstructor
@Component @Component
public final class CommandJsonMapper { final class CommandJsonMapper {
private static final String CLASS_ATTRIBUTE = "@class"; private static final String CLASS_ATTRIBUTE = "@class";
private final ObjectMapper mapper; private final ObjectMapper mapper;
@@ -20,7 +20,7 @@ package org.apache.fineract.command;
import java.util.Map; import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.command.persistence.CommandRepository; import org.apache.fineract.command.persistence.domain.CommandRepository;
import org.apache.fineract.command.persistence.mapping.CommandMapper; import org.apache.fineract.command.persistence.mapping.CommandMapper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
@@ -23,16 +23,11 @@ import org.apache.fineract.command.core.CommandProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.PropertySource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import yakworks.i18n.icu.ICUBundleMessageSource;
@Slf4j @Slf4j
@Configuration @Configuration
@@ -42,22 +37,4 @@ import yakworks.i18n.icu.ICUBundleMessageSource;
@EnableAsync @EnableAsync
@PropertySource("classpath:application-test.properties") @PropertySource("classpath:application-test.properties")
@ComponentScan("org.apache.fineract.command.sample") @ComponentScan("org.apache.fineract.command.sample")
public class TestConfiguration { public class TestConfiguration {}
@Bean
MessageSource messageSource() {
var messageSource = new ICUBundleMessageSource();
messageSource.setBasenames("classpath:org.apache.fineract.messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
Validator validatorFactoryBean(MessageSource messageSource) {
var localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(messageSource);
return localValidatorFactoryBean;
}
}
@@ -22,7 +22,6 @@ import static org.apache.fineract.command.core.CommandConstants.COMMAND_REQUEST_
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON_VALUE; import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON_VALUE;
import jakarta.validation.Valid;
import java.time.OffsetDateTime; import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.UUID; import java.util.UUID;
@@ -56,7 +55,7 @@ class DummyApiController {
@PostMapping("/sync") @PostMapping("/sync")
DummyResponse dummySync(@RequestHeader(value = COMMAND_REQUEST_ID, required = false) UUID requestId, DummyResponse dummySync(@RequestHeader(value = COMMAND_REQUEST_ID, required = false) UUID requestId,
@RequestHeader(value = "x-fineract-tenant-id", required = false) String tenantId, @Valid @RequestBody DummyRequest request) { @RequestHeader(value = "x-fineract-tenant-id", required = false) String tenantId, @RequestBody DummyRequest request) {
var command = new DummyCommand(); var command = new DummyCommand();
command.setId(requestId); command.setId(requestId);
command.setPayload(request); command.setPayload(request);
+4 -3
View File
@@ -23,9 +23,10 @@ dependencies {
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library. // Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
// We also (normally should have) no need to ever use 'compileOnly'. // We also (normally should have) no need to ever use 'compileOnly'.
implementation( implementation(project(path: ':fineract-avro-schemas'))
project(path: ':fineract-avro-schemas') implementation(project(path: ':fineract-command'))
) implementation(project(path: ':fineract-validation'))
// implementation dependencies are directly used (compiled against) in src/main (and src/test) // implementation dependencies are directly used (compiled against) in src/main (and src/test)
implementation( implementation(
@@ -20,30 +20,26 @@ package org.apache.fineract.infrastructure.businessdate.api;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes; import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET; import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST; import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path; import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam; import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces; import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.MediaType;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.function.Supplier;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.command.core.CommandPipeline;
import org.apache.fineract.commands.service.CommandWrapperBuilder; import org.apache.fineract.infrastructure.businessdate.command.BusinessDateUpdateCommand;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.businessdate.data.request.BusinessDateRequest;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService; import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -52,19 +48,14 @@ import org.springframework.stereotype.Component;
@Tag(name = "Business Date Management", description = "Business date management enables you to set up, fetch and adjust organisation business dates") @Tag(name = "Business Date Management", description = "Business date management enables you to set up, fetch and adjust organisation business dates")
public class BusinessDateApiResource { public class BusinessDateApiResource {
private static final String BUSINESS_DATE = "BUSINESS_DATE";
private final PlatformSecurityContext securityContext;
private final DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer;
private final BusinessDateReadPlatformService readPlatformService; private final BusinessDateReadPlatformService readPlatformService;
private final PortfolioCommandSourceWritePlatformService commandWritePlatformService; private final CommandPipeline commandPipeline;
@GET @GET
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "List all business dates", description = "") @Operation(summary = "List all business dates", description = "")
public List<BusinessDateData> getBusinessDates() { public List<BusinessDateResponse> getBusinessDates() {
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
return this.readPlatformService.findAll(); return this.readPlatformService.findAll();
} }
@@ -73,8 +64,7 @@ public class BusinessDateApiResource {
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON }) @Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Retrieve a specific Business date", description = "") @Operation(summary = "Retrieve a specific Business date", description = "")
public BusinessDateData getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) { public BusinessDateResponse getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) {
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
return this.readPlatformService.findByType(type); return this.readPlatformService.findByType(type);
} }
@@ -82,14 +72,19 @@ public class BusinessDateApiResource {
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update Business Date", description = "") @Operation(summary = "Update Business Date", description = "")
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = BusinessDateRequest.class))) public BusinessDateResponse updateBusinessDate(@HeaderParam("Idempotency-Key") String idempotencyKey,
@ApiResponses({ @Valid BusinessDateUpdateRequest request) {
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateResponse.class))) })
public CommandProcessingResult updateBusinessDate(BusinessDateRequest businessDateRequest) { final var command = new BusinessDateUpdateCommand();
securityContext.authenticatedUser().validateHasUpdatePermission(BUSINESS_DATE);
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateBusinessDate() command.setId(UUID.randomUUID());
.withJson(jsonSerializer.serialize(businessDateRequest)).build(); command.setIdempotencyKey(idempotencyKey);
return commandWritePlatformService.logCommandSource(commandRequest); command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
command.setPayload(request);
final Supplier<BusinessDateResponse> response = commandPipeline.send(command);
return response.get();
} }
} }
@@ -16,11 +16,13 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.fineract.infrastructure.jobs.service.increasedateby1day; package org.apache.fineract.infrastructure.businessdate.command;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.fineract.command.core.Command;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
public interface IncreaseDateBy1DayService { @Data
@EqualsAndHashCode(callSuper = true)
void increaseDateByTypeByOneDay(BusinessDateType businessDateType); public class BusinessDateUpdateCommand extends Command<BusinessDateUpdateRequest> {}
}
@@ -21,24 +21,43 @@ package org.apache.fineract.infrastructure.businessdate.data;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
@Builder
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@Accessors(chain = true) @AllArgsConstructor
public class BusinessDateData implements Serializable { public class BusinessDateResponse implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private String description;
private String type;
private LocalDate date;
public static BusinessDateData instance(BusinessDateType businessDateType, LocalDate value) { private String description;
return new BusinessDateData().setType(businessDateType.getName()).setDescription(businessDateType.getDescription()).setDate(value); private BusinessDateType type;
private LocalDate date;
private Map<BusinessDateType, LocalDate> changes;
public void addChange(final BusinessDateType businessDateType, final LocalDate date) {
if (this.changes == null) {
this.changes = new HashMap<>();
}
changes.put(businessDateType, date);
} }
public void addAllChanges(final Map<BusinessDateType, LocalDate> changes) {
if (changes == null || changes.isEmpty()) {
return;
}
for (final Map.Entry<BusinessDateType, LocalDate> entry : changes.entrySet()) {
addChange(entry.getKey(), entry.getValue());
}
}
} }
@@ -0,0 +1,52 @@
/**
* 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.businessdate.data;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serial;
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.validation.constraints.LocalDate;
import org.apache.fineract.validation.constraints.Locale;
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@LocalDate(dateField = "date", formatField = "dateFormat", localeField = "locale")
public class BusinessDateUpdateRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotBlank(message = "{org.apache.fineract.businessdate.date-format.not-blank}")
private String dateFormat;
@NotNull(message = "{org.apache.fineract.businessdate.type.not-null}")
private BusinessDateType type;
@NotBlank(message = "{org.apache.fineract.businessdate.date.not-blank}")
private String date;
@NotBlank(message = "{org.apache.fineract.businessdate.locale.not-blank}")
@Locale
private String locale;
}
@@ -18,26 +18,26 @@
*/ */
package org.apache.fineract.infrastructure.businessdate.handler; package org.apache.fineract.infrastructure.businessdate.handler;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.commands.annotation.CommandType; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.commands.handler.NewCommandSourceHandler; import org.apache.fineract.command.core.Command;
import org.apache.fineract.command.core.CommandHandler;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService; import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.springframework.stereotype.Component;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@Slf4j
@Component
@RequiredArgsConstructor @RequiredArgsConstructor
@Service public class BusinessDateUpdateHandler implements CommandHandler<BusinessDateUpdateRequest, BusinessDateResponse> {
@CommandType(entity = "BUSINESS_DATE", action = "UPDATE")
public class BusinessDateUpdateHandler implements NewCommandSourceHandler {
private final BusinessDateWritePlatformService businessDateWritePlatformService; private final BusinessDateWritePlatformService businessDateWritePlatformService;
@Transactional @Transactional
@Override @Override
public CommandProcessingResult processCommand(@NotNull final JsonCommand command) { public BusinessDateResponse handle(Command<BusinessDateUpdateRequest> command) {
return businessDateWritePlatformService.updateBusinessDate(command); return businessDateWritePlatformService.updateBusinessDate(command.getPayload());
} }
} }
@@ -19,7 +19,7 @@
package org.apache.fineract.infrastructure.businessdate.mapper; package org.apache.fineract.infrastructure.businessdate.mapper;
import java.util.List; import java.util.List;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig; import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
@@ -29,8 +29,8 @@ import org.mapstruct.Mappings;
@Mapper(config = MapstructMapperConfig.class) @Mapper(config = MapstructMapperConfig.class)
public interface BusinessDateMapper { public interface BusinessDateMapper {
@Mappings({ @Mapping(target = "description", source = "source.type.description") }) @Mappings({ @Mapping(target = "description", source = "source.type.description"), @Mapping(target = "changes", ignore = true) })
BusinessDateData map(BusinessDate source); BusinessDateResponse map(BusinessDate source);
List<BusinessDateData> map(List<BusinessDate> sources); List<BusinessDateResponse> map(List<BusinessDate> sources);
} }
@@ -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.businessdate.mapper;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.core.config.MapstructMapperConfig;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@Mapper(config = MapstructMapperConfig.class)
public interface BusinessDateUpdateRequestMapper {
@Mapping(target = "description", expression = "java(source.getType().getDescription())")
@Mapping(source = "type", target = "type")
@Mapping(target = "date", expression = "java(org.apache.fineract.infrastructure.core.service.DateUtils.toLocalDate(source.getLocale(), source.getDate(), source.getDateFormat()))")
@Mapping(target = "changes", ignore = true)
BusinessDateResponse map(BusinessDateUpdateRequest source);
}
@@ -21,14 +21,14 @@ package org.apache.fineract.infrastructure.businessdate.service;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
public interface BusinessDateReadPlatformService { public interface BusinessDateReadPlatformService {
List<BusinessDateData> findAll(); List<BusinessDateResponse> findAll();
BusinessDateData findByType(String type); BusinessDateResponse findByType(String type);
HashMap<BusinessDateType, LocalDate> getBusinessDates(); HashMap<BusinessDateType, LocalDate> getBusinessDates();
} }
@@ -24,7 +24,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
@@ -40,17 +40,17 @@ import org.springframework.stereotype.Service;
public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlatformService { public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlatformService {
private final BusinessDateRepository repository; private final BusinessDateRepository repository;
private final BusinessDateMapper mapper; private final BusinessDateMapper businessDatemapper;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
@Override @Override
public List<BusinessDateData> findAll() { public List<BusinessDateResponse> findAll() {
List<BusinessDate> businessDateList = repository.findAll(); List<BusinessDate> businessDateList = repository.findAll();
return mapper.map(businessDateList); return businessDatemapper.map(businessDateList);
} }
@Override @Override
public BusinessDateData findByType(String type) { public BusinessDateResponse findByType(String type) {
BusinessDateType businessDateType; BusinessDateType businessDateType;
try { try {
businessDateType = BusinessDateType.valueOf(type); businessDateType = BusinessDateType.valueOf(type);
@@ -63,7 +63,7 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
log.error("Business date with the provided type cannot be found {}", type); log.error("Business date with the provided type cannot be found {}", type);
throw BusinessDateNotFoundException.notFound(type); throw BusinessDateNotFoundException.notFound(type);
} }
return mapper.map(businessDate.get()); return businessDatemapper.map(businessDate.get());
} }
@Override @Override
@@ -73,9 +73,9 @@ public class BusinessDateReadPlatformServiceImpl implements BusinessDateReadPlat
businessDateMap.put(BusinessDateType.BUSINESS_DATE, tenantDate); businessDateMap.put(BusinessDateType.BUSINESS_DATE, tenantDate);
businessDateMap.put(BusinessDateType.COB_DATE, tenantDate); businessDateMap.put(BusinessDateType.COB_DATE, tenantDate);
if (configurationDomainService.isBusinessDateEnabled()) { if (configurationDomainService.isBusinessDateEnabled()) {
final List<BusinessDateData> businessDateDataList = this.findAll(); final List<BusinessDateResponse> businessDateResponseList = this.findAll();
for (BusinessDateData businessDateData : businessDateDataList) { for (BusinessDateResponse businessDateResponse : businessDateResponseList) {
businessDateMap.put(BusinessDateType.valueOf(businessDateData.getType()), businessDateData.getDate()); businessDateMap.put(businessDateResponse.getType(), businessDateResponse.getDate());
} }
} }
return businessDateMap; return businessDateMap;
@@ -18,19 +18,14 @@
*/ */
package org.apache.fineract.infrastructure.businessdate.service; package org.apache.fineract.infrastructure.businessdate.service;
import java.util.Map; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException; import org.apache.fineract.infrastructure.jobs.exception.JobExecutionException;
public interface BusinessDateWritePlatformService { public interface BusinessDateWritePlatformService {
CommandProcessingResult updateBusinessDate(JsonCommand command); BusinessDateResponse updateBusinessDate(BusinessDateUpdateRequest request);
void adjustDate(BusinessDateData data, Map<String, Object> changes); void increaseDateByTypeByOneDay(BusinessDateType businessDateType) throws JobExecutionException;
void increaseCOBDateByOneDay() throws JobExecutionException;
void increaseBusinessDateByOneDay() throws JobExecutionException;
} }
@@ -18,27 +18,21 @@
*/ */
package org.apache.fineract.infrastructure.businessdate.service; package org.apache.fineract.infrastructure.businessdate.service;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateActionException; import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateActionException;
import org.apache.fineract.infrastructure.businessdate.validator.BusinessDateDataParserAndValidator; import org.apache.fineract.infrastructure.businessdate.mapper.BusinessDateUpdateRequestMapper;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException; import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
@@ -50,54 +44,30 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePlatformService { public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePlatformService {
private final BusinessDateDataParserAndValidator dataValidator;
private final BusinessDateRepository repository; private final BusinessDateRepository repository;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
private final BusinessDateUpdateRequestMapper updateRequestMapper;
@Override @Override
public CommandProcessingResult updateBusinessDate(@NotNull final JsonCommand command) { public BusinessDateResponse updateBusinessDate(BusinessDateUpdateRequest request) {
BusinessDateData data = dataValidator.validateAndParseUpdate(command); BusinessDateResponse businessDateDto = updateRequestMapper.map(request);
Map<String, Object> changes = new HashMap<>();
adjustDate(data, changes);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).with(changes).build();
adjustDate(businessDateDto);
return businessDateDto;
} }
@Override @Override
public void adjustDate(BusinessDateData data, Map<String, Object> changes) { public void increaseDateByTypeByOneDay(BusinessDateType businessDateType) throws JobExecutionException {
boolean isCOBDateAdjustmentEnabled = configurationDomainService.isCOBDateAdjustmentEnabled();
boolean isBusinessDateEnabled = configurationDomainService.isBusinessDateEnabled();
if (!isBusinessDateEnabled) {
log.error("Business date functionality is not enabled!");
throw new BusinessDateActionException("business.date.is.not.enabled", "Business date functionality is not enabled");
}
updateOrCreateBusinessDate(data.getType(), data.getDate(), changes);
if (isCOBDateAdjustmentEnabled && BusinessDateType.BUSINESS_DATE.name().equals(data.getType())) {
updateOrCreateBusinessDate(BusinessDateType.COB_DATE.getName(), data.getDate().minus(1, ChronoUnit.DAYS), changes);
}
}
@Override
public void increaseCOBDateByOneDay() throws JobExecutionException {
increaseDateByTypeByOneDay(BusinessDateType.COB_DATE);
}
@Override
public void increaseBusinessDateByOneDay() throws JobExecutionException {
increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE);
}
private void increaseDateByTypeByOneDay(BusinessDateType businessDateType) throws JobExecutionException {
Map<String, Object> changes = new HashMap<>();
Optional<BusinessDate> businessDateEntity = repository.findByType(businessDateType); Optional<BusinessDate> businessDateEntity = repository.findByType(businessDateType);
List<Throwable> exceptions = new ArrayList<>(); List<Throwable> exceptions = new ArrayList<>();
LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant()); LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant());
businessDate = businessDate.plusDays(1); businessDate = businessDate.plusDays(1);
try { try {
BusinessDateData businessDateData = BusinessDateData.instance(businessDateType, businessDate); BusinessDateResponse response = BusinessDateResponse.builder().type(businessDateType)
adjustDate(businessDateData, changes); .description(businessDateType.getDescription()).date(businessDate).build();
adjustDate(response);
} catch (final PlatformApiDataValidationException e) { } catch (final PlatformApiDataValidationException e) {
final List<ApiParameterError> errors = e.getErrors(); final List<ApiParameterError> errors = e.getErrors();
for (final ApiParameterError error : errors) { for (final ApiParameterError error : errors) {
@@ -116,27 +86,44 @@ public class BusinessDateWritePlatformServiceImpl implements BusinessDateWritePl
} }
} }
private void updateOrCreateBusinessDate(String type, LocalDate newDate, Map<String, Object> changes) { private void adjustDate(BusinessDateResponse response) {
BusinessDateType businessDateType = BusinessDateType.valueOf(type); boolean isCOBDateAdjustmentEnabled = configurationDomainService.isCOBDateAdjustmentEnabled();
boolean isBusinessDateEnabled = configurationDomainService.isBusinessDateEnabled();
if (!isBusinessDateEnabled) {
log.error("Business date functionality is not enabled!");
throw new BusinessDateActionException("business.date.is.not.enabled", "Business date functionality is not enabled");
}
updateOrCreateBusinessDate(response);
if (isCOBDateAdjustmentEnabled && BusinessDateType.BUSINESS_DATE.equals(response.getType())) {
BusinessDateResponse res = BusinessDateResponse.builder().type(BusinessDateType.COB_DATE)
.description(BusinessDateType.COB_DATE.getDescription()).date(response.getDate().minusDays(1)).build();
updateOrCreateBusinessDate(res);
response.addAllChanges(res.getChanges());
}
}
private void updateOrCreateBusinessDate(BusinessDateResponse businessDateDto) {
BusinessDateType businessDateType = businessDateDto.getType();
Optional<BusinessDate> businessDate = repository.findByType(businessDateType); Optional<BusinessDate> businessDate = repository.findByType(businessDateType);
if (businessDate.isEmpty()) { if (businessDate.isEmpty()) {
BusinessDate newBusinessDate = BusinessDate.instance(businessDateType, newDate); BusinessDate newBusinessDate = BusinessDate.instance(businessDateType, businessDateDto.getDate());
repository.save(newBusinessDate); repository.save(newBusinessDate);
changes.put(type, newBusinessDate.getDate()); businessDateDto.addChange(businessDateType, newBusinessDate.getDate());
} else { } else {
updateBusinessDate(businessDate.get(), newDate, changes); updateBusinessDate(businessDate.get(), businessDateDto);
} }
} }
private void updateBusinessDate(BusinessDate businessDate, LocalDate newDate, Map<String, Object> changes) { private void updateBusinessDate(BusinessDate businessDate, BusinessDateResponse businessDateDto) {
LocalDate oldDate = businessDate.getDate(); if (DateUtils.isEqual(businessDate.getDate(), businessDateDto.getDate())) {
if (DateUtils.isEqual(oldDate, newDate)) {
return; return;
} }
businessDate.setDate(newDate);
businessDate.setDate(businessDateDto.getDate());
repository.save(businessDate); repository.save(businessDate);
changes.put(businessDate.getType().name(), newDate);
businessDateDto.addChange(businessDate.getType(), businessDateDto.getDate());
} }
} }
@@ -1,107 +0,0 @@
/**
* 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.businessdate.validator;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.springframework.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
@Component
public class BusinessDateDataParserAndValidator {
private final FromJsonHelper jsonHelper;
public BusinessDateData validateAndParseUpdate(@NotNull final JsonCommand command) {
final DataValidatorBuilder dataValidator = new DataValidatorBuilder(new ArrayList<>()).resource("businessdate.update");
JsonObject element = extractJsonObject(command);
BusinessDateData result = validateAndParseUpdate(dataValidator, element, jsonHelper);
throwExceptionIfValidationWarningsExist(dataValidator);
return result;
}
private JsonObject extractJsonObject(JsonCommand command) {
String json = command.json();
if (StringUtils.isBlank(json)) {
throw new InvalidJsonException();
}
final JsonElement element = jsonHelper.parse(json);
return element.getAsJsonObject();
}
private void throwExceptionIfValidationWarningsExist(DataValidatorBuilder dataValidator) {
if (dataValidator.hasError()) {
log.error("Business date - Validation errors: {}", dataValidator.getDataValidationErrors());
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.",
dataValidator.getDataValidationErrors());
}
}
private BusinessDateData validateAndParseUpdate(final DataValidatorBuilder dataValidator, JsonObject element,
FromJsonHelper jsonHelper) {
if (element == null) {
return null;
}
jsonHelper.checkForUnsupportedParameters(element, List.of("type", "date", "dateFormat", "locale"));
String businessDateTypeName = jsonHelper.extractStringNamed("type", element);
final String localeValue = jsonHelper.extractStringNamed("locale", element);
final String dateFormat = jsonHelper.extractDateFormatParameter(element);
final String dateValue = jsonHelper.extractStringNamed("date", element);
dataValidator.reset().parameter("type").value(businessDateTypeName).notBlank();
dataValidator.reset().parameter("locale").value(localeValue).notBlank();
dataValidator.reset().parameter("dateFormat").value(dateFormat).notBlank();
dataValidator.reset().parameter("date").value(dateValue).notBlank();
if (dataValidator.hasError()) {
return null;
}
Locale locale = jsonHelper.extractLocaleParameter(element);
BusinessDateType type;
try {
type = BusinessDateType.valueOf(businessDateTypeName);
} catch (IllegalArgumentException e) {
dataValidator.reset().parameter("type").failWithCode("Invalid Business Type value: `" + businessDateTypeName + "`");
return null;
}
LocalDate date = jsonHelper.extractLocalDateNamed("date", element, dateFormat, locale);
dataValidator.reset().parameter("date").value(date).notNull();
return dataValidator.hasError() ? null : BusinessDateData.instance(type, date);
}
}
@@ -0,0 +1,57 @@
/**
* 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.core.exceptionmapper;
import jakarta.validation.ConstraintViolationException;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import jakarta.ws.rs.ext.ExceptionMapper;
import jakarta.ws.rs.ext.Provider;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
import org.springframework.stereotype.Component;
@Slf4j
@Provider
@Component
public class JakartaValidationExceptionMapper implements FineractExceptionMapper, ExceptionMapper<ConstraintViolationException> {
@Override
public Response toResponse(final ConstraintViolationException exception) {
log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
final ApiGlobalErrorResponse dataValidationErrorResponse = ApiGlobalErrorResponse.badClientRequest(exception.getMessage(),
exception.getLocalizedMessage(), getApiParameterErrors(exception));
return Response.status(Status.BAD_REQUEST).entity(dataValidationErrorResponse).type(MediaType.APPLICATION_JSON).build();
}
@Override
public int errorCode() {
return 2002;
}
private List<ApiParameterError> getApiParameterErrors(final ConstraintViolationException exception) {
return exception.getConstraintViolations().stream().map(violation -> ApiParameterError
.parameterError(violation.getMessageTemplate(), violation.getMessage(), violation.getPropertyPath().toString())).toList();
}
}
@@ -28,7 +28,9 @@ import java.time.OffsetDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField; import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
@@ -128,18 +130,10 @@ public final class DateUtils {
return compare(first, second, truncate) == 0; return compare(first, second, truncate) == 0;
} }
public static boolean isEqualTenantDateTime(LocalDateTime dateTime) {
return isEqualTenantDateTime(dateTime, null);
}
public static boolean isEqualTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) { public static boolean isEqualTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
return isEqual(dateTime, getLocalDateTimeOfTenant(), truncate); return isEqual(dateTime, getLocalDateTimeOfTenant(), truncate);
} }
public static boolean isEqualSystemDateTime(LocalDateTime dateTime) {
return isEqualSystemDateTime(dateTime, null);
}
public static boolean isEqualSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) { public static boolean isEqualSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
return isEqual(dateTime, getLocalDateTimeOfSystem(), truncate); return isEqual(dateTime, getLocalDateTimeOfSystem(), truncate);
} }
@@ -152,22 +146,6 @@ public final class DateUtils {
return compare(first, second, truncate) < 0; return compare(first, second, truncate) < 0;
} }
public static boolean isBeforeTenantDateTime(LocalDateTime dateTime) {
return isBeforeTenantDateTime(dateTime, null);
}
public static boolean isBeforeTenantDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
return isBefore(dateTime, getLocalDateTimeOfTenant(), truncate);
}
public static boolean isBeforeSystemDateTime(LocalDateTime dateTime) {
return isBeforeSystemDateTime(dateTime, null);
}
public static boolean isBeforeSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
return isBefore(dateTime, getLocalDateTimeOfSystem(), truncate);
}
public static boolean isAfter(LocalDateTime first, LocalDateTime second) { public static boolean isAfter(LocalDateTime first, LocalDateTime second) {
return isAfter(first, second, null); return isAfter(first, second, null);
} }
@@ -184,10 +162,6 @@ public final class DateUtils {
return isAfter(dateTime, getLocalDateTimeOfTenant(), truncate); return isAfter(dateTime, getLocalDateTimeOfTenant(), truncate);
} }
public static boolean isAfterSystemDateTime(LocalDateTime dateTime) {
return isAfterSystemDateTime(dateTime, null);
}
public static boolean isAfterSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) { public static boolean isAfterSystemDateTime(LocalDateTime dateTime, ChronoUnit truncate) {
return isAfter(dateTime, getLocalDateTimeOfSystem(), truncate); return isAfter(dateTime, getLocalDateTimeOfSystem(), truncate);
} }
@@ -228,10 +202,6 @@ public final class DateUtils {
return compare(first, second, truncate) == 0; return compare(first, second, truncate) == 0;
} }
public static boolean isEqualTenantDateTime(OffsetDateTime dateTime) {
return isEqualTenantDateTime(dateTime, null);
}
public static boolean isEqualTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) { public static boolean isEqualTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
return isEqual(dateTime, getOffsetDateTimeOfTenant(), truncate); return isEqual(dateTime, getOffsetDateTimeOfTenant(), truncate);
} }
@@ -244,10 +214,6 @@ public final class DateUtils {
return compare(first, second, truncate) < 0; return compare(first, second, truncate) < 0;
} }
public static boolean isBeforeTenantDateTime(OffsetDateTime dateTime) {
return isBeforeTenantDateTime(dateTime, null);
}
public static boolean isBeforeTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) { public static boolean isBeforeTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
return isBefore(dateTime, getOffsetDateTimeOfTenant(), truncate); return isBefore(dateTime, getOffsetDateTimeOfTenant(), truncate);
} }
@@ -260,10 +226,6 @@ public final class DateUtils {
return compare(first, second, truncate) > 0; return compare(first, second, truncate) > 0;
} }
public static boolean isAfterTenantDateTime(OffsetDateTime dateTime) {
return isAfterTenantDateTime(dateTime, null);
}
public static boolean isAfterTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) { public static boolean isAfterTenantDateTime(OffsetDateTime dateTime, ChronoUnit truncate) {
return isAfter(dateTime, getOffsetDateTimeOfTenant(), truncate); return isAfter(dateTime, getOffsetDateTimeOfTenant(), truncate);
} }
@@ -274,10 +236,6 @@ public final class DateUtils {
return ThreadLocalContextUtil.getBusinessDate(); return ThreadLocalContextUtil.getBusinessDate();
} }
public static int compareToBusinessDate(LocalDate date) {
return compare(date, getBusinessLocalDate());
}
public static boolean isEqualTenantDate(LocalDate date) { public static boolean isEqualTenantDate(LocalDate date) {
return isEqual(date, getLocalDateOfTenant()); return isEqual(date, getLocalDateOfTenant());
} }
@@ -286,10 +244,6 @@ public final class DateUtils {
return isBefore(date, getLocalDateOfTenant()); return isBefore(date, getLocalDateOfTenant());
} }
public static boolean isAfterTenantDate(LocalDate date) {
return isAfter(date, getLocalDateOfTenant());
}
public static boolean isEqualBusinessDate(LocalDate date) { public static boolean isEqualBusinessDate(LocalDate date) {
return isEqual(date, getBusinessLocalDate()); return isEqual(date, getBusinessLocalDate());
} }
@@ -306,10 +260,6 @@ public final class DateUtils {
return isAfterBusinessDate(localDate); return isAfterBusinessDate(localDate);
} }
public static boolean isDateInThePast(final LocalDate localDate) {
return isBeforeBusinessDate(localDate);
}
public static boolean isDateInRangeFromInclusiveToExclusive(final LocalDate fromInclusive, final LocalDate upToNotInclusive, public static boolean isDateInRangeFromInclusiveToExclusive(final LocalDate fromInclusive, final LocalDate upToNotInclusive,
final LocalDate target) { final LocalDate target) {
return (DateUtils.isEqual(target, fromInclusive) || DateUtils.isAfter(target, fromInclusive)) return (DateUtils.isEqual(target, fromInclusive) || DateUtils.isAfter(target, fromInclusive))
@@ -399,6 +349,16 @@ public final class DateUtils {
} }
} }
public static LocalDate toLocalDate(String local, String date, String dateFormat) {
Locale locale = Locale.forLanguageTag(local);
String patternISO = dateFormat.replace("y", "u");
DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().parseLenient().appendPattern(patternISO)
.optionalStart().appendPattern(" HH:mm:ss").optionalEnd().parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0).parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0).toFormatter(locale)
.withResolverStyle(ResolverStyle.STRICT);
return LocalDateTime.parse(date, formatter).toLocalDate();
}
public static String format(LocalDate date) { public static String format(LocalDate date) {
return format(date, null); return format(date, null);
} }
@@ -21,8 +21,8 @@ package org.apache.fineract.test.helper;
import java.io.IOException; import java.io.IOException;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.fineract.client.models.BusinessDateRequest;
import org.apache.fineract.client.models.BusinessDateResponse; import org.apache.fineract.client.models.BusinessDateResponse;
import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.services.BusinessDateManagementApi; import org.apache.fineract.client.services.BusinessDateManagementApi;
import org.apache.fineract.test.support.TestContext; import org.apache.fineract.test.support.TestContext;
import org.apache.fineract.test.support.TestContextKey; import org.apache.fineract.test.support.TestContextKey;
@@ -36,15 +36,14 @@ public class BusinessDateHelper {
public static final String DATE_FORMAT = "dd MMMM yyyy"; public static final String DATE_FORMAT = "dd MMMM yyyy";
public static final String DEFAULT_LOCALE = "en"; public static final String DEFAULT_LOCALE = "en";
public static final String BUSINESS_DATE = "BUSINESS_DATE"; public static final String BUSINESS_DATE = "BUSINESS_DATE";
public static final String DEFAULT = "BUSINESS_DATE";
public static final String COB = "COB_DATE"; public static final String COB = "COB_DATE";
private final BusinessDateManagementApi businessDateManagementApi; private final BusinessDateManagementApi businessDateManagementApi;
public void setBusinessDate(String businessDate) throws IOException { public void setBusinessDate(String businessDate) throws IOException {
BusinessDateRequest businessDateRequest = defaultBusinessDateRequest().date(businessDate); BusinessDateUpdateRequest businessDateRequest = defaultBusinessDateRequest().date(businessDate);
Response<BusinessDateResponse> businessDateRequestResponse = businessDateManagementApi.updateBusinessDate(businessDateRequest) Response<BusinessDateResponse> businessDateRequestResponse = businessDateManagementApi.updateBusinessDate(null, businessDateRequest)
.execute(); .execute();
ErrorHelper.checkSuccessfulApiCall(businessDateRequestResponse); ErrorHelper.checkSuccessfulApiCall(businessDateRequestResponse);
TestContext.INSTANCE.set(TestContextKey.BUSINESS_DATE_RESPONSE, businessDateRequestResponse); TestContext.INSTANCE.set(TestContextKey.BUSINESS_DATE_RESPONSE, businessDateRequestResponse);
@@ -56,11 +55,12 @@ public class BusinessDateHelper {
setBusinessDate(today); setBusinessDate(today);
} }
public BusinessDateRequest defaultBusinessDateRequest() { public BusinessDateUpdateRequest defaultBusinessDateRequest() {
return new BusinessDateRequest().type(DEFAULT).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); return new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE).dateFormat(DATE_FORMAT)
.locale(DEFAULT_LOCALE);
} }
public String getBusinessDate() throws IOException { public String getBusinessDate() throws IOException {
return businessDateManagementApi.getBusinessDate(DEFAULT).toString(); return businessDateManagementApi.getBusinessDate(BUSINESS_DATE).toString();
} }
} }
@@ -25,7 +25,7 @@ import io.cucumber.java.en.When;
import java.io.IOException; import java.io.IOException;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import org.apache.fineract.client.models.BusinessDateData; import org.apache.fineract.client.models.BusinessDateResponse;
import org.apache.fineract.client.services.BusinessDateManagementApi; import org.apache.fineract.client.services.BusinessDateManagementApi;
import org.apache.fineract.test.helper.BusinessDateHelper; import org.apache.fineract.test.helper.BusinessDateHelper;
import org.apache.fineract.test.helper.ErrorHelper; import org.apache.fineract.test.helper.ErrorHelper;
@@ -53,7 +53,7 @@ public class BusinessDateStepDef extends AbstractStepDef {
@Then("Admin checks that the business date is correctly set to {string}") @Then("Admin checks that the business date is correctly set to {string}")
public void checkBusinessDate(String businessDate) throws IOException { public void checkBusinessDate(String businessDate) throws IOException {
Response<BusinessDateData> businessDateResponse = businessDateManagementApi.getBusinessDate(BusinessDateHelper.BUSINESS_DATE) Response<BusinessDateResponse> businessDateResponse = businessDateManagementApi.getBusinessDate(BusinessDateHelper.BUSINESS_DATE)
.execute(); .execute();
ErrorHelper.checkSuccessfulApiCall(businessDateResponse); ErrorHelper.checkSuccessfulApiCall(businessDateResponse);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy"); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d MMMM yyyy");
@@ -29,7 +29,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateData; import org.apache.fineract.client.models.BusinessDateResponse;
import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData; import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactions; import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
@@ -132,7 +132,7 @@ public class LoanChargeAdjustmentStepDef extends AbstractStepDef {
Long transactionId = getTransactionIdForTransactionMetConditions(transactionDate, transactionAmount, loanDetailsResponse); Long transactionId = getTransactionIdForTransactionMetConditions(transactionDate, transactionAmount, loanDetailsResponse);
Response<List<BusinessDateData>> businessDateResponse = businessDateManagementApi.getBusinessDates().execute(); Response<List<BusinessDateResponse>> businessDateResponse = businessDateManagementApi.getBusinessDates().execute();
LocalDate businessDate = businessDateResponse.body().get(0).getDate(); LocalDate businessDate = businessDateResponse.body().get(0).getDate();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
String businessDateActual = formatter.format(businessDate); String businessDateActual = formatter.format(businessDate);
@@ -61,7 +61,7 @@ import org.apache.fineract.avro.loan.v1.LoanChargePaidByDataV1;
import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1; import org.apache.fineract.avro.loan.v1.LoanStatusEnumDataV1;
import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1; import org.apache.fineract.avro.loan.v1.LoanTransactionDataV1;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.BusinessDateData; import org.apache.fineract.client.models.BusinessDateResponse;
import org.apache.fineract.client.models.DeleteLoansLoanIdResponse; import org.apache.fineract.client.models.DeleteLoansLoanIdResponse;
import org.apache.fineract.client.models.DisbursementDetail; import org.apache.fineract.client.models.DisbursementDetail;
import org.apache.fineract.client.models.GetLoanProductsChargeOffReasonOptions; import org.apache.fineract.client.models.GetLoanProductsChargeOffReasonOptions;
@@ -2579,7 +2579,7 @@ public class LoanStepDef extends AbstractStepDef {
// Only proceed with date check if catch-up is not running // Only proceed with date check if catch-up is not running
if (!statusResponse.body().getCatchUpRunning()) { if (!statusResponse.body().getCatchUpRunning()) {
// Get the current business date // Get the current business date
Response<BusinessDateData> businessDateResponse = businessDateApi.getBusinessDate(BusinessDateHelper.COB).execute(); Response<BusinessDateResponse> businessDateResponse = businessDateApi.getBusinessDate(BusinessDateHelper.COB).execute();
ErrorHelper.checkSuccessfulApiCall(businessDateResponse); ErrorHelper.checkSuccessfulApiCall(businessDateResponse);
LocalDate currentBusinessDate = businessDateResponse.body().getDate(); LocalDate currentBusinessDate = businessDateResponse.body().getDate();
+3 -1
View File
@@ -25,6 +25,8 @@ dependencies {
} }
implementation(project(path: ':fineract-core')) implementation(project(path: ':fineract-core'))
implementation(project(path: ':fineract-command'))
implementation(project(path: ':fineract-validation'))
implementation(project(path: ':fineract-accounting')) implementation(project(path: ':fineract-accounting'))
implementation(project(path: ':fineract-investor')) implementation(project(path: ':fineract-investor'))
implementation(project(path: ':fineract-rates')) implementation(project(path: ':fineract-rates'))
@@ -36,7 +38,6 @@ dependencies {
implementation(project(path: ':fineract-progressive-loan')) implementation(project(path: ':fineract-progressive-loan'))
implementation(project(path: ':fineract-report')) implementation(project(path: ':fineract-report'))
implementation(project(path: ':fineract-tax')) implementation(project(path: ':fineract-tax'))
implementation(project(path: ':fineract-command'))
providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
@@ -51,6 +52,7 @@ dependencies {
) )
implementation( implementation(
'org.springframework.boot:spring-boot-starter-web', 'org.springframework.boot:spring-boot-starter-web',
'org.springframework.boot:spring-boot-starter-validation',
'org.springframework.boot:spring-boot-starter-security', 'org.springframework.boot:spring-boot-starter-security',
'org.springframework.boot:spring-boot-starter-cache', 'org.springframework.boot:spring-boot-starter-cache',
'org.springframework.boot:spring-boot-starter-oauth2-resource-server', 'org.springframework.boot:spring-boot-starter-oauth2-resource-server',
@@ -28,8 +28,6 @@ import static org.springframework.security.web.util.matcher.AntPathRequestMatche
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.apache.fineract.commands.domain.CommandSourceRepository;
import org.apache.fineract.commands.service.CommandSourceService;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService; import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService; import org.apache.fineract.infrastructure.cache.service.CacheWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
@@ -48,7 +46,6 @@ import org.apache.fineract.infrastructure.security.filter.InsecureTwoFactorAuthe
import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter; import org.apache.fineract.infrastructure.security.filter.TenantAwareBasicAuthenticationFilter;
import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter; import org.apache.fineract.infrastructure.security.filter.TwoFactorAuthenticationFilter;
import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService; import org.apache.fineract.infrastructure.security.service.BasicAuthTenantDetailsService;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService; import org.apache.fineract.infrastructure.security.service.TenantAwareJpaPlatformUserDetailsService;
import org.apache.fineract.infrastructure.security.service.TwoFactorService; import org.apache.fineract.infrastructure.security.service.TwoFactorService;
import org.apache.fineract.notification.service.UserNotificationService; import org.apache.fineract.notification.service.UserNotificationService;
@@ -111,17 +108,11 @@ public class SecurityConfig {
@Autowired @Autowired
private MDCWrapper mdcWrapper; private MDCWrapper mdcWrapper;
@Autowired @Autowired
private CommandSourceRepository commandSourceRepository;
@Autowired
private CommandSourceService commandSourceService;
@Autowired
private FineractRequestContextHolder fineractRequestContextHolder; private FineractRequestContextHolder fineractRequestContextHolder;
@Autowired(required = false) @Autowired(required = false)
private LoanCOBFilterHelper loanCOBFilterHelper; private LoanCOBFilterHelper loanCOBFilterHelper;
@Autowired @Autowired
private PlatformSecurityContext context;
@Autowired
private IdempotencyStoreHelper idempotencyStoreHelper; private IdempotencyStoreHelper idempotencyStoreHelper;
@Bean @Bean
@@ -141,6 +132,12 @@ public class SecurityConfig {
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/echo")).permitAll() // .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/echo")).permitAll() //
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/authentication")).permitAll() // .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/authentication")).permitAll() //
.requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/instance-mode")).permitAll() // .requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/instance-mode")).permitAll() //
// businessdate
.requestMatchers(antMatcher(HttpMethod.GET, "/api/*/businessdate/*"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_BUSINESS_DATE") //
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/businessdate"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_BUSINESS_DATE") //
//
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated() // .requestMatchers(antMatcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated() //
.requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() // .requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() //
.requestMatchers(antMatcher("/api/**")) .requestMatchers(antMatcher("/api/**"))
@@ -46,6 +46,7 @@ public class JerseyConfig extends ResourceConfig {
bind(PageableParamProvider.class).to(ValueParamProvider.class).in(Singleton.class); bind(PageableParamProvider.class).to(ValueParamProvider.class).in(Singleton.class);
} }
}); });
register(org.glassfish.jersey.server.validation.ValidationFeature.class);
property(ServerProperties.WADL_FEATURE_DISABLE, true); property(ServerProperties.WADL_FEATURE_DISABLE, true);
} }
@@ -1,67 +0,0 @@
/**
* 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.jobs.service.increasedateby1day;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class IncreaseDateBy1DayServiceImpl implements IncreaseDateBy1DayService {
private final BusinessDateRepository businessDateRepository;
private final BusinessDateWritePlatformService businessDateWritePlatformService;
@Override
public void increaseDateByTypeByOneDay(BusinessDateType businessDateType) {
Map<String, Object> changes = new HashMap<>();
Optional<BusinessDate> businessDateEntity = businessDateRepository.findByType(businessDateType);
LocalDate businessDate = businessDateEntity.map(BusinessDate::getDate).orElse(DateUtils.getLocalDateOfTenant());
businessDate = businessDate.plusDays(1);
try {
BusinessDateData businessDateData = BusinessDateData.instance(businessDateType, businessDate);
businessDateWritePlatformService.adjustDate(businessDateData, changes);
} catch (final PlatformApiDataValidationException e) {
final List<ApiParameterError> errors = e.getErrors();
for (final ApiParameterError error : errors) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), error.getDeveloperMessage());
}
} catch (final AbstractPlatformDomainRuleException e) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), e.getDefaultUserMessage());
} catch (Exception e) {
log.error("Increasing {} by 1 day failed due to: {}", businessDateType.getDescription(), e.getMessage());
}
}
}
@@ -18,16 +18,14 @@
*/ */
package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.increasebusinessdateby1day; package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.increasebusinessdateby1day;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.JobName; import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.springframework.batch.core.Job; import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@@ -35,29 +33,17 @@ import org.springframework.transaction.PlatformTransactionManager;
@Configuration @Configuration
public class IncreaseBusinessDateBy1DayConfig { public class IncreaseBusinessDateBy1DayConfig {
@Autowired
private JobRepository jobRepository;
@Autowired
private PlatformTransactionManager transactionManager;
@Autowired
private IncreaseDateBy1DayService increaseDateBy1DayService;
@Autowired
private ConfigurationDomainService configurationDomainService;
@Bean @Bean
protected Step increaseBusinessDateBy1DayStep() { public IncreaseBusinessDateBy1DayTasklet increaseBusinessDateBy1DayTasklet(
return new StepBuilder(JobName.INCREASE_BUSINESS_DATE_BY_1_DAY.name(), jobRepository) BusinessDateWritePlatformService businessDateWritePlatformService, ConfigurationDomainService configurationDomainService) {
.tasklet(increaseBusinessDateBy1DayTasklet(), transactionManager).build(); return new IncreaseBusinessDateBy1DayTasklet(businessDateWritePlatformService, configurationDomainService);
} }
@Bean @Bean
public Job increaseBusinessDateBy1DayJob() { public Job increaseBusinessDateBy1DayJob(PlatformTransactionManager transactionManager, JobRepository jobRepository,
return new JobBuilder(JobName.INCREASE_BUSINESS_DATE_BY_1_DAY.name(), jobRepository).start(increaseBusinessDateBy1DayStep()) IncreaseBusinessDateBy1DayTasklet tasklet) {
return new JobBuilder(JobName.INCREASE_BUSINESS_DATE_BY_1_DAY.name(), jobRepository).start(
new StepBuilder(JobName.INCREASE_BUSINESS_DATE_BY_1_DAY.name(), jobRepository).tasklet(tasklet, transactionManager).build())
.incrementer(new RunIdIncrementer()).build(); .incrementer(new RunIdIncrementer()).build();
} }
@Bean
public IncreaseBusinessDateBy1DayTasklet increaseBusinessDateBy1DayTasklet() {
return new IncreaseBusinessDateBy1DayTasklet(increaseDateBy1DayService, configurationDomainService);
}
} }
@@ -21,8 +21,8 @@ package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.incre
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.scope.context.ChunkContext;
@@ -33,13 +33,13 @@ import org.springframework.batch.repeat.RepeatStatus;
@RequiredArgsConstructor @RequiredArgsConstructor
public class IncreaseBusinessDateBy1DayTasklet implements Tasklet { public class IncreaseBusinessDateBy1DayTasklet implements Tasklet {
private final IncreaseDateBy1DayService increaseDateBy1DayService; private final BusinessDateWritePlatformService businessDateWritePlatformService;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
@Override @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
if (configurationDomainService.isBusinessDateEnabled()) { if (configurationDomainService.isBusinessDateEnabled()) {
increaseDateBy1DayService.increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE); businessDateWritePlatformService.increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE);
} else { } else {
contribution.setExitStatus(ExitStatus.NOOP); contribution.setExitStatus(ExitStatus.NOOP);
} }
@@ -18,31 +18,28 @@
*/ */
package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.increasecobdateby1day; package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.increasecobdateby1day;
import lombok.RequiredArgsConstructor;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.JobName; import org.apache.fineract.infrastructure.jobs.service.JobName;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.springframework.batch.core.Job; import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step; import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder; import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer; import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder; import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
@Configuration @Configuration
@RequiredArgsConstructor
public class IncreaseCobDateBy1DayConfig { public class IncreaseCobDateBy1DayConfig {
@Autowired private final JobRepository jobRepository;
private JobRepository jobRepository; private final PlatformTransactionManager transactionManager;
@Autowired private final BusinessDateWritePlatformService businessDateWritePlatformService;
private PlatformTransactionManager transactionManager; private final ConfigurationDomainService configurationDomainService;
@Autowired
private IncreaseDateBy1DayService increaseDateBy1DayService;
@Autowired
private ConfigurationDomainService configurationDomainService;
@Bean @Bean
protected Step increaseCobDateBy1DayStep() { protected Step increaseCobDateBy1DayStep() {
@@ -58,6 +55,6 @@ public class IncreaseCobDateBy1DayConfig {
@Bean @Bean
public IncreaseCobDateBy1DayTasklet increaseCobDateBy1DayTasklet() { public IncreaseCobDateBy1DayTasklet increaseCobDateBy1DayTasklet() {
return new IncreaseCobDateBy1DayTasklet(increaseDateBy1DayService, configurationDomainService); return new IncreaseCobDateBy1DayTasklet(businessDateWritePlatformService, configurationDomainService);
} }
} }
@@ -21,8 +21,8 @@ package org.apache.fineract.infrastructure.jobs.service.increasedateby1day.incre
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.scope.context.ChunkContext; import org.springframework.batch.core.scope.context.ChunkContext;
@@ -33,13 +33,13 @@ import org.springframework.batch.repeat.RepeatStatus;
@RequiredArgsConstructor @RequiredArgsConstructor
public class IncreaseCobDateBy1DayTasklet implements Tasklet { public class IncreaseCobDateBy1DayTasklet implements Tasklet {
private final IncreaseDateBy1DayService increaseDateBy1DayService; private final BusinessDateWritePlatformService businessDateWritePlatformService;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
@Override @Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
if (configurationDomainService.isBusinessDateEnabled()) { if (configurationDomainService.isBusinessDateEnabled()) {
increaseDateBy1DayService.increaseDateByTypeByOneDay(BusinessDateType.COB_DATE); businessDateWritePlatformService.increaseDateByTypeByOneDay(BusinessDateType.COB_DATE);
} else { } else {
contribution.setExitStatus(ExitStatus.NOOP); contribution.setExitStatus(ExitStatus.NOOP);
} }
@@ -1,141 +0,0 @@
/**
* 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.businessdate.api;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import java.util.List;
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.data.request.BusinessDateRequest;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.security.exception.NoAuthorizationException;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.useradministration.domain.AppUser;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
class BusinessDateApiTest {
@Mock
private BusinessDateReadPlatformService readPlatformService;
@Mock
private PlatformSecurityContext securityContext;
@Mock
private DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer;
@Mock
private PortfolioCommandSourceWritePlatformService commandWritePlatformService;
@InjectMocks
private BusinessDateApiResource underTest;
@Test
void getBusinessDatesAPIHasPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
List<BusinessDateData> response = Mockito.mock(List.class);
given(readPlatformService.findAll()).willReturn(response);
// given
Mockito.doNothing().when(appUser).validateHasReadPermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
// when
underTest.getBusinessDates();
// then
verify(readPlatformService, Mockito.times(1)).findAll();
}
@Test
void getBusinessDatesAPIHasNoPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
// given
Mockito.doThrow(NoAuthorizationException.class).when(appUser).validateHasReadPermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
// when
assertThatThrownBy(() -> underTest.getBusinessDates()).isInstanceOf(NoAuthorizationException.class);
// then
verifyNoInteractions(readPlatformService);
}
@Test
void getBusinessDateByTypeAPIHasPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
BusinessDateData response = Mockito.mock(BusinessDateData.class);
given(readPlatformService.findByType("type")).willReturn(response);
// given
Mockito.doNothing().when(appUser).validateHasReadPermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
// when
underTest.getBusinessDate("type");
// then
verify(readPlatformService, Mockito.times(1)).findByType("type");
}
@Test
void getBusinessDateByTypeAPIHasNoPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
// given
Mockito.doThrow(NoAuthorizationException.class).when(appUser).validateHasReadPermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
// when
assertThatThrownBy(() -> underTest.getBusinessDate("type")).isInstanceOf(NoAuthorizationException.class);
// then
verifyNoInteractions(readPlatformService);
}
@Test
void postBusinessDateAPIHasPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
CommandProcessingResult response = Mockito.mock(CommandProcessingResult.class);
// given
Mockito.doNothing().when(appUser).validateHasUpdatePermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
given(commandWritePlatformService.logCommandSource(Mockito.any())).willReturn(response);
// when
underTest.updateBusinessDate(BusinessDateRequest.ofNull());
// then
verify(commandWritePlatformService, Mockito.times(1)).logCommandSource(Mockito.any());
}
@Test
void postBusinessDateAPIHasNoPermission() {
AppUser appUser = Mockito.mock(AppUser.class);
// given
Mockito.doThrow(NoAuthorizationException.class).when(appUser).validateHasUpdatePermission("BUSINESS_DATE");
given(securityContext.authenticatedUser()).willReturn(appUser);
// when
assertThatThrownBy(() -> underTest.updateBusinessDate(BusinessDateRequest.ofNull())).isInstanceOf(NoAuthorizationException.class);
// then
verifyNoInteractions(readPlatformService);
}
}
@@ -1,60 +0,0 @@
/**
* 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.businessdate.data;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate;
import java.time.ZoneId;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.serialization.CommandProcessingResultJsonSerializer;
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.apache.fineract.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
import org.junit.jupiter.api.Test;
public class BusinessDataSerialized {
@Test
public void serializeBusinessDateData() {
DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer = new DefaultToApiJsonSerializer<>(
new ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson(), new CommandProcessingResultJsonSerializer(),
new GoogleGsonSerializerHelper());
LocalDate now = LocalDate.now(ZoneId.systemDefault());
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, now);
String result = jsonSerializer.serialize(businessDateData);
assertEquals("{\"description\":\"Business Date\",\"type\":\"BUSINESS_DATE\",\"date\":[" + now.getYear() + "," + now.getMonthValue()
+ "," + now.getDayOfMonth() + "]}", result);
}
@Test
public void serializeBusinessDateData_COB() {
DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer = new DefaultToApiJsonSerializer<>(
new ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson(), new CommandProcessingResultJsonSerializer(),
new GoogleGsonSerializerHelper());
LocalDate now = LocalDate.now(ZoneId.systemDefault());
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.COB_DATE, now);
String result = jsonSerializer.serialize(businessDateData);
assertEquals("{\"description\":\"Close of Business Date\",\"type\":\"COB_DATE\",\"date\":[" + now.getYear() + ","
+ now.getMonthValue() + "," + now.getDayOfMonth() + "]}", result);
}
}
@@ -23,11 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
public class BusinessDataTypeTest { class BusinessDataTypeTest {
@Test @Test
public void typoCheck() { void typoCheck() {
for (BusinessDateType businessDateType : BusinessDateType.values()) { for (var businessDateType : BusinessDateType.values()) {
switch (businessDateType) { switch (businessDateType) {
case BUSINESS_DATE -> assertEquals("Business Date", businessDateType.getDescription()); case BUSINESS_DATE -> assertEquals("Business Date", businessDateType.getDescription());
case COB_DATE -> assertEquals("Close of Business Date", businessDateType.getDescription()); case COB_DATE -> assertEquals("Close of Business Date", businessDateType.getDescription());
@@ -0,0 +1,60 @@
/**
* 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.businessdate.data;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.LocalDate;
import java.time.ZoneId;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.junit.jupiter.api.Test;
class BusinessDateSerializationTest {
private final ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule())
.setSerializationInclusion(JsonInclude.Include.NON_NULL);
@Test
void serializeBusinessDateData() throws JsonProcessingException {
var now = LocalDate.now(ZoneId.systemDefault());
var businessDateResponse = BusinessDateResponse.builder().type(BusinessDateType.BUSINESS_DATE)
.description(BusinessDateType.BUSINESS_DATE.getDescription()).date(now).build();
var result = mapper.writeValueAsString(businessDateResponse);
assertEquals("{\"description\":\"Business Date\",\"type\":\"BUSINESS_DATE\",\"date\":[" + now.getYear() + "," + now.getMonthValue()
+ "," + now.getDayOfMonth() + "]}", result);
}
@Test
void serializeBusinessDateData_COB() throws JsonProcessingException {
var now = LocalDate.now(ZoneId.systemDefault());
var businessDateResponse = BusinessDateResponse.builder().type(BusinessDateType.COB_DATE)
.description(BusinessDateType.COB_DATE.getDescription()).date(now).build();
var result = mapper.writeValueAsString(businessDateResponse);
assertEquals("{\"description\":\"Close of Business Date\",\"type\":\"COB_DATE\",\"date\":[" + now.getYear() + ","
+ now.getMonthValue() + "," + now.getDayOfMonth() + "]}", result);
}
}
@@ -23,34 +23,32 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
public class BusinessDateMapperTest { class BusinessDateUpdateRequestMapperTest {
private BusinessDateMapper businessDateMapper = Mappers.getMapper(BusinessDateMapper.class); private final BusinessDateMapper businessDateMapper = Mappers.getMapper(BusinessDateMapper.class);
@Test @Test
public void testMapping() { void testMapping() {
LocalDate now = LocalDate.now(ZoneId.systemDefault()); var now = LocalDate.now(ZoneId.systemDefault());
BusinessDate businessDate = BusinessDate.instance(BusinessDateType.BUSINESS_DATE, now); var businessDate = BusinessDate.instance(BusinessDateType.BUSINESS_DATE, now);
BusinessDateData businessDateData = businessDateMapper.map(businessDate); var businessDateResponse = businessDateMapper.map(businessDate);
assertEquals(businessDate.getDate(), businessDateData.getDate()); assertEquals(businessDate.getDate(), businessDateResponse.getDate());
assertEquals(businessDate.getType().getDescription(), businessDateData.getDescription()); assertEquals(businessDate.getType().getDescription(), businessDateResponse.getDescription());
assertEquals(businessDate.getType().getName(), businessDateData.getType()); assertEquals(businessDate.getType(), businessDateResponse.getType());
} }
@Test @Test
public void testMappingList() { void testMappingList() {
LocalDate now = LocalDate.now(ZoneId.systemDefault()); var now = LocalDate.now(ZoneId.systemDefault());
BusinessDate businessDate = BusinessDate.instance(BusinessDateType.BUSINESS_DATE, now); var businessDate = BusinessDate.instance(BusinessDateType.BUSINESS_DATE, now);
List<BusinessDateData> businessDateData = businessDateMapper.map(Collections.singletonList(businessDate)); var businessDateData = businessDateMapper.map(Collections.singletonList(businessDate));
assertEquals(businessDate.getDate(), businessDateData.get(0).getDate()); assertEquals(businessDate.getDate(), businessDateData.get(0).getDate());
assertEquals(businessDate.getType().getDescription(), businessDateData.get(0).getDescription()); assertEquals(businessDate.getType().getDescription(), businessDateData.get(0).getDescription());
assertEquals(businessDate.getType().getName(), businessDateData.get(0).getType()); assertEquals(businessDate.getType(), businessDateData.get(0).getType());
} }
} }
@@ -51,7 +51,7 @@ public class BusinessDateReadPlatformServiceTest {
private BusinessDateRepository repository; private BusinessDateRepository repository;
@Mock @Mock
private BusinessDateMapper mapper; private BusinessDateMapper businessDateMapper;
@Test @Test
public void notFoundByTypeNonexistentType() { public void notFoundByTypeNonexistentType() {
@@ -73,7 +73,7 @@ public class BusinessDateReadPlatformServiceTest {
given(repository.findAll()).willReturn(resultList); given(repository.findAll()).willReturn(resultList);
businessDateReadPlatformService.findAll(); businessDateReadPlatformService.findAll();
verify(repository, times(1)).findAll(); verify(repository, times(1)).findAll();
verify(mapper, times(1)).map(resultList); verify(businessDateMapper, times(1)).map(resultList);
} }
@Test @Test
@@ -82,7 +82,7 @@ public class BusinessDateReadPlatformServiceTest {
given(repository.findByType(BusinessDateType.COB_DATE)).willReturn(result); given(repository.findByType(BusinessDateType.COB_DATE)).willReturn(result);
businessDateReadPlatformService.findByType("COB_DATE"); businessDateReadPlatformService.findByType("COB_DATE");
verify(repository, times(1)).findByType(BusinessDateType.COB_DATE); verify(repository, times(1)).findByType(BusinessDateType.COB_DATE);
verify(mapper, times(1)).map(result.get()); verify(businessDateMapper, times(1)).map(result.get());
} }
@Test @Test
@@ -91,6 +91,6 @@ public class BusinessDateReadPlatformServiceTest {
given(repository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(result); given(repository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(result);
businessDateReadPlatformService.findByType("BUSINESS_DATE"); businessDateReadPlatformService.findByType("BUSINESS_DATE");
verify(repository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(repository, times(1)).findByType(BusinessDateType.BUSINESS_DATE);
verify(mapper, times(1)).map(result.get()); verify(businessDateMapper, times(1)).map(result.get());
} }
} }
@@ -18,6 +18,8 @@
*/ */
package org.apache.fineract.infrastructure.businessdate.service; package org.apache.fineract.infrastructure.businessdate.service;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.COB_DATE;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -27,17 +29,17 @@ import static org.mockito.Mockito.verify;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData; import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDate;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateRepository;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateActionException; import org.apache.fineract.infrastructure.businessdate.exception.BusinessDateActionException;
import org.apache.fineract.infrastructure.businessdate.validator.BusinessDateDataParserAndValidator; import org.apache.fineract.infrastructure.businessdate.mapper.BusinessDateUpdateRequestMapper;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
@@ -64,7 +66,7 @@ public class BusinessDateWritePlatformServiceTest {
private BusinessDateWritePlatformServiceImpl underTest; private BusinessDateWritePlatformServiceImpl underTest;
@Mock @Mock
private BusinessDateDataParserAndValidator businessDateDataParserAndValidator; private BusinessDateUpdateRequestMapper updateBusinessDateMapper;
@Mock @Mock
private BusinessDateRepository businessDateRepository; private BusinessDateRepository businessDateRepository;
@@ -87,163 +89,180 @@ public class BusinessDateWritePlatformServiceTest {
@Test @Test
public void businessDateIsNotEnabled() { public void businessDateIsNotEnabled() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE,
LocalDate.now(ZoneId.systemDefault()));
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData);
BusinessDateActionException exception = assertThrows(BusinessDateActionException.class, BusinessDateActionException exception = assertThrows(BusinessDateActionException.class,
() -> underTest.updateBusinessDate(command)); () -> underTest.updateBusinessDate(businessDateUpdateRequest));
assertEquals("Business date functionality is not enabled", exception.getDefaultUserMessage()); assertEquals("Business date functionality is not enabled", exception.getDefaultUserMessage());
} }
@Test @Test
public void businessDateSetNew() { public void businessDateSetNew() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)); final LocalDate localDate = LocalDate.of(2022, 6, 13);
final Map<BusinessDateType, LocalDate> changes = new HashMap<>(Map.of(BUSINESS_DATE, localDate));
BusinessDateResponse businessDateRes = BusinessDateResponse.builder().type(BUSINESS_DATE)
.description(BUSINESS_DATE.getDescription()).date(localDate).changes(changes).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(businessDateUpdateRequest)).willReturn(businessDateRes);
Optional<BusinessDate> newEntity = Optional.empty(); Optional<BusinessDate> newEntity = Optional.empty();
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(businessDateUpdateRequest);
LocalDate resultData = (LocalDate) result.getChanges().get("BUSINESS_DATE"); final LocalDate resultDate = result.getChanges().get(BUSINESS_DATE);
assertEquals(LocalDate.of(2022, 6, 13), resultData); assertEquals(LocalDate.of(2022, 6, 13), resultDate);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture());
assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate()); assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate());
assertEquals(BusinessDateType.BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType()); assertEquals(BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType());
} }
@Test @Test
public void cobDateSetNew() { public void cobDateSetNew() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.COB_DATE, LocalDate.of(2022, 6, 13)); final LocalDate localDate = LocalDate.of(2022, 6, 13);
final Map<BusinessDateType, LocalDate> changes = new HashMap<>(Map.of(COB_DATE, localDate));
BusinessDateResponse response = BusinessDateResponse.builder().type(COB_DATE).description(COB_DATE.getDescription()).date(localDate)
.changes(changes).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(businessDateUpdateRequest)).willReturn(response);
Optional<BusinessDate> newEntity = Optional.empty(); Optional<BusinessDate> newEntity = Optional.empty();
given(businessDateRepository.findByType(BusinessDateType.COB_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(COB_DATE)).willReturn(newEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(businessDateUpdateRequest);
LocalDate resultData = (LocalDate) result.getChanges().get("COB_DATE"); LocalDate resultData = result.getChanges().get(COB_DATE);
assertEquals(LocalDate.of(2022, 6, 13), resultData); assertEquals(LocalDate.of(2022, 6, 13), resultData);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.COB_DATE); verify(businessDateRepository, times(1)).findByType(COB_DATE);
verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture());
assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate()); assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate());
assertEquals(BusinessDateType.COB_DATE, businessDateArgumentCaptor.getValue().getType()); assertEquals(COB_DATE, businessDateArgumentCaptor.getValue().getType());
} }
@Test @Test
public void businessDateSetModifyExistingWhenItWasAfter() { public void businessDateSetModifyExistingWhenItWasAfter() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 11)); final LocalDate localDate = LocalDate.of(2022, 6, 11);
final Map<BusinessDateType, LocalDate> changes = new HashMap<>(Map.of(COB_DATE, localDate));
BusinessDateResponse response = BusinessDateResponse.builder().type(BUSINESS_DATE).description(BUSINESS_DATE.getDescription())
.date(localDate).changes(changes).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(businessDateUpdateRequest)).willReturn(response);
Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 12))); Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BUSINESS_DATE, LocalDate.of(2022, 6, 12)));
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(businessDateUpdateRequest);
LocalDate resultData = (LocalDate) result.getChanges().get("BUSINESS_DATE"); LocalDate resultData = result.getChanges().get(BUSINESS_DATE);
assertEquals(LocalDate.of(2022, 6, 11), resultData); assertEquals(LocalDate.of(2022, 6, 11), resultData);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture());
assertEquals(LocalDate.of(2022, 6, 11), businessDateArgumentCaptor.getValue().getDate()); assertEquals(LocalDate.of(2022, 6, 11), businessDateArgumentCaptor.getValue().getDate());
assertEquals(BusinessDateType.BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType()); assertEquals(BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType());
} }
@Test @Test
public void businessDateSetModifyExistingWhenItWasBefore() { public void businessDateSetModifyExistingWhenItWasBefore() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)); final LocalDate localDate = LocalDate.of(2022, 6, 13);
final Map<BusinessDateType, LocalDate> changes = new HashMap<>(Map.of(BUSINESS_DATE, localDate));
BusinessDateResponse response = BusinessDateResponse.builder().type(BUSINESS_DATE).description(BUSINESS_DATE.getDescription())
.date(localDate).changes(changes).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(businessDateUpdateRequest)).willReturn(response);
Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 12))); Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BUSINESS_DATE, LocalDate.of(2022, 6, 12)));
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(businessDateUpdateRequest);
LocalDate resultData = (LocalDate) result.getChanges().get("BUSINESS_DATE"); LocalDate resultData = result.getChanges().get(BUSINESS_DATE);
assertEquals(LocalDate.of(2022, 6, 13), resultData); assertEquals(LocalDate.of(2022, 6, 13), resultData);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture());
assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate()); assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getValue().getDate());
assertEquals(BusinessDateType.BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType()); assertEquals(BUSINESS_DATE, businessDateArgumentCaptor.getValue().getType());
} }
@Test @Test
public void businessDateSetModifyExistingButNoChanges() { public void businessDateSetModifyExistingButNoChanges() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest businessDateUpdateRequest = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)); final LocalDate localDate = LocalDate.of(2022, 6, 13);
BusinessDateResponse response = BusinessDateResponse.builder().type(BUSINESS_DATE).description(BUSINESS_DATE.getDescription())
.date(localDate).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.FALSE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(businessDateUpdateRequest)).willReturn(response);
Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)));
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); Optional<BusinessDate> newEntity = Optional.of(BusinessDate.instance(BUSINESS_DATE, LocalDate.of(2022, 6, 13)));
CommandProcessingResult result = underTest.updateBusinessDate(command); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
BusinessDateResponse result = underTest.updateBusinessDate(businessDateUpdateRequest);
assertNull(result.getChanges()); assertNull(result.getChanges());
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(0)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(0)).save(businessDateArgumentCaptor.capture());
} }
@Test @Test
public void cobDateSetNewAutomatically() { public void cobDateSetNewAutomatically() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest request = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)); final LocalDate localDate = LocalDate.of(2022, 6, 13);
final Map<BusinessDateType, LocalDate> changes = new HashMap<>(Map.of(BUSINESS_DATE, localDate));
BusinessDateResponse response = BusinessDateResponse.builder().type(BUSINESS_DATE).description(BUSINESS_DATE.getDescription())
.date(localDate).changes(changes).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(request)).willReturn(response);
Optional<BusinessDate> newEntity = Optional.empty(); Optional<BusinessDate> newEntity = Optional.empty();
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(request);
LocalDate businessDate = (LocalDate) result.getChanges().get("BUSINESS_DATE"); LocalDate businessDate = result.getChanges().get(BUSINESS_DATE);
assertEquals(LocalDate.of(2022, 6, 13), businessDate); assertEquals(LocalDate.of(2022, 6, 13), businessDate);
LocalDate cobDate = (LocalDate) result.getChanges().get("COB_DATE"); LocalDate cobDate = result.getChanges().get(COB_DATE);
assertEquals(LocalDate.of(2022, 6, 12), cobDate); assertEquals(LocalDate.of(2022, 6, 12), cobDate);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(1)).findByType(BusinessDateType.COB_DATE); verify(businessDateRepository, times(1)).findByType(COB_DATE);
verify(businessDateRepository, times(2)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(2)).save(businessDateArgumentCaptor.capture());
assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getAllValues().get(0).getDate()); assertEquals(LocalDate.of(2022, 6, 13), businessDateArgumentCaptor.getAllValues().get(0).getDate());
assertEquals(BusinessDateType.BUSINESS_DATE, businessDateArgumentCaptor.getAllValues().get(0).getType()); assertEquals(BUSINESS_DATE, businessDateArgumentCaptor.getAllValues().get(0).getType());
assertEquals(LocalDate.of(2022, 6, 12), businessDateArgumentCaptor.getAllValues().get(1).getDate()); assertEquals(LocalDate.of(2022, 6, 12), businessDateArgumentCaptor.getAllValues().get(1).getDate());
assertEquals(BusinessDateType.COB_DATE, businessDateArgumentCaptor.getAllValues().get(1).getType()); assertEquals(COB_DATE, businessDateArgumentCaptor.getAllValues().get(1).getType());
} }
@Test @Test
public void businessDateAndCobDateSetModifyExistingButNoChanges() { public void businessDateAndCobDateSetModifyExistingButNoChanges() {
JsonCommand command = JsonCommand.from(""); BusinessDateUpdateRequest request = new BusinessDateUpdateRequest();
BusinessDateData businessDateData = BusinessDateData.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13)); BusinessDateResponse response = BusinessDateResponse.builder().type(BUSINESS_DATE).description(BUSINESS_DATE.getDescription())
.date(LocalDate.of(2022, 6, 13)).build();
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE);
given(businessDateDataParserAndValidator.validateAndParseUpdate(command)).willReturn(businessDateData); given(updateBusinessDateMapper.map(request)).willReturn(response);
Optional<BusinessDate> newBusinessEntity = Optional
.of(BusinessDate.instance(BusinessDateType.BUSINESS_DATE, LocalDate.of(2022, 6, 13))); Optional<BusinessDate> newBusinessEntity = Optional.of(BusinessDate.instance(BUSINESS_DATE, LocalDate.of(2022, 6, 13)));
Optional<BusinessDate> newCOBEntity = Optional.of(BusinessDate.instance(BusinessDateType.COB_DATE, LocalDate.of(2022, 6, 12))); Optional<BusinessDate> newCOBEntity = Optional.of(BusinessDate.instance(COB_DATE, LocalDate.of(2022, 6, 12)));
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newBusinessEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newBusinessEntity);
given(businessDateRepository.findByType(BusinessDateType.COB_DATE)).willReturn(newCOBEntity); given(businessDateRepository.findByType(COB_DATE)).willReturn(newCOBEntity);
CommandProcessingResult result = underTest.updateBusinessDate(command); BusinessDateResponse result = underTest.updateBusinessDate(request);
assertNull(result.getChanges()); assertNull(result.getChanges());
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).findByType(BusinessDateType.BUSINESS_DATE); verify(businessDateRepository, times(1)).findByType(BUSINESS_DATE);
verify(businessDateRepository, times(1)).findByType(BusinessDateType.COB_DATE); verify(businessDateRepository, times(1)).findByType(COB_DATE);
verify(businessDateRepository, times(0)).save(Mockito.any()); verify(businessDateRepository, times(0)).save(Mockito.any());
} }
@Test @Test
public void businessDateIsNotEnabledTriggeredByJob() { public void businessDateIsNotEnabledTriggeredByJob() {
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.FALSE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.FALSE);
assertThrows(JobExecutionException.class, () -> underTest.increaseBusinessDateByOneDay()); assertThrows(JobExecutionException.class, () -> underTest.increaseDateByTypeByOneDay(BUSINESS_DATE));
} }
@Test @Test
@@ -253,25 +272,25 @@ public class BusinessDateWritePlatformServiceTest {
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE);
Optional<BusinessDate> newEntity = Optional.empty(); Optional<BusinessDate> newEntity = Optional.empty();
given(businessDateRepository.findByType(BusinessDateType.BUSINESS_DATE)).willReturn(newEntity); given(businessDateRepository.findByType(BUSINESS_DATE)).willReturn(newEntity);
underTest.increaseBusinessDateByOneDay(); underTest.increaseDateByTypeByOneDay(BUSINESS_DATE);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(2)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(2)).save(businessDateArgumentCaptor.capture());
assertEquals(localDatePlus1, businessDateArgumentCaptor.getAllValues().get(0).getDate()); assertEquals(localDatePlus1, businessDateArgumentCaptor.getAllValues().get(0).getDate());
assertEquals(BusinessDateType.BUSINESS_DATE, businessDateArgumentCaptor.getAllValues().get(0).getType()); assertEquals(BUSINESS_DATE, businessDateArgumentCaptor.getAllValues().get(0).getType());
assertEquals(localDate, businessDateArgumentCaptor.getAllValues().get(1).getDate()); assertEquals(localDate, businessDateArgumentCaptor.getAllValues().get(1).getDate());
assertEquals(BusinessDateType.COB_DATE, businessDateArgumentCaptor.getAllValues().get(1).getType()); assertEquals(COB_DATE, businessDateArgumentCaptor.getAllValues().get(1).getType());
} }
@Test @Test
public void cobDateModifyExistingTriggeredByJob() throws JobExecutionException { public void cobDateModifyExistingTriggeredByJob() throws JobExecutionException {
Optional<BusinessDate> newCOBEntity = Optional.of(BusinessDate.instance(BusinessDateType.COB_DATE, LocalDate.of(2022, 6, 12))); Optional<BusinessDate> newCOBEntity = Optional.of(BusinessDate.instance(COB_DATE, LocalDate.of(2022, 6, 12)));
given(businessDateRepository.findByType(BusinessDateType.COB_DATE)).willReturn(newCOBEntity); given(businessDateRepository.findByType(COB_DATE)).willReturn(newCOBEntity);
LocalDate localDate = LocalDate.of(2022, 6, 12).plusDays(1); LocalDate localDate = LocalDate.of(2022, 6, 12).plusDays(1);
given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isBusinessDateEnabled()).willReturn(Boolean.TRUE);
given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE); given(configurationDomainService.isCOBDateAdjustmentEnabled()).willReturn(Boolean.TRUE);
underTest.increaseCOBDateByOneDay(); underTest.increaseDateByTypeByOneDay(COB_DATE);
verify(configurationDomainService, times(1)).isBusinessDateEnabled(); verify(configurationDomainService, times(1)).isBusinessDateEnabled();
verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled(); verify(configurationDomainService, times(1)).isCOBDateAdjustmentEnabled();
verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture()); verify(businessDateRepository, times(1)).save(businessDateArgumentCaptor.capture());
@@ -0,0 +1,88 @@
/**
* 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.businessdate.validation;
import static org.assertj.core.api.Assertions.assertThat;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.validation.config.ValidationConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.validation.Validator;
@Slf4j
@SpringBootTest
@ContextConfiguration(classes = { ValidationConfig.class })
class BusinessDateValidationTest {
@Autowired
private Validator validator;
@Test
void invalidAllBlank() {
var request = BusinessDateUpdateRequest.builder().dateFormat("").type(null).date(" ").locale(null).build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(5);
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("date"));
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("dateFormat"));
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("type"));
}
@Test
void invalidLocale() {
var request = BusinessDateUpdateRequest.builder().dateFormat("dd-MM-yyyy").type(BusinessDateType.BUSINESS_DATE).date("12-05-2025")
.locale("EN").build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(1);
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
}
@Test
void invalidDateFormat() {
var request = BusinessDateUpdateRequest.builder().dateFormat("dd/MM/yyyy").type(BusinessDateType.BUSINESS_DATE).date("12-05-2025")
.locale("en").build();
var errors = validator.validateObject(request);
assertThat(errors.getErrorCount()).isEqualTo(1);
assertThat(errors.getAllErrors()).anyMatch(e -> "Wrong local date fields.".equals(e.getDefaultMessage()));
}
@Test
void valid() {
var request = BusinessDateUpdateRequest.builder().dateFormat("dd-MM-yyyy").type(BusinessDateType.BUSINESS_DATE).date("12-05-2025")
.locale("en").build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(0);
}
}
@@ -1,120 +0,0 @@
/**
* 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.businessdate.validator;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.time.LocalDate;
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.junit.jupiter.api.Test;
public class BusinessDateValidatorTest {
private BusinessDateDataParserAndValidator businessDateDataParserAndValidator = new BusinessDateDataParserAndValidator(
new FromJsonHelper());
@Test
public void validateAndParseUpdateWithEmptyRequest() {
String json = "{}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals(
"PlatformApiDataValidationException{errors=[The parameter `type` is mandatory., The parameter `locale` is mandatory., The parameter `dateFormat` is mandatory., The parameter `date` is mandatory.]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithBlankFieldsInRequest() {
String json = "{\"type\":\"\", \"locale\":\"\",\"dateFormat\":\"\",\"date\":\"\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals(
"PlatformApiDataValidationException{errors=[The parameter `type` is mandatory., The parameter `locale` is mandatory., The parameter `dateFormat` is mandatory., The parameter `date` is mandatory.]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithInvalidLocale() {
String json = "{\"type\":\"BUSINESS_DATE\", \"locale\":\"invalid\",\"dateFormat\":\"yyyy-MM-dd\",\"date\":\"2022-06-11\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals("PlatformApiDataValidationException{errors=[The parameter `locale` has an invalid language value invalid .]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithInvalidBusinessType() {
String json = "{\"type\":\"invalid\", \"locale\":\"hu\",\"dateFormat\":\"yyyy-MM-dd\",\"date\":\"2022-06-11\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals("PlatformApiDataValidationException{errors=[Failed data validation due to: Invalid Business Type value: `invalid`.]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithInvalidDateFormat() {
String json = "{\"type\":\"BUSINESS_DATE\", \"locale\":\"hu\",\"dateFormat\":\"y2yyy-MM-dd\",\"date\":\"2022-06-11\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals(
"PlatformApiDataValidationException{errors=[The parameter `date` is invalid based on the dateFormat: `y2yyy-MM-dd` and locale: `hu` provided:]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithInvalidDate() {
String json = "{\"type\":\"BUSINESS_DATE\", \"locale\":\"hu\",\"dateFormat\":\"yyyy-MM-dd\",\"date\":\"2y22-06-11\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals(
"PlatformApiDataValidationException{errors=[The parameter `date` is invalid based on the dateFormat: `yyyy-MM-dd` and locale: `hu` provided:]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithWrongDate() {
String json = "{\"type\":\"BUSINESS_DATE\", \"locale\":\"hu\",\"dateFormat\":\"yyyy-MM-dd\",\"date\":\"11-06-2022\"}";
JsonCommand command = JsonCommand.from(json);
PlatformApiDataValidationException exception = assertThrows(PlatformApiDataValidationException.class,
() -> businessDateDataParserAndValidator.validateAndParseUpdate(command));
assertEquals(
"PlatformApiDataValidationException{errors=[The parameter `date` is invalid based on the dateFormat: `yyyy-MM-dd` and locale: `hu` provided:]}",
exception.toString());
}
@Test
public void validateAndParseUpdateWithRightDate() {
String json = "{\"type\":\"COB_DATE\", \"locale\":\"hu\",\"dateFormat\":\"yyyy-MM-dd\",\"date\":\"2022-06-11\"}";
JsonCommand command = JsonCommand.from(json);
BusinessDateData result = businessDateDataParserAndValidator.validateAndParseUpdate(command);
assertEquals("COB_DATE", result.getType());
assertEquals("Close of Business Date", result.getDescription());
assertEquals(LocalDate.of(2022, 6, 11), result.getDate());
}
}
@@ -24,8 +24,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
@@ -52,7 +52,7 @@ class IncreaseBusinessDateBy1DayTaskletTest {
private ConfigurationDomainService configurationDomainService; private ConfigurationDomainService configurationDomainService;
@Mock @Mock
private IncreaseDateBy1DayService increaseDateBy1DayService; private BusinessDateWritePlatformService businessDateWritePlatformService;
@InjectMocks @InjectMocks
private IncreaseBusinessDateBy1DayTasklet underTest; private IncreaseBusinessDateBy1DayTasklet underTest;
@@ -73,7 +73,7 @@ class IncreaseBusinessDateBy1DayTaskletTest {
RepeatStatus repeatStatus = underTest.execute(stepContribution, chunkContext); RepeatStatus repeatStatus = underTest.execute(stepContribution, chunkContext);
verify(increaseDateBy1DayService, times(1)).increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE); verify(businessDateWritePlatformService, times(1)).increaseDateByTypeByOneDay(BusinessDateType.BUSINESS_DATE);
assertEquals(RepeatStatus.FINISHED, repeatStatus); assertEquals(RepeatStatus.FINISHED, repeatStatus);
} }
@@ -24,8 +24,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateWritePlatformService;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.jobs.service.increasedateby1day.IncreaseDateBy1DayService;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
@@ -52,7 +52,7 @@ class IncreaseCobDateBy1DayTaskletTest {
private ConfigurationDomainService configurationDomainService; private ConfigurationDomainService configurationDomainService;
@Mock @Mock
private IncreaseDateBy1DayService increaseDateBy1DayService; private BusinessDateWritePlatformService businessDateWritePlatformService;
@InjectMocks @InjectMocks
private IncreaseCobDateBy1DayTasklet underTest; private IncreaseCobDateBy1DayTasklet underTest;
@@ -73,7 +73,7 @@ class IncreaseCobDateBy1DayTaskletTest {
RepeatStatus repeatStatus = underTest.execute(stepContribution, chunkContext); RepeatStatus repeatStatus = underTest.execute(stepContribution, chunkContext);
verify(increaseDateBy1DayService, times(1)).increaseDateByTypeByOneDay(BusinessDateType.COB_DATE); verify(businessDateWritePlatformService, times(1)).increaseDateByTypeByOneDay(BusinessDateType.COB_DATE);
assertEquals(RepeatStatus.FINISHED, repeatStatus); assertEquals(RepeatStatus.FINISHED, repeatStatus);
} }
@@ -16,17 +16,25 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.fineract.infrastructure.businessdate.data.request; description = 'Fineract Validation'
import java.io.Serial; apply plugin: 'java'
import java.io.Serializable; apply plugin: 'eclipse'
public record BusinessDateRequest(String dateFormat, String type, String date, String locale) implements Serializable { apply from: 'dependencies.gradle'
@Serial // If we are running Gradle within Eclipse to enhance classes with OpenJPA,
private static final long serialVersionUID = 1L; // set the classes directory to point to Eclipse's default build directory
if (project.hasProperty('env') && project.getProperty('env') == 'eclipse') {
sourceSets.main.java.outputDir = new File(rootProject.projectDir, "fineract-validation/bin/main")
}
public static BusinessDateRequest ofNull() { if (!(project.hasProperty('env') && project.getProperty('env') == 'dev')) {
return new BusinessDateRequest(null, null, null, null); sourceSets {
test {
java {
exclude '**/core/boot/tests/**'
}
}
} }
} }
+52
View File
@@ -0,0 +1,52 @@
/**
* 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.
*/
dependencies {
implementation(
'org.springframework.boot:spring-boot-starter',
'org.springframework.boot:spring-boot-starter-validation',
'org.apache.commons:commons-lang3',
'commons-beanutils:commons-beanutils',
'com.github.spotbugs:spotbugs-annotations',
'jakarta.validation:jakarta.validation-api',
'org.hibernate.validator:hibernate-validator',
'com.ibm.icu:icu4j',
'org.yakworks:spring-icu4j',
)
api('org.glassfish.jersey.ext:jersey-bean-validation') {
exclude group: 'jakarta.el', module: 'jakarta.el-api'
}
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
annotationProcessor 'org.mapstruct:mapstruct-processor'
testImplementation ('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'com.jayway.jsonpath', module: 'json-path'
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
exclude group: 'jakarta.activation'
exclude group: 'javax.activation'
exclude group: 'org.skyscreamer'
}
testImplementation( 'io.github.classgraph:classgraph' )
testImplementation ('org.mockito:mockito-inline')
}
@@ -0,0 +1,91 @@
/**
* 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.validation.config;
import jakarta.validation.MessageInterpolator;
import java.util.Locale;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.messageinterpolation.AbstractMessageInterpolator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator;
import yakworks.i18n.icu.ICUBundleMessageSource;
@Slf4j
@RequiredArgsConstructor
@Configuration
public class ValidationConfig {
@Bean
public MessageSource messageSource() {
var messageSource = new ICUBundleMessageSource();
messageSource.setBasenames("classpath:fineract/validation/messages");
messageSource.setCacheSeconds(3600);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public MessageInterpolator messageInterpolator() {
var resourceBundleLocator = new MessageSourceResourceBundleLocator(messageSource());
var messageInterpolator = new ResourceBundleMessageInterpolator(resourceBundleLocator);
return new RecursiveLocaleContextMessageInterpolator(messageInterpolator);
}
@Bean
@Primary
public Validator validator() {
var localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setMessageInterpolator(messageInterpolator());
return localValidatorFactoryBean;
}
private static final class RecursiveLocaleContextMessageInterpolator extends AbstractMessageInterpolator {
private static final Pattern PATTERN_PLACEHOLDER = Pattern.compile("\\{([^}]+)\\}");
private final MessageInterpolator interpolator;
private RecursiveLocaleContextMessageInterpolator(MessageInterpolator interpolator) {
this.interpolator = interpolator;
}
@Override
public String interpolate(MessageInterpolator.Context context, Locale locale, String message) {
int level = 0;
while (containsPlaceholder(message) && (level++ < 2)) {
message = this.interpolator.interpolate(message, context, locale);
}
return message;
}
private boolean containsPlaceholder(String code) {
return PATTERN_PLACEHOLDER.matcher(code).find();
}
}
}
@@ -0,0 +1,46 @@
/**
* 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.validation.constraints;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Constraint(validatedBy = LocalDateValidator.class)
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface LocalDate {
String message() default "{org.apache.fineract.validation.local-date}";
String dateField();
String formatField();
String localeField();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@@ -0,0 +1,83 @@
/**
* 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.validation.constraints;
import static java.time.LocalDateTime.parse;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.ResolverStyle;
import java.time.temporal.ChronoField;
import java.util.Locale;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@Slf4j
class LocalDateValidator implements ConstraintValidator<LocalDate, Object> {
private String dateField;
private String formatField;
private String localeField;
@Override
public void initialize(LocalDate annotation) {
this.dateField = annotation.dateField();
this.formatField = annotation.formatField();
this.localeField = annotation.localeField();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
try {
var dateAttr = value.getClass().getDeclaredField(dateField);
var formatAttr = value.getClass().getDeclaredField(formatField);
var localeAttr = value.getClass().getDeclaredField(localeField);
dateAttr.setAccessible(true);
formatAttr.setAccessible(true);
localeAttr.setAccessible(true);
var date = (String) dateAttr.get(value);
var format = (String) formatAttr.get(value);
var locale = (String) localeAttr.get(value);
if (StringUtils.isBlank(date) || StringUtils.isBlank(format) || StringUtils.isBlank(locale)) {
return false;
}
toLocalDate(date, format, locale);
return true;
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new RuntimeException("Invalid configuration for @LocalDate", e);
} catch (Exception e) {
return false;
}
}
private void toLocalDate(String date, String format, String locale) {
var formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().parseLenient().appendPattern(format.replace("y", "u"))
.optionalStart().appendPattern(" HH:mm:ss").optionalEnd().parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0).parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
.toFormatter(Locale.forLanguageTag(locale)).withResolverStyle(ResolverStyle.STRICT);
parse(date, formatter);
}
}
@@ -0,0 +1,40 @@
/**
* 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.validation.constraints;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Constraint(validatedBy = LocaleValidator.class)
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface Locale {
String message() default "{org.apache.fineract.validation.locale}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@@ -16,26 +16,17 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.apache.fineract.infrastructure.businessdate.api; package org.apache.fineract.validation.constraints;
import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.ConstraintValidator;
import java.util.Map; import jakarta.validation.ConstraintValidatorContext;
import java.util.Arrays;
import org.apache.commons.lang3.StringUtils;
final class BusinessDateApiResourceSwagger { class LocaleValidator implements ConstraintValidator<Locale, String> {
private BusinessDateApiResourceSwagger() { @Override
public boolean isValid(String value, ConstraintValidatorContext context) {
} return StringUtils.isNotBlank(value) && Arrays.asList(java.util.Locale.getISOLanguages()).contains(value);
@Schema(description = "BusinessDateResponse")
public static final class BusinessDateResponse {
@Schema(example = "1")
public Long commandId;
public Map<String, Object> changes;
private BusinessDateResponse() {
}
} }
} }
@@ -0,0 +1,30 @@
#
# 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.
#
# Validation
org.apache.fineract.validation.local-date=Wrong local date fields.
org.apache.fineract.validation.locale=The parameter `locale` has an invalid language value: `${validatedValue}`.
## Business Date
org.apache.fineract.businessdate.date-format.not-blank=The parameter 'dateFormat' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.type.not-null=The parameter 'type' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.date.not-blank=The parameter 'date' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.locale.not-blank=The parameter 'locale' is mandatory: '${validatedValue}'.
@@ -0,0 +1,30 @@
#
# 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.
#
# Validation
org.apache.fineract.validation.local-date=Wrong local date fields.
org.apache.fineract.validation.locale=The parameter `locale` has an invalid language value: `${validatedValue}`.
## Business Date
org.apache.fineract.businessdate.date-format.not-blank=The parameter 'dateFormat' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.type.not-null=The parameter 'type' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.date.not-blank=The parameter 'date' is mandatory: '${validatedValue}'.
org.apache.fineract.businessdate.locale.not-blank=The parameter 'locale' is mandatory: '${validatedValue}'.
@@ -0,0 +1,96 @@
/**
* 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.validation.constraints;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.validation.config.ValidationConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.validation.Validator;
@Slf4j
@SpringBootTest
@ContextConfiguration(classes = { ValidationConfig.class })
class LocalDateValidationTest {
@Autowired
private Validator validator;
@Test
void invalidAllBlank() {
var request = LocalDateModel.builder().format("").date(" ").locale(null).build();
var errors = validator.validateObject(request);
assertThat(errors.getAllErrors()).hasSize(1);
assertThat(errors.getAllErrors()).allMatch(e -> "Wrong local date fields.".equals(e.getDefaultMessage()));
}
@Test
void invalidLocaleFormat() {
var request = LocalDateModel.builder().format("dd-MM-yyyy").date("12-05-2025").locale("").build();
var errors = validator.validateObject(request);
assertThat(errors.getAllErrors()).hasSize(1);
assertThat(errors.getAllErrors()).allMatch(e -> "Wrong local date fields.".equals(e.getDefaultMessage()));
}
@Test
void invalidDateFormat() {
var request = LocalDateModel.builder().format("dd/MM/yyyy").date("12-05-2025").locale("en").build();
var errors = validator.validateObject(request);
assertThat(errors.getAllErrors()).hasSize(1);
assertThat(errors.getAllErrors()).allMatch(e -> "Wrong local date fields.".equals(e.getDefaultMessage()));
}
@Test
void valid() {
var request = LocalDateModel.builder().format("dd-MM-yyyy").date("12-05-2025").locale("en").build();
var errors = validator.validateObject(request);
assertThat(errors.getAllErrors()).isEmpty();
}
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@LocalDate(dateField = "date", formatField = "format", localeField = "locale")
static class LocalDateModel {
private String date;
private String format;
private String locale;
}
}
@@ -0,0 +1,83 @@
/**
* 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.validation.constraints;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.validation.config.ValidationConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.validation.Validator;
@Slf4j
@SpringBootTest
@ContextConfiguration(classes = { ValidationConfig.class })
class LocaleValidationTest {
@Autowired
private Validator validator;
@Test
void invalidBlank() {
var request = LocaleModel.builder().locale(null).build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(1);
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
}
@Test
void invalidFormat() {
var request = LocaleModel.builder().locale("EN").build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(1);
assertThat(errors.getFieldErrors()).anyMatch(e -> e.getField().equals("locale"));
}
@Test
void valid() {
var request = LocaleModel.builder().locale("en").build();
var errors = validator.validateObject(request);
assertThat(errors.getFieldErrorCount()).isEqualTo(0);
}
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
static class LocaleModel {
@Locale
private String locale;
}
}
@@ -42,7 +42,7 @@ import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.CreditAllocationData; import org.apache.fineract.client.models.CreditAllocationData;
import org.apache.fineract.client.models.CreditAllocationOrder; import org.apache.fineract.client.models.CreditAllocationOrder;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
@@ -68,7 +68,6 @@ import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PostUpdateRescheduleLoansRequest; import org.apache.fineract.client.models.PostUpdateRescheduleLoansRequest;
import org.apache.fineract.client.models.PutLoansLoanIdRequest; import org.apache.fineract.client.models.PutLoansLoanIdRequest;
import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.client.util.CallFailedRuntimeException;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -2467,7 +2466,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -2574,7 +2573,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -2679,7 +2678,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -2784,7 +2783,7 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -19,7 +19,6 @@
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static java.lang.System.lineSeparator; import static java.lang.System.lineSeparator;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION_STRATEGY; import static org.apache.fineract.integrationtests.BaseLoanIntegrationTest.TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION_STRATEGY;
import static org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY; import static org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder.DUE_PENALTY_INTEREST_PRINCIPAL_FEE_IN_ADVANCE_PENALTY_INTEREST_PRINCIPAL_FEE_STRATEGY;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -59,7 +58,7 @@ import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse; import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.AllowAttributeOverrides; import org.apache.fineract.client.models.AllowAttributeOverrides;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse; import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdChargesChargeIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod; import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
@@ -976,8 +975,8 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate( businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .date(date).dateFormat(DATETIME_PATTERN).locale("en"));
runnable.run(); runnable.run();
} finally { } finally {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
@@ -1147,8 +1146,8 @@ public abstract class BaseLoanIntegrationTest extends IntegrationTest {
} }
protected void updateBusinessDate(String date) { protected void updateBusinessDate(String date) {
businessDateHelper.updateBusinessDate( businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .date(date).dateFormat(DATETIME_PATTERN).locale("en"));
} }
protected Long getTransactionId(Long loanId, String type, String date) { protected Long getTransactionId(Long loanId, String type, String date) {
@@ -55,7 +55,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import org.apache.fineract.accounting.glaccount.domain.GLAccountType; import org.apache.fineract.accounting.glaccount.domain.GLAccountType;
import org.apache.fineract.client.models.AllowAttributeOverrides; import org.apache.fineract.client.models.AllowAttributeOverrides;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.ChargeRequest; import org.apache.fineract.client.models.ChargeRequest;
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse; import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoanTransactionRelation; import org.apache.fineract.client.models.GetLoanTransactionRelation;
@@ -87,7 +87,6 @@ import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutChargeTransactionChangesRequest; import org.apache.fineract.client.models.PutChargeTransactionChangesRequest;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.client.util.CallFailedRuntimeException;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
@@ -5320,7 +5319,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("01 November 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("01 November 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount(); final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount();
@@ -5491,7 +5490,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("01 November 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("01 November 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
final Account assetFeeAndPenaltyAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetFeeAndPenaltyAccount = ACCOUNT_HELPER.createAssetAccount();
@@ -6172,7 +6171,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("04 September 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("04 September 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount(); final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount();
@@ -6309,7 +6308,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
assertEquals(403, exception.getResponse().code()); assertEquals(403, exception.getResponse().code());
assertTrue(exception.getMessage().contains("error.msg.loan.is.not.charged.off")); assertTrue(exception.getMessage().contains("error.msg.loan.is.not.charged.off"));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("08 September 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("08 September 2022").dateFormat(DATETIME_PATTERN).locale("en"));
PostLoansLoanIdTransactionsResponse loanRepaymentResponse = LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID, PostLoansLoanIdTransactionsResponse loanRepaymentResponse = LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID,
@@ -6643,7 +6642,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
@@ -6779,7 +6778,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
@@ -6911,7 +6910,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en")); .date("10 October 2022").dateFormat(DATETIME_PATTERN).locale("en"));
final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount();
@@ -6993,7 +6992,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("01 January 2023").dateFormat(DATETIME_PATTERN).locale("en")); .date("01 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
LOG.info("-----------------------------------NEW CLIENT-----------------------------------------"); LOG.info("-----------------------------------NEW CLIENT-----------------------------------------");
final PostClientsRequest newClient = createRandomClientWithDate("01 January 2023"); final PostClientsRequest newClient = createRandomClientWithDate("01 January 2023");
@@ -7026,7 +7025,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
new PostLoansLoanIdChargesRequest().chargeId(penaltyCharge.getResourceId()).dateFormat(DATETIME_PATTERN).locale("en") new PostLoansLoanIdChargesRequest().chargeId(penaltyCharge.getResourceId()).dateFormat(DATETIME_PATTERN).locale("en")
.amount(10.0).dueDate("10 January 2023")); .amount(10.0).dueDate("10 January 2023"));
LOG.info("-------------------------------DO SOME PARTIAL REPAYMENTS-------------------------------------------"); LOG.info("-------------------------------DO SOME PARTIAL REPAYMENTS-------------------------------------------");
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("07 January 2023").dateFormat(DATETIME_PATTERN).locale("en")); .date("07 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
String firstRepaymentUUID = UUID.randomUUID().toString(); String firstRepaymentUUID = UUID.randomUUID().toString();
PostLoansLoanIdTransactionsResponse firstRepaymentResult = LOAN_TRANSACTION_HELPER.makeLoanRepayment(loanId, PostLoansLoanIdTransactionsResponse firstRepaymentResult = LOAN_TRANSACTION_HELPER.makeLoanRepayment(loanId,
@@ -18,15 +18,13 @@
*/ */
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse; import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO; import org.apache.fineract.infrastructure.event.external.service.validation.ExternalEventDTO;
@@ -335,8 +333,8 @@ public class CustomSnapshotEventIntegrationTest extends BaseLoanIntegrationTest
} }
private void updateBusinessDateAndExecuteCOBJob(String date) { private void updateBusinessDateAndExecuteCOBJob(String date) {
businessDateHelper.updateBusinessDate( businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .date(date).dateFormat(DATETIME_PATTERN).locale("en"));
schedulerJobHelper.executeAndAwaitJob("Loan COB"); schedulerJobHelper.executeAndAwaitJob("Loan COB");
} }
@@ -19,7 +19,6 @@
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static java.lang.Boolean.TRUE; import static java.lang.Boolean.TRUE;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.PAUSE; import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.PAUSE;
import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.RESUME; import static org.apache.fineract.portfolio.delinquency.domain.DelinquencyAction.RESUME;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -35,7 +34,7 @@ import java.util.UUID;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetDelinquencyActionsResponse; import org.apache.fineract.client.models.GetDelinquencyActionsResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdDelinquencyPausePeriod; import org.apache.fineract.client.models.GetLoansLoanIdDelinquencyPausePeriod;
@@ -137,8 +136,8 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE, "10 January 2023", "15 January 2023"); loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE, "10 January 2023", "15 January 2023");
// Update business date // Update business date
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("14 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("14 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// Create 2nd Delinquency Resume for the Loan // Create 2nd Delinquency Resume for the Loan
loanTransactionHelper.createLoanDelinquencyAction(loanId, RESUME, "14 January 2023"); loanTransactionHelper.createLoanDelinquencyAction(loanId, RESUME, "14 January 2023");
@@ -175,8 +174,8 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE, "10 January 2023", "15 January 2023"); loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE, "10 January 2023", "15 January 2023");
// Update business date // Update business date
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("14 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("14 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// Validate Loan Delinquency Pause Period on Loan // Validate Loan Delinquency Pause Period on Loan
validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "15 January 2023", true)); validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "15 January 2023", true));
@@ -188,8 +187,8 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "14 January 2023", true)); validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "14 January 2023", true));
// Update business date to 15 January 2023 // Update business date to 15 January 2023
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// Validate Loan Delinquency Pause Period on Loan // Validate Loan Delinquency Pause Period on Loan
validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "14 January 2023", false)); validateLoanDelinquencyPausePeriods(loanId, pausePeriods("10 January 2023", "14 January 2023", false));
@@ -343,8 +342,8 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
disburseLoan(loanId, BigDecimal.valueOf(100.00), "01 November 2023"); disburseLoan(loanId, BigDecimal.valueOf(100.00), "01 November 2023");
// Update business date // Update business date
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("05 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("05 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// Create Delinquency Pause for the Loan // Create Delinquency Pause for the Loan
PostLoansDelinquencyActionResponse response = loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE, PostLoansDelinquencyActionResponse response = loanTransactionHelper.createLoanDelinquencyAction(loanId, PAUSE,
@@ -352,8 +351,8 @@ public class DelinquencyActionIntegrationTests extends BaseLoanIntegrationTest {
// run cob for business date 26 November // run cob for business date 26 November
final InlineLoanCOBHelper inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec); final InlineLoanCOBHelper inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("26 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("26 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue()));
// Loan delinquency data // Loan delinquency data
@@ -41,7 +41,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateData; import org.apache.fineract.client.models.BusinessDateResponse;
import org.apache.fineract.client.models.DeleteDelinquencyBucketResponse; import org.apache.fineract.client.models.DeleteDelinquencyBucketResponse;
import org.apache.fineract.client.models.DeleteDelinquencyRangeResponse; import org.apache.fineract.client.models.DeleteDelinquencyRangeResponse;
import org.apache.fineract.client.models.DelinquencyBucketData; import org.apache.fineract.client.models.DelinquencyBucketData;
@@ -320,7 +320,7 @@ public class DelinquencyBucketsIntegrationTest extends BaseLoanIntegrationTest {
final LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 March 2012"); final LocalDate bussinesLocalDate = Utils.getDateAsLocalDate("01 March 2012");
log.info("Current date {}", bussinesLocalDate); log.info("Current date {}", bussinesLocalDate);
BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate); BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.BUSINESS_DATE, bussinesLocalDate);
final BusinessDateData businessDateResponse = this.businessDateHelper.getBusinessDateByType(requestSpec, responseSpec, final BusinessDateResponse businessDateResponse = this.businessDateHelper.getBusinessDateByType(requestSpec, responseSpec,
BusinessDateType.BUSINESS_DATE); BusinessDateType.BUSINESS_DATE);
ArrayList<Integer> rangeIds = new ArrayList<>(); ArrayList<Integer> rangeIds = new ArrayList<>();
@@ -32,7 +32,7 @@ import io.restassured.specification.ResponseSpecification;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdRequest;
import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse; import org.apache.fineract.client.models.PostLoansLoanIdChargesChargeIdResponse;
@@ -40,7 +40,6 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -96,7 +95,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -213,7 +212,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -344,7 +343,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -457,7 +456,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -542,7 +541,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -686,7 +685,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -769,7 +768,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.01.28").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.01.28").dateFormat("yyyy.MM.dd").locale("en"));
Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -823,7 +822,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
(long) firstRepaymentId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat("dd MMMM yyyy") (long) firstRepaymentId, new PostLoansLoanIdTransactionsTransactionIdRequest().dateFormat("dd MMMM yyyy")
.transactionDate("28 January 2023").transactionAmount(0.0).locale("en")); .transactionDate("28 January 2023").transactionAmount(0.0).locale("en"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.01.31").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.01.31").dateFormat("yyyy.MM.dd").locale("en"));
response = loanTransactionHelper.getLoanDetails((long) loanID); response = loanTransactionHelper.getLoanDetails((long) loanID);
@@ -913,7 +912,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -987,7 +986,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
Integer secondChargeId = loanTransactionHelper.addChargesForLoan(loanID, Integer secondChargeId = loanTransactionHelper.addChargesForLoan(loanID,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "15 February 2023", "15")); LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "15 February 2023", "15"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
response = loanTransactionHelper.getLoanDetails((long) loanID); response = loanTransactionHelper.getLoanDetails((long) loanID);
@@ -1159,7 +1158,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec, Integer fee = ChargesHelper.createCharges(requestSpec, responseSpec,
@@ -1233,7 +1232,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
Integer secondChargeId = loanTransactionHelper.addChargesForLoan(loanID, Integer secondChargeId = loanTransactionHelper.addChargesForLoan(loanID,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "15 February 2023", "15")); LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "15 February 2023", "15"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
response = loanTransactionHelper.getLoanDetails((long) loanID); response = loanTransactionHelper.getLoanDetails((long) loanID);
@@ -1328,7 +1327,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
} }
assertEquals(2, response.getTransactions().get(4).getLoanChargePaidByList().size()); assertEquals(2, response.getTransactions().get(4).getLoanChargePaidByList().size());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.07").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.07").dateFormat("yyyy.MM.dd").locale("en"));
PostLoansLoanIdTransactionsResponse secondReverseRepayment = loanTransactionHelper.reverseLoanTransaction((long) loanID, PostLoansLoanIdTransactionsResponse secondReverseRepayment = loanTransactionHelper.reverseLoanTransaction((long) loanID,
@@ -1338,7 +1337,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
Integer thirdChargeId = loanTransactionHelper.addChargesForLoan(loanID, Integer thirdChargeId = loanTransactionHelper.addChargesForLoan(loanID,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "07 March 2023", "15")); LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), "07 March 2023", "15"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.08").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.08").dateFormat("yyyy.MM.dd").locale("en"));
Integer thirdRepayment = (Integer) loanTransactionHelper.makeRepayment("08 March 2023", Float.parseFloat("15.00"), loanID) Integer thirdRepayment = (Integer) loanTransactionHelper.makeRepayment("08 March 2023", Float.parseFloat("15.00"), loanID)
@@ -1500,7 +1499,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en"));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.CHARGE_ACCRUAL_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.CHARGE_ACCRUAL_DATE,
new PutGlobalConfigurationsRequest().stringValue("submitted-date")); new PutGlobalConfigurationsRequest().stringValue("submitted-date"));
@@ -1525,7 +1524,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95"); loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95");
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en"));
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023") final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023")
@@ -1542,7 +1541,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON); this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON);
Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID, Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65")); LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en"));
inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue())); inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue()));
@@ -1582,7 +1581,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion()));
assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance()));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en"));
PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID), PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023") new PostLoansLoanIdTransactionsRequest().locale("en").dateFormat("dd MMMM yyyy").transactionDate("17 June 2023")
@@ -1692,7 +1691,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.05.14").dateFormat("yyyy.MM.dd").locale("en"));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.CHARGE_ACCRUAL_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.CHARGE_ACCRUAL_DATE,
new PutGlobalConfigurationsRequest().stringValue("submitted-date")); new PutGlobalConfigurationsRequest().stringValue("submitted-date"));
@@ -1717,7 +1716,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95"); loanStatusHashMap = loanTransactionHelper.disburseLoanWithTransactionAmount("14 May 2023", loanID, "127.95");
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.11").dateFormat("yyyy.MM.dd").locale("en"));
final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023") final String requestJSON = new LoanRescheduleRequestTestBuilder().updateRescheduleFromDate("13 June 2023")
@@ -1734,7 +1733,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON); this.loanRescheduleRequestHelper.approveLoanRescheduleRequest(loanRescheduleRequestId, aproveRequestJSON);
Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID, Integer penalty1LoanChargeId = loanTransactionHelper.addChargesForLoan(loanID,
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65")); LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(fee), "13 July 2023", "3.65"));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.12").dateFormat("yyyy.MM.dd").locale("en"));
inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue())); inlineLoanCOBHelper.executeInlineCOB(List.of(loanID.longValue()));
@@ -1774,7 +1773,7 @@ public class DueDateRespectiveLoanRepaymentScheduleTest extends BaseLoanIntegrat
assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion())); assertEquals(3.65, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getFeeChargesPortion()));
assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance())); assertEquals(0.0, Utils.getDoubleValue(loanDetails.getTransactions().get(1).getOutstandingLoanBalance()));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.06.17").dateFormat("yyyy.MM.dd").locale("en"));
PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID), PostLoansLoanIdTransactionsResponse merchantIssuedRefund1 = loanTransactionHelper.makeMerchantIssuedRefund(Long.valueOf(loanID),
@@ -31,7 +31,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse; import org.apache.fineract.client.models.DeleteLoansLoanIdChargesChargeIdResponse;
import org.apache.fineract.client.models.DeleteLoansLoanIdResponse; import org.apache.fineract.client.models.DeleteLoansLoanIdResponse;
import org.apache.fineract.client.models.DelinquencyRangeData; import org.apache.fineract.client.models.DelinquencyRangeData;
@@ -62,7 +62,6 @@ import org.apache.fineract.client.models.PutLoansLoanIdChargesChargeIdResponse;
import org.apache.fineract.client.models.PutLoansLoanIdRequest; import org.apache.fineract.client.models.PutLoansLoanIdRequest;
import org.apache.fineract.client.models.PutLoansLoanIdResponse; import org.apache.fineract.client.models.PutLoansLoanIdResponse;
import org.apache.fineract.client.util.CallFailedRuntimeException; import org.apache.fineract.client.util.CallFailedRuntimeException;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -832,7 +831,7 @@ public class ExternalIdSupportIntegrationTest extends BaseLoanIntegrationTest {
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
new BusinessDateHelper().updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) new BusinessDateHelper().updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2022.10.10").dateFormat("yyyy.MM.dd").locale("en")); .date("2022.10.10").dateFormat("yyyy.MM.dd").locale("en"));
try { try {
ArrayList<Integer> rangeIds = new ArrayList<>(); ArrayList<Integer> rangeIds = new ArrayList<>();
@@ -18,7 +18,6 @@
*/ */
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
@@ -26,7 +25,7 @@ import java.util.List;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoansLoanIdLoanInstallmentLevelDelinquency; import org.apache.fineract.client.models.GetLoansLoanIdLoanInstallmentLevelDelinquency;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsRequest;
@@ -595,8 +594,8 @@ public class InstallmentLevelDelinquencyAPIIntegrationTests extends BaseLoanInte
} }
private void updateBusinessDateAndExecuteCOBJob(String date) { private void updateBusinessDateAndExecuteCOBJob(String date) {
businessDateHelper.updateBusinessDate( businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .date(date).dateFormat(DATETIME_PATTERN).locale("en"));
schedulerJobHelper.executeAndAwaitJob("Loan COB"); schedulerJobHelper.executeAndAwaitJob("Loan COB");
} }
@@ -35,14 +35,13 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostClientsResponse; import org.apache.fineract.client.models.PostClientsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdRequest;
import org.apache.fineract.client.models.PostLoansRequest; import org.apache.fineract.client.models.PostLoansRequest;
import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -165,7 +164,7 @@ public class LoanChargePaymentWithAdvancedPaymentAllocationTest extends BaseLoan
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
final Integer savingsId = createSavingsAccountDailyPosting(client.getClientId().intValue(), startDate); final Integer savingsId = createSavingsAccountDailyPosting(client.getClientId().intValue(), startDate);
@@ -19,7 +19,6 @@
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static java.lang.Boolean.TRUE; import static java.lang.Boolean.TRUE;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -27,7 +26,7 @@ import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsRequest;
@@ -80,20 +79,20 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
verifyLoanDelinquencyNextPaymentDate(loanId, "01 November 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "01 November 2023", false);
// Update business date // Update business date
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("13 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("13 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 13 Nov Business date // delinquency next payment date for 13 Nov Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("16 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("16 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 16 Nov Business date // delinquency next payment date for 16 Nov Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("01 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("01 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 01 Dec Business date // delinquency next payment date for 01 Dec Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false);
@@ -111,14 +110,14 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") // installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("17 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("17 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 17 Dec Business date N + 1 // delinquency next payment date for 17 Dec Business date N + 1
verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("25 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("25 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
} finally { } finally {
// reset global config // reset global config
@@ -166,8 +165,8 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);
// Update business date // Update business date
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("13 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("13 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 13 Nov Business date // delinquency next payment date for 13 Nov Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "16 November 2023", false);
@@ -187,8 +186,8 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
// delinquency next payment date for 13 Nov Business date after paying 16 November Installment // delinquency next payment date for 13 Nov Business date after paying 16 November Installment
verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("16 November 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("16 November 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 16 Nov Business date // delinquency next payment date for 16 Nov Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);
@@ -208,8 +207,8 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
// delinquency next payment date for 16 Nov Business date after partial payment of 01 Dec installment // delinquency next payment date for 16 Nov Business date after partial payment of 01 Dec installment
verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "01 December 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("01 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("01 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 01 December Business date // delinquency next payment date for 01 December Business date
verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "16 December 2023", false);
@@ -227,14 +226,14 @@ public class LoanDelinquencyDetailsNextPaymentDateConfigurationTest extends Base
installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") // installment(0.0, 0.0, 50.0, 50.0, false, "23 December 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("17 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("17 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// delinquency next payment date for 17 Dec Business date N + 1 // delinquency next payment date for 17 Dec Business date N + 1
verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false); verifyLoanDelinquencyNextPaymentDate(loanId, "23 December 2023", false);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("25 December 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("25 December 2023").dateFormat(DATETIME_PATTERN).locale("en"));
} finally { } finally {
// reset global config // reset global config
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.NEXT_PAYMENT_DUE_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.NEXT_PAYMENT_DUE_DATE,
@@ -35,7 +35,7 @@ import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.ChargeRequest; import org.apache.fineract.client.models.ChargeRequest;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostChargesResponse; import org.apache.fineract.client.models.PostChargesResponse;
@@ -49,7 +49,6 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionI
import org.apache.fineract.client.models.PostLoansRequest; import org.apache.fineract.client.models.PostLoansRequest;
import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -436,7 +435,7 @@ public class LoanSpecificDueDateChargeAfterMaturityTest extends BaseLoanIntegrat
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("01 September 2023").dateFormat(DATETIME_PATTERN).locale("en")); .date("01 September 2023").dateFormat(DATETIME_PATTERN).locale("en"));
PostChargesResponse penaltyCharge = CHARGES_HELPER.createCharges(new ChargeRequest().penalty(true).amount(10.0) PostChargesResponse penaltyCharge = CHARGES_HELPER.createCharges(new ChargeRequest().penalty(true).amount(10.0)
@@ -462,7 +461,7 @@ public class LoanSpecificDueDateChargeAfterMaturityTest extends BaseLoanIntegrat
validateLoanTransaction(loanDetails, 0, 1000.0, 0.0, 0.0, 1000.0); validateLoanTransaction(loanDetails, 0, 1000.0, 0.0, 0.0, 1000.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("01 October 2023").dateFormat(DATETIME_PATTERN).locale("en")); .date("01 October 2023").dateFormat(DATETIME_PATTERN).locale("en"));
PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(),
@@ -475,7 +474,7 @@ public class LoanSpecificDueDateChargeAfterMaturityTest extends BaseLoanIntegrat
validateLoanTransaction(loanDetails, 1, 1000.0, 1000.0, 0.0, 0.0); validateLoanTransaction(loanDetails, 1, 1000.0, 1000.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getClosedObligationsMet()); assertTrue(loanDetails.getStatus().getClosedObligationsMet());
BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("04 October 2023").dateFormat(DATETIME_PATTERN).locale("en")); .date("04 October 2023").dateFormat(DATETIME_PATTERN).locale("en"));
loanTransactionHelper.makeMerchantIssuedRefund(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeMerchantIssuedRefund(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -40,7 +40,7 @@ import org.apache.fineract.batch.command.internal.CreateTransactionLoanCommandSt
import org.apache.fineract.batch.domain.BatchRequest; import org.apache.fineract.batch.domain.BatchRequest;
import org.apache.fineract.batch.domain.BatchResponse; import org.apache.fineract.batch.domain.BatchResponse;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.ChargeRequest; import org.apache.fineract.client.models.ChargeRequest;
import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData; import org.apache.fineract.client.models.GetLoansLoanIdLoanChargeData;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
@@ -57,7 +57,6 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
import org.apache.fineract.client.models.PostLoansRequest; import org.apache.fineract.client.models.PostLoansRequest;
import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.integrationtests.common.BatchHelper; import org.apache.fineract.integrationtests.common.BatchHelper;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -906,7 +905,7 @@ public class LoanTransactionInterestPaymentWaiverTest extends BaseLoanIntegratio
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -1013,7 +1012,7 @@ public class LoanTransactionInterestPaymentWaiverTest extends BaseLoanIntegratio
0.0, 0.0, 0.0); 0.0, 0.0, 0.0);
assertTrue(loanDetails.getStatus().getActive()); assertTrue(loanDetails.getStatus().getActive());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.09.16").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeLoanRepayment(loanResponse.getLoanId(), new PostLoansLoanIdTransactionsRequest()
@@ -34,7 +34,7 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactions; import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
@@ -42,7 +42,6 @@ import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -97,7 +96,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("04 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("04 October 2022").dateFormat(DATE_PATTERN).locale("en"));
// Loan ExternalId // Loan ExternalId
@@ -123,13 +122,13 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue()));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("05 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("05 October 2022").dateFormat(DATE_PATTERN).locale("en"));
loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr, new PostLoansLoanIdTransactionsRequest() loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr, new PostLoansLoanIdTransactionsRequest()
.dateFormat(DATE_PATTERN).transactionDate("05 October 2022").locale("en").transactionAmount(500.0)); .dateFormat(DATE_PATTERN).transactionDate("05 October 2022").locale("en").transactionAmount(500.0));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("06 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("06 October 2022").dateFormat(DATE_PATTERN).locale("en"));
loanTransactionHelper.reverseLoanTransaction(loanExternalIdStr, repaymentTransaction.getResourceId(), loanTransactionHelper.reverseLoanTransaction(loanExternalIdStr, repaymentTransaction.getResourceId(),
@@ -162,7 +161,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("04 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("04 October 2022").dateFormat(DATE_PATTERN).locale("en"));
// Loan ExternalId // Loan ExternalId
@@ -198,7 +197,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
assertEquals(LocalDate.of(2022, 10, 10), assertEquals(LocalDate.of(2022, 10, 10),
loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate()); loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("06 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("06 October 2022").dateFormat(DATE_PATTERN).locale("en"));
final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
@@ -217,7 +216,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
assertEquals(LocalDate.of(2022, 10, 10), assertEquals(LocalDate.of(2022, 10, 10),
loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate()); loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("11 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("11 October 2022").dateFormat(DATE_PATTERN).locale("en"));
loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, loanTransactionExternalIdStr, loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, loanTransactionExternalIdStr,
new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(100.0).paymentTypeId(1L)); new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(100.0).paymentTypeId(1L));
@@ -237,7 +236,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("04 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("04 October 2022").dateFormat(DATE_PATTERN).locale("en"));
final Account assetAccount = accountHelper.createAssetAccount(); final Account assetAccount = accountHelper.createAssetAccount();
@@ -277,7 +276,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue()));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("05 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("05 October 2022").dateFormat(DATE_PATTERN).locale("en"));
PostLoansLoanIdTransactionsResponse cbrTransactionResponse = loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr, PostLoansLoanIdTransactionsResponse cbrTransactionResponse = loanTransactionHelper.makeCreditBalanceRefund(loanExternalIdStr,
@@ -302,7 +301,7 @@ public class LoanTransactionReverseReplayTest extends BaseLoanIntegrationTest {
assertEquals(1, cbrExpenseJournalEntries.size()); assertEquals(1, cbrExpenseJournalEntries.size());
assertEquals(1, cbrAssetJournalEntries.size()); assertEquals(1, cbrAssetJournalEntries.size());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("06 October 2022").dateFormat(DATE_PATTERN).locale("en")); .date("06 October 2022").dateFormat(DATE_PATTERN).locale("en"));
loanTransactionHelper.reverseLoanTransaction(loanExternalIdStr, repaymentTransaction.getResourceId(), loanTransactionHelper.reverseLoanTransaction(loanExternalIdStr, repaymentTransaction.getResourceId(),
@@ -31,7 +31,7 @@ import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod; import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostClientsResponse; import org.apache.fineract.client.models.PostClientsResponse;
@@ -39,7 +39,6 @@ import org.apache.fineract.client.models.PostLoansLoanIdRequest;
import org.apache.fineract.client.models.PostLoansRequest; import org.apache.fineract.client.models.PostLoansRequest;
import org.apache.fineract.client.models.PostLoansResponse; import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants; import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
@@ -87,7 +86,7 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest extends BaseL
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
final Account assetAccount = accountHelper.createAssetAccount(); final Account assetAccount = accountHelper.createAssetAccount();
@@ -167,7 +166,7 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest extends BaseL
assertEquals(250.00, Utils.getDoubleValue(thirdRepaymentInstallment.getTotalOutstandingForPeriod())); assertEquals(250.00, Utils.getDoubleValue(thirdRepaymentInstallment.getTotalOutstandingForPeriod()));
assertEquals(LocalDate.of(2023, 4, 1), thirdRepaymentInstallment.getDueDate()); assertEquals(LocalDate.of(2023, 4, 1), thirdRepaymentInstallment.getDueDate());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeRepayment("01 March 2023", 810.0f, loanId); loanTransactionHelper.makeRepayment("01 March 2023", 810.0f, loanId);
@@ -288,7 +287,7 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest extends BaseL
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.02.15").dateFormat("yyyy.MM.dd").locale("en"));
final Account assetAccount = accountHelper.createAssetAccount(); final Account assetAccount = accountHelper.createAssetAccount();
@@ -368,7 +367,7 @@ public class RefundForActiveLoansWithAdvancedPaymentAllocationTest extends BaseL
assertEquals(250.00, Utils.getDoubleValue(thirdRepaymentInstallment.getTotalOutstandingForPeriod())); assertEquals(250.00, Utils.getDoubleValue(thirdRepaymentInstallment.getTotalOutstandingForPeriod()));
assertEquals(LocalDate.of(2023, 4, 1), thirdRepaymentInstallment.getDueDate()); assertEquals(LocalDate.of(2023, 4, 1), thirdRepaymentInstallment.getDueDate());
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en")); .date("2023.03.01").dateFormat("yyyy.MM.dd").locale("en"));
loanTransactionHelper.makeRepayment("28 January 2023", 810.0f, loanId); loanTransactionHelper.makeRepayment("28 January 2023", 810.0f, loanId);
@@ -49,7 +49,7 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse; import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.JournalEntryTransactionItem; import org.apache.fineract.client.models.JournalEntryTransactionItem;
@@ -1348,7 +1348,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2022.09.04").dateFormat("yyyy.MM.dd").locale("en")); .date("2022.09.04").dateFormat("yyyy.MM.dd").locale("en"));
final Account assetAccount = this.accountHelper.createAssetAccount(); final Account assetAccount = this.accountHelper.createAssetAccount();
@@ -1375,7 +1375,7 @@ public class SchedulerJobsTestResults extends IntegrationTest {
this.loanTransactionHelper.approveLoan("02 September 2022", loanId); this.loanTransactionHelper.approveLoan("02 September 2022", loanId);
this.loanTransactionHelper.disburseLoan("03 September 2022", loanId, "1000", null); this.loanTransactionHelper.disburseLoan("03 September 2022", loanId, "1000", null);
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.date("2022.09.05").dateFormat("yyyy.MM.dd").locale("en")); .date("2022.09.05").dateFormat("yyyy.MM.dd").locale("en"));
LocalDate targetDate = LocalDate.of(2022, 9, 5); LocalDate targetDate = LocalDate.of(2022, 9, 5);
@@ -19,12 +19,11 @@
package org.apache.fineract.integrationtests; package org.apache.fineract.integrationtests;
import static java.lang.Boolean.TRUE; import static java.lang.Boolean.TRUE;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsRequest;
import org.apache.fineract.client.models.PostLoanProductsResponse; import org.apache.fineract.client.models.PostLoanProductsResponse;
@@ -795,8 +794,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -909,8 +908,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("10 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("10 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
addRepaymentForLoan(loanId, 300.0, "10 January 2023"); addRepaymentForLoan(loanId, 300.0, "10 January 2023");
@@ -920,8 +919,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
transaction(300.0, "Repayment", "10 January 2023") // transaction(300.0, "Repayment", "10 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1047,8 +1046,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1166,8 +1165,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1201,8 +1200,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(1050.0, false, "31 January 2023") // installment(1050.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("20 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("20 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// make an additional repayment after the 2nd disbursal // make an additional repayment after the 2nd disbursal
addRepaymentForLoan(loanId, 50.0, "20 January 2023"); addRepaymentForLoan(loanId, 50.0, "20 January 2023");
@@ -1258,8 +1257,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1296,8 +1295,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(1050.0, false, "31 January 2023") // installment(1050.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("20 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("20 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// make an additional repayment after the 2nd disbursal // make an additional repayment after the 2nd disbursal
addRepaymentForLoan(loanId, 50.0, "20 January 2023"); addRepaymentForLoan(loanId, 50.0, "20 January 2023");
@@ -1350,8 +1349,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1472,8 +1471,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1594,8 +1593,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1629,8 +1628,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(1050.0, false, "31 January 2023") // installment(1050.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("20 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("20 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// make an additional repayment after the 2nd disbursal // make an additional repayment after the 2nd disbursal
addRepaymentForLoan(loanId, 50.0, "20 January 2023"); addRepaymentForLoan(loanId, 50.0, "20 January 2023");
@@ -1730,8 +1729,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(750.0, false, "31 January 2023") // installment(750.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("15 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("15 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// 2nd Disburse Loan // 2nd Disburse Loan
disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023"); disburseLoan(loanId, BigDecimal.valueOf(400.0), "15 January 2023");
@@ -1767,8 +1766,8 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
installment(1050.0, false, "31 January 2023") // installment(1050.0, false, "31 January 2023") //
); );
businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BUSINESS_DATE.getName()).date("20 January 2023") businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
.dateFormat(DATETIME_PATTERN).locale("en")); .date("20 January 2023").dateFormat(DATETIME_PATTERN).locale("en"));
// make an additional repayment after the 2nd disbursal // make an additional repayment after the 2nd disbursal
addRepaymentForLoan(loanId, 50.0, "20 January 2023"); addRepaymentForLoan(loanId, 50.0, "20 January 2023");
@@ -18,8 +18,6 @@
*/ */
package org.apache.fineract.integrationtests.common; package org.apache.fineract.integrationtests.common;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import com.google.gson.Gson; import com.google.gson.Gson;
import io.restassured.specification.RequestSpecification; import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification; import io.restassured.specification.ResponseSpecification;
@@ -27,9 +25,8 @@ import java.time.LocalDate;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import lombok.extern.slf4j.Slf4j; 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.BusinessDateResponse;
import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.PutGlobalConfigurationsRequest; import org.apache.fineract.client.models.PutGlobalConfigurationsRequest;
import org.apache.fineract.client.util.Calls; import org.apache.fineract.client.util.Calls;
import org.apache.fineract.client.util.JSON; import org.apache.fineract.client.util.JSON;
@@ -56,29 +53,29 @@ public final class BusinessDateHelper {
return Utils.performServerPost(requestSpec, responseSpec, BUSINESS_DATE_API, buildBusinessDateRequest(type, date), "changes"); return Utils.performServerPost(requestSpec, responseSpec, BUSINESS_DATE_API, buildBusinessDateRequest(type, date), "changes");
} }
public static BusinessDateResponse updateBusinessDate(final BusinessDateRequest request) { public static BusinessDateResponse updateBusinessDate(final BusinessDateUpdateRequest request) {
log.info("------------------UPDATE BUSINESS DATE----------------------"); log.info("------------------UPDATE BUSINESS DATE----------------------");
log.info("------------------Type: {}, date: {}----------------------", request.getType(), request.getDate()); log.info("------------------Type: {}, date: {}----------------------", request.getType(), request.getDate());
return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.updateBusinessDate(request)); return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.updateBusinessDate(null, request));
} }
// TODO: Rewrite to use fineract-client instead! // TODO: Rewrite to use fineract-client instead!
// Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long, // Example: org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper.disburseLoan(java.lang.Long,
// org.apache.fineract.client.models.PostLoansLoanIdRequest) // org.apache.fineract.client.models.PostLoansLoanIdRequest)
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public BusinessDateData getBusinessDateByType(final RequestSpecification requestSpec, final ResponseSpecification responseSpec, public BusinessDateResponse getBusinessDateByType(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
final BusinessDateType type) { final BusinessDateType type) {
final String BUSINESS_DATE_API = "/fineract-provider/api/v1/businessdate/" + type.name() + "?" + Utils.TENANT_IDENTIFIER; final String BUSINESS_DATE_API = "/fineract-provider/api/v1/businessdate/" + type.name() + "?" + Utils.TENANT_IDENTIFIER;
final String response = Utils.performServerGet(requestSpec, responseSpec, BUSINESS_DATE_API); final String response = Utils.performServerGet(requestSpec, responseSpec, BUSINESS_DATE_API);
log.info("{}", response); log.info("{}", response);
return GSON.fromJson(response, BusinessDateData.class); return GSON.fromJson(response, BusinessDateResponse.class);
} }
public BusinessDateData getBusinessDate(final String type) { public BusinessDateResponse getBusinessDate(final String type) {
return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.getBusinessDate(type)); return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.getBusinessDate(type));
} }
public List<BusinessDateData> getBusinessDates() { public List<BusinessDateResponse> getBusinessDates() {
return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.getBusinessDates()); return Calls.ok(FineractClientHelper.getFineractClient().businessDateManagement.getBusinessDates());
} }
@@ -100,8 +97,8 @@ public final class BusinessDateHelper {
try { try {
new GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
updateBusinessDate( updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE).date(date)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .dateFormat(DATETIME_PATTERN).locale("en"));
runnable.run(); runnable.run();
} finally { } finally {
new GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new GlobalConfigurationHelper().updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
@@ -18,8 +18,6 @@
*/ */
package org.apache.fineract.integrationtests.savings.base; package org.apache.fineract.integrationtests.savings.base;
import static org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType.BUSINESS_DATE;
import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.RequestSpecBuilder;
import io.restassured.builder.ResponseSpecBuilder; import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.http.ContentType; import io.restassured.http.ContentType;
@@ -36,7 +34,7 @@ import java.util.function.Consumer;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.ToString; import lombok.ToString;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.BusinessDateUpdateRequest;
import org.apache.fineract.client.models.PostSavingsAccountTransactionsRequest; import org.apache.fineract.client.models.PostSavingsAccountTransactionsRequest;
import org.apache.fineract.client.models.PostSavingsAccountTransactionsResponse; import org.apache.fineract.client.models.PostSavingsAccountTransactionsResponse;
import org.apache.fineract.client.models.PostSavingsAccountsAccountIdRequest; import org.apache.fineract.client.models.PostSavingsAccountsAccountIdRequest;
@@ -102,8 +100,8 @@ public class BaseSavingsIntegrationTest extends IntegrationTest {
try { try {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
new PutGlobalConfigurationsRequest().enabled(true)); new PutGlobalConfigurationsRequest().enabled(true));
businessDateHelper.updateBusinessDate( businessDateHelper.updateBusinessDate(new BusinessDateUpdateRequest().type(BusinessDateUpdateRequest.TypeEnum.BUSINESS_DATE)
new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en")); .date(date).dateFormat(DATETIME_PATTERN).locale("en"));
runnable.accept(date); runnable.accept(date);
} finally { } finally {
globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE,
+1
View File
@@ -48,6 +48,7 @@ buildCache {
rootProject.name='fineract' rootProject.name='fineract'
include ':fineract-core' include ':fineract-core'
include ':fineract-validation'
include ':fineract-command' include ':fineract-command'
include ':fineract-accounting' include ':fineract-accounting'
include ':fineract-provider' include ':fineract-provider'
+1
View File
@@ -43,6 +43,7 @@ project.afterEvaluate {
copy { copy {
from persistenceXmlFile.toPath() from persistenceXmlFile.toPath()
into metaInf.toPath() into metaInf.toPath()
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
} }
javaexec { javaexec {