Skip to content

Commit c7dc8a6

Browse files
FINERACT-2238: Refactor under new concept business date api;
1 parent 9c87276 commit c7dc8a6

File tree

76 files changed

+1023
-953
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1023
-953
lines changed

buildSrc/src/main/groovy/org.apache.fineract.dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencyManagement {
3838
mavenBom 'software.amazon.awssdk:bom:2.29.9'
3939
mavenBom 'io.github.resilience4j:resilience4j-bom:2.2.0'
4040
mavenBom 'org.testcontainers:testcontainers-bom:1.20.4'
41+
mavenBom 'org.glassfish.jersey:jersey-bom:3.1.10'
4142
}
4243

4344
dependencies {
@@ -117,7 +118,6 @@ dependencyManagement {
117118
dependency 'jakarta.management.j2ee:jakarta.management.j2ee-api:1.1.4'
118119
dependency 'jakarta.jms:jakarta.jms-api:3.1.0'
119120
dependency 'jakarta.ws.rs:jakarta.ws.rs-api:3.1.0'
120-
dependency 'org.glassfish.jersey.media:jersey-media-multipart:3.1.10'
121121
dependency 'org.glassfish.jaxb:jaxb-runtime:2.3.6' // Swagger needs exactly this version
122122
dependency 'org.apache.bval:org.apache.bval.bundle:3.0.2'
123123
dependency 'joda-time:joda-time:2.13.1'

fineract-accounting/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ dependencies {
3838
'org.springframework.batch:spring-batch-integration',
3939
'jakarta.ws.rs:jakarta.ws.rs-api',
4040
'org.glassfish.jersey.media:jersey-media-multipart',
41+
'org.glassfish.jersey.ext:jersey-bean-validation',
4142

4243
'com.google.guava:guava',
4344
'com.google.code.gson:gson',

fineract-branch/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies {
3232
'org.springframework.boot:spring-boot-starter-security',
3333
'jakarta.ws.rs:jakarta.ws.rs-api',
3434
'org.glassfish.jersey.media:jersey-media-multipart',
35+
'org.glassfish.jersey.ext:jersey-bean-validation',
3536

3637
'com.google.guava:guava',
3738
'com.google.code.gson:gson',

fineract-charge/dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dependencies {
3232
'org.springframework.boot:spring-boot-starter-security',
3333
'jakarta.ws.rs:jakarta.ws.rs-api',
3434
'org.glassfish.jersey.media:jersey-media-multipart',
35+
'org.glassfish.jersey.ext:jersey-bean-validation',
3536

3637
'com.google.guava:guava',
3738
'com.google.code.gson:gson',

fineract-command/src/main/java/org/apache/fineract/command/core/Command.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class Command<T> implements Serializable {
3434

3535
private UUID id;
3636

37+
private String idempotencyKey;
38+
3739
private OffsetDateTime createdAt;
3840

3941
private String tenantId;

fineract-core/dependencies.gradle

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ dependencies {
2323
// Note that we never use 'api', because Fineract at least currently is a simple monolithic application ("WAR"), not a library.
2424
// We also (normally should have) no need to ever use 'compileOnly'.
2525

26-
implementation(
27-
project(path: ':fineract-avro-schemas')
28-
)
26+
implementation(project(path: ':fineract-avro-schemas'))
27+
implementation(project(path: ':fineract-command'))
28+
2929

3030
// implementation dependencies are directly used (compiled against) in src/main (and src/test)
3131
implementation(
@@ -36,6 +36,7 @@ dependencies {
3636
'org.springframework.batch:spring-batch-integration',
3737
'jakarta.ws.rs:jakarta.ws.rs-api',
3838
'org.glassfish.jersey.media:jersey-media-multipart',
39+
'org.glassfish.jersey.ext:jersey-bean-validation',
3940
'org.apache.avro:avro',
4041

4142
'com.google.guava:guava',

fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/api/BusinessDateApiResource.java

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,26 @@
2020

2121
import io.swagger.v3.oas.annotations.Operation;
2222
import io.swagger.v3.oas.annotations.Parameter;
23-
import io.swagger.v3.oas.annotations.media.Content;
24-
import io.swagger.v3.oas.annotations.media.Schema;
25-
import io.swagger.v3.oas.annotations.parameters.RequestBody;
26-
import io.swagger.v3.oas.annotations.responses.ApiResponse;
27-
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2823
import io.swagger.v3.oas.annotations.tags.Tag;
24+
import jakarta.validation.Valid;
2925
import jakarta.ws.rs.Consumes;
3026
import jakarta.ws.rs.GET;
27+
import jakarta.ws.rs.HeaderParam;
3128
import jakarta.ws.rs.POST;
3229
import jakarta.ws.rs.Path;
3330
import jakarta.ws.rs.PathParam;
3431
import jakarta.ws.rs.Produces;
3532
import jakarta.ws.rs.core.MediaType;
3633
import java.util.List;
34+
import java.util.UUID;
35+
import java.util.function.Supplier;
3736
import lombok.RequiredArgsConstructor;
38-
import org.apache.fineract.commands.domain.CommandWrapper;
39-
import org.apache.fineract.commands.service.CommandWrapperBuilder;
40-
import org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
41-
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateData;
42-
import org.apache.fineract.infrastructure.businessdate.data.request.BusinessDateRequest;
37+
import org.apache.fineract.command.core.CommandPipeline;
38+
import org.apache.fineract.infrastructure.businessdate.command.BusinessDateCommand;
39+
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateResponse;
40+
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
4341
import org.apache.fineract.infrastructure.businessdate.service.BusinessDateReadPlatformService;
44-
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
45-
import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
46-
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
42+
import org.apache.fineract.infrastructure.core.service.DateUtils;
4743
import org.springframework.stereotype.Component;
4844

4945
@RequiredArgsConstructor
@@ -52,19 +48,14 @@
5248
@Tag(name = "Business Date Management", description = "Business date management enables you to set up, fetch and adjust organisation business dates")
5349
public class BusinessDateApiResource {
5450

55-
private static final String BUSINESS_DATE = "BUSINESS_DATE";
56-
57-
private final PlatformSecurityContext securityContext;
58-
private final DefaultToApiJsonSerializer<BusinessDateData> jsonSerializer;
5951
private final BusinessDateReadPlatformService readPlatformService;
60-
private final PortfolioCommandSourceWritePlatformService commandWritePlatformService;
52+
private final CommandPipeline commandPipeline;
6153

6254
@GET
6355
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
6456
@Produces(MediaType.APPLICATION_JSON)
6557
@Operation(summary = "List all business dates", description = "")
66-
public List<BusinessDateData> getBusinessDates() {
67-
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
58+
public List<BusinessDateResponse> getBusinessDates() {
6859
return this.readPlatformService.findAll();
6960
}
7061

@@ -73,23 +64,27 @@ public List<BusinessDateData> getBusinessDates() {
7364
@Consumes({ MediaType.TEXT_HTML, MediaType.APPLICATION_JSON })
7465
@Produces(MediaType.APPLICATION_JSON)
7566
@Operation(summary = "Retrieve a specific Business date", description = "")
76-
public BusinessDateData getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) {
77-
securityContext.authenticatedUser().validateHasReadPermission(BUSINESS_DATE);
67+
public BusinessDateResponse getBusinessDate(@PathParam("type") @Parameter(description = "type") final String type) {
7868
return this.readPlatformService.findByType(type);
7969
}
8070

8171
@POST
8272
@Consumes({ MediaType.APPLICATION_JSON })
8373
@Produces({ MediaType.APPLICATION_JSON })
8474
@Operation(summary = "Update Business Date", description = "")
85-
@RequestBody(required = true, content = @Content(schema = @Schema(implementation = BusinessDateRequest.class)))
86-
@ApiResponses({
87-
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = BusinessDateApiResourceSwagger.BusinessDateResponse.class))) })
88-
public CommandProcessingResult updateBusinessDate(BusinessDateRequest businessDateRequest) {
89-
securityContext.authenticatedUser().validateHasUpdatePermission(BUSINESS_DATE);
90-
final CommandWrapper commandRequest = new CommandWrapperBuilder().updateBusinessDate()
91-
.withJson(jsonSerializer.serialize(businessDateRequest)).build();
92-
return commandWritePlatformService.logCommandSource(commandRequest);
75+
public BusinessDateResponse updateBusinessDate(@HeaderParam("Idempotency-Key") String idempotencyKey,
76+
@Valid BusinessDateUpdateRequest request) {
77+
78+
final BusinessDateCommand command = new BusinessDateCommand();
79+
80+
command.setId(UUID.randomUUID());
81+
command.setIdempotencyKey(idempotencyKey);
82+
command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
83+
command.setPayload(request);
84+
85+
final Supplier<BusinessDateResponse> response = commandPipeline.send(command);
86+
87+
return response.get();
9388
}
9489

9590
}

fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/increasedateby1day/IncreaseDateBy1DayService.java renamed to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/command/BusinessDateCommand.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package org.apache.fineract.infrastructure.jobs.service.increasedateby1day;
19+
package org.apache.fineract.infrastructure.businessdate.command;
2020

21-
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
21+
import lombok.Data;
22+
import lombok.EqualsAndHashCode;
23+
import org.apache.fineract.command.core.Command;
24+
import org.apache.fineract.infrastructure.businessdate.data.BusinessDateUpdateRequest;
2225

23-
public interface IncreaseDateBy1DayService {
24-
25-
void increaseDateByTypeByOneDay(BusinessDateType businessDateType);
26-
}
26+
@Data
27+
@EqualsAndHashCode(callSuper = true)
28+
public class BusinessDateCommand extends Command<BusinessDateUpdateRequest> {}

fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateData.java renamed to fineract-core/src/main/java/org/apache/fineract/infrastructure/businessdate/data/BusinessDateResponse.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,24 +21,43 @@
2121
import java.io.Serial;
2222
import java.io.Serializable;
2323
import java.time.LocalDate;
24+
import java.util.HashMap;
25+
import java.util.Map;
26+
import lombok.AllArgsConstructor;
27+
import lombok.Builder;
2428
import lombok.Data;
2529
import lombok.NoArgsConstructor;
26-
import lombok.experimental.Accessors;
2730
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
2831

32+
@Builder
2933
@Data
3034
@NoArgsConstructor
31-
@Accessors(chain = true)
32-
public class BusinessDateData implements Serializable {
35+
@AllArgsConstructor
36+
public class BusinessDateResponse implements Serializable {
3337

3438
@Serial
3539
private static final long serialVersionUID = 1L;
40+
3641
private String description;
37-
private String type;
42+
private BusinessDateType type;
3843
private LocalDate date;
44+
private Map<BusinessDateType, LocalDate> changes;
45+
46+
public void addChange(final BusinessDateType businessDateType, final LocalDate date) {
47+
if (this.changes == null) {
48+
this.changes = new HashMap<>();
49+
}
3950

40-
public static BusinessDateData instance(BusinessDateType businessDateType, LocalDate value) {
41-
return new BusinessDateData().setType(businessDateType.getName()).setDescription(businessDateType.getDescription()).setDate(value);
51+
changes.put(businessDateType, date);
4252
}
4353

54+
public void addAllChanges(final Map<BusinessDateType, LocalDate> changes) {
55+
if (changes == null || changes.isEmpty()) {
56+
return;
57+
}
58+
59+
for (final Map.Entry<BusinessDateType, LocalDate> entry : changes.entrySet()) {
60+
addChange(entry.getKey(), entry.getValue());
61+
}
62+
}
4463
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.fineract.infrastructure.businessdate.data;
20+
21+
import jakarta.validation.constraints.NotBlank;
22+
import jakarta.validation.constraints.NotNull;
23+
import java.io.Serial;
24+
import java.io.Serializable;
25+
import lombok.AllArgsConstructor;
26+
import lombok.Builder;
27+
import lombok.Data;
28+
import lombok.NoArgsConstructor;
29+
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
30+
import org.apache.fineract.infrastructure.businessdate.validator.ISOLocale;
31+
import org.apache.fineract.infrastructure.businessdate.validator.ParsableDate;
32+
33+
@Builder
34+
@Data
35+
@NoArgsConstructor
36+
@AllArgsConstructor
37+
@ParsableDate(dateField = "date", formatField = "dateFormat", localeField = "locale")
38+
public class BusinessDateUpdateRequest implements Serializable {
39+
40+
@Serial
41+
private static final long serialVersionUID = 1L;
42+
43+
@NotBlank(message = "{org.apache.fineract.businessdate.date-format.not-blank}")
44+
private String dateFormat;
45+
@NotNull(message = "{org.apache.fineract.businessdate.type.not-null}")
46+
private BusinessDateType type;
47+
@NotBlank(message = "{org.apache.fineract.businessdate.date.not-blank}")
48+
private String date;
49+
@NotBlank(message = "{org.apache.fineract.businessdate.locale.not-blank}")
50+
@ISOLocale
51+
private String locale;
52+
}

0 commit comments

Comments
 (0)