This is an automated email from the ASF dual-hosted git repository.
aleks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 701cfae60b FINERACT 2289: New command processing - Working Days
701cfae60b is described below
commit 701cfae60bc70de68e41b9b4345e0c393ec3d19a
Author: yuwatidora <[email protected]>
AuthorDate: Thu Feb 19 21:17:21 2026 -0500
FINERACT 2289: New command processing - Working Days
command base test fix
---
docker-compose-mysql.yml | 34 ++++++++++++
.../workingdays/domain/WorkingDays.java | 60 ++++-----------------
.../domain/WorkingDaysEnumerations.java | 4 +-
.../infrastructure/core/config/SecurityConfig.java | 7 +++
.../workingdays/api/WorkingDaysApiResource.java | 42 +++++++--------
.../WorkingDaysUpdateCommand.java} | 15 +++---
.../workingdays/data/WorkingDayValidator.java | 1 +
.../workingdays/data/WorkingDaysData.java | 36 +++----------
.../WorkingDaysUpdateRequest.java} | 30 +++++++++--
.../data/WorkingDaysUpdateRequestValidator.java | 62 ++++++++++++++++++++++
.../WorkingDaysUpdateResponse.java} | 26 +++++++--
.../handler/UpdateWorkingDaysCommandHandler.java | 41 ++++++++------
.../WorkingDaysReadPlatformServiceImpl.java | 12 +++--
.../service/WorkingDaysWritePlatformService.java | 8 +--
...gDaysWritePlatformServiceJpaRepositoryImpl.java | 53 +++++++++++++-----
.../OrganisationWorkingDaysConfiguration.java | 6 +--
16 files changed, 277 insertions(+), 160 deletions(-)
diff --git a/docker-compose-mysql.yml b/docker-compose-mysql.yml
new file mode 100644
index 0000000000..5f0521724a
--- /dev/null
+++ b/docker-compose-mysql.yml
@@ -0,0 +1,34 @@
+# 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.
+#
+
+services:
+ mysql:
+ container_name: mysql
+ image: mysql:8
+ volumes:
+ -
${PWD}/config/docker/mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf:ro
+ -
${PWD}/config/docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
+ restart: always
+ env_file:
+ - ${PWD}/config/docker/env/mysql.env
+ healthcheck:
+ test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect",
"--innodb_initialized" ]
+ timeout: 10s
+ retries: 10
+ ports:
+ - "3306:3306"
diff --git
a/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java
b/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java
index 8fbe7125b5..b55b591c73 100644
---
a/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java
+++
b/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java
@@ -21,16 +21,21 @@ package org.apache.fineract.organisation.workingdays.domain;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
+import lombok.experimental.FieldNameConstants;
import
org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
-import
org.apache.fineract.organisation.workingdays.api.WorkingDaysApiConstants;
+@Builder
@Getter
+@Setter
@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
@Table(name = "m_working_days")
public class WorkingDays extends AbstractPersistableCustom<Long> {
@@ -47,51 +52,4 @@ public class WorkingDays extends
AbstractPersistableCustom<Long> {
@Column(name = "extend_term_holiday_repayment", nullable = false)
private Boolean extendTermForRepaymentsOnHolidays;
- protected WorkingDays() {
-
- }
-
- public WorkingDays(final String recurrence, final Integer
repaymentReschedulingType, final Boolean extendTermForDailyRepayments,
- final Boolean extendTermForRepaymentsOnHolidays) {
- this.recurrence = recurrence;
- this.repaymentReschedulingType = repaymentReschedulingType;
- this.extendTermForDailyRepayments = extendTermForDailyRepayments;
- this.extendTermForRepaymentsOnHolidays =
extendTermForRepaymentsOnHolidays;
- }
-
- public Map<String, Object> update(final JsonCommand command) {
- final Map<String, Object> actualChanges = new LinkedHashMap<>(7);
-
- final String recurrenceParamName = "recurrence";
- if (command.isChangeInStringParameterNamed(recurrenceParamName,
this.recurrence)) {
- final String newValue =
command.stringValueOfParameterNamed(recurrenceParamName);
- actualChanges.put(recurrenceParamName, newValue);
- this.recurrence = newValue;
- }
-
- final String repaymentRescheduleTypeParamName =
"repaymentRescheduleType";
- if
(command.isChangeInIntegerParameterNamed(repaymentRescheduleTypeParamName,
this.repaymentReschedulingType)) {
- final Integer newValue =
command.integerValueOfParameterNamed(repaymentRescheduleTypeParamName);
- actualChanges.put(repaymentRescheduleTypeParamName,
WorkingDaysEnumerations.workingDaysStatusType(newValue));
- this.repaymentReschedulingType =
RepaymentRescheduleType.fromInt(newValue).getValue();
- }
-
- if
(command.isChangeInBooleanParameterNamed(WorkingDaysApiConstants.extendTermForDailyRepayments,
- this.extendTermForDailyRepayments)) {
- final Boolean newValue =
command.booleanPrimitiveValueOfParameterNamed(WorkingDaysApiConstants.extendTermForDailyRepayments);
-
actualChanges.put(WorkingDaysApiConstants.extendTermForDailyRepayments,
newValue);
- this.extendTermForDailyRepayments = newValue;
- }
-
- if
(command.isChangeInBooleanParameterNamed(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays,
- this.extendTermForRepaymentsOnHolidays)) {
- final Boolean newValue = command
-
.booleanPrimitiveValueOfParameterNamed(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays);
-
actualChanges.put(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays,
newValue);
- this.extendTermForRepaymentsOnHolidays = newValue;
- }
-
- return actualChanges;
- }
-
}
diff --git
a/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDaysEnumerations.java
b/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDaysEnumerations.java
index e3f9606285..c2caf64484 100644
---
a/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDaysEnumerations.java
+++
b/fineract-core/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDaysEnumerations.java
@@ -41,8 +41,8 @@ public final class WorkingDaysEnumerations {
case SAME_DAY:
optionData = new
EnumOptionData(RepaymentRescheduleType.SAME_DAY.getValue().longValue(),
RepaymentRescheduleType.SAME_DAY.getCode(), "same
day");
-
break;
+
case MOVE_TO_NEXT_WORKING_DAY:
optionData = new
EnumOptionData(RepaymentRescheduleType.MOVE_TO_NEXT_WORKING_DAY.getValue().longValue(),
RepaymentRescheduleType.MOVE_TO_NEXT_WORKING_DAY.getCode(), "move to next
working day");
@@ -52,10 +52,12 @@ public final class WorkingDaysEnumerations {
optionData = new
EnumOptionData(RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY.getValue().longValue(),
RepaymentRescheduleType.MOVE_TO_NEXT_REPAYMENT_MEETING_DAY.getCode(), "move to
next repayment meeting day");
break;
+
case MOVE_TO_PREVIOUS_WORKING_DAY:
optionData = new
EnumOptionData(RepaymentRescheduleType.MOVE_TO_PREVIOUS_WORKING_DAY.getValue().longValue(),
RepaymentRescheduleType.MOVE_TO_PREVIOUS_WORKING_DAY.getCode(), "move to
previous working day");
break;
+
case MOVE_TO_NEXT_MEETING_DAY:
optionData = new
EnumOptionData(RepaymentRescheduleType.MOVE_TO_NEXT_MEETING_DAY.getValue().longValue(),
RepaymentRescheduleType.MOVE_TO_NEXT_MEETING_DAY.getCode(), "move to next
meeting day");
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
index 6168cfc631..2aa14cb57e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/SecurityConfig.java
@@ -328,6 +328,13 @@ public class SecurityConfig {
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE,
"UPDATE_MIX_REPORT")
.requestMatchers(API_MATCHER.matcher(HttpMethod.DELETE,
"/api/*/mixreport/*"))
.hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE,
"DELETE_MIX_REPORT")
+ // working days
+ .requestMatchers(API_MATCHER.matcher(HttpMethod.GET,
"/api/*/workingdays"))
+ .hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_READ,
"READ_WORKING_DAYS")
+ .requestMatchers(API_MATCHER.matcher(HttpMethod.GET,
"/api/*/workingdays/template"))
+ .hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_READ,
"READ_WORKING_DAYS")
+ .requestMatchers(API_MATCHER.matcher(HttpMethod.PUT,
"/api/*/workingdays"))
+ .hasAnyAuthority(ALL_FUNCTIONS, ALL_FUNCTIONS_WRITE,
"UPDATE_WORKING_DAYS")
.requestMatchers(API_MATCHER.matcher(HttpMethod.POST,
"/api/*/twofactor/validate")).fullyAuthenticated()
.requestMatchers(API_MATCHER.matcher("/api/*/twofactor")).fullyAuthenticated()
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiResource.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiResource.java
index 1ec2298d25..d58dd0bfa9 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiResource.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/api/WorkingDaysApiResource.java
@@ -19,26 +19,23 @@
package org.apache.fineract.organisation.workingdays.api;
import io.swagger.v3.oas.annotations.Operation;
-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.tags.Tag;
+import jakarta.validation.Valid;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
+import java.time.Instant;
+import java.util.function.Supplier;
import lombok.RequiredArgsConstructor;
-import org.apache.fineract.commands.domain.CommandWrapper;
-import org.apache.fineract.commands.service.CommandWrapperBuilder;
-import
org.apache.fineract.commands.service.PortfolioCommandSourceWritePlatformService;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
-import
org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer;
-import
org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
+import org.apache.fineract.command.core.CommandPipeline;
+import
org.apache.fineract.organisation.workingdays.command.WorkingDaysUpdateCommand;
import org.apache.fineract.organisation.workingdays.data.WorkingDaysData;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequestValidator;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateResponse;
import
org.apache.fineract.organisation.workingdays.service.WorkingDaysReadPlatformService;
import org.springframework.stereotype.Component;
@@ -51,17 +48,15 @@ import org.springframework.stereotype.Component;
@RequiredArgsConstructor
public class WorkingDaysApiResource {
- private final DefaultToApiJsonSerializer<WorkingDaysData>
toApiJsonSerializer;
private final WorkingDaysReadPlatformService
workingDaysReadPlatformService;
- private final PortfolioCommandSourceWritePlatformService
commandsSourceWritePlatformService;
- private final PlatformSecurityContext context;
+ private final WorkingDaysUpdateRequestValidator
workingDaysUpdateRequestValidator;
+ private final CommandPipeline commandPipeline;
@GET
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "List Working days", description = "Example
Requests:\n" + "\n" + "workingdays")
public WorkingDaysData retrieveAll() {
-
this.context.authenticatedUser().validateHasReadPermission(WorkingDaysApiConstants.WORKING_DAYS_RESOURCE_NAME);
return this.workingDaysReadPlatformService.retrieve();
}
@@ -70,15 +65,17 @@ public class WorkingDaysApiResource {
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Update a Working Day", description = "Mandatory
Fields\n"
+
"recurrence,repaymentRescheduleType,extendTermForDailyRepayments,locale")
- @RequestBody(required = true, content = @Content(schema =
@Schema(implementation =
WorkingDaysApiResourceSwagger.PutWorkingDaysRequest.class)))
- @ApiResponse(responseCode = "200", description = "OK", content =
@Content(schema = @Schema(implementation =
WorkingDaysApiResourceSwagger.PutWorkingDaysResponse.class)))
- public String update(@Parameter(hidden = true) final String
jsonRequestBody) {
+ public WorkingDaysUpdateResponse update(@Valid WorkingDaysUpdateRequest
request) {
- final CommandWrapper commandRequest = new
CommandWrapperBuilder().updateWorkingDays().withJson(jsonRequestBody).build();
+ final var command = new WorkingDaysUpdateCommand();
- final CommandProcessingResult result =
this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
+ command.setCommandId(System.currentTimeMillis());
+ command.setCreatedAt(Instant.now());
+ command.setPayload(request);
- return this.toApiJsonSerializer.serialize(result);
+ final Supplier<WorkingDaysUpdateResponse> response =
commandPipeline.send(command);
+
+ return response.get();
}
@GET
@@ -87,10 +84,7 @@ public class WorkingDaysApiResource {
@Produces({ MediaType.APPLICATION_JSON })
@Operation(summary = "Working Days Template", description = "This is a
convenience resource. It can be useful when building maintenance user interface
screens for working days.\n"
+ "\n" + "Example Request:\n" + "\n" + "workingdays/template")
- @ApiResponse(responseCode = "200", description = "OK", content =
@Content(schema = @Schema(implementation =
WorkingDaysApiResourceSwagger.GetWorkingDaysTemplateResponse.class)))
public WorkingDaysData template() {
-
this.context.authenticatedUser().validateHasReadPermission(WorkingDaysApiConstants.WORKING_DAYS_RESOURCE_NAME);
-
return this.workingDaysReadPlatformService.repaymentRescheduleType();
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/command/WorkingDaysUpdateCommand.java
old mode 100755
new mode 100644
similarity index 68%
copy from
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
copy to
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/command/WorkingDaysUpdateCommand.java
index dcdb3d1e40..d9fb669316
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/command/WorkingDaysUpdateCommand.java
@@ -16,12 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.fineract.organisation.workingdays.service;
+package org.apache.fineract.organisation.workingdays.command;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.apache.fineract.command.core.Command;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;
-public interface WorkingDaysWritePlatformService {
-
- CommandProcessingResult updateWorkingDays(JsonCommand command);
-}
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class WorkingDaysUpdateCommand extends
Command<WorkingDaysUpdateRequest> {}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java
index 8c3e365c18..97416f3806 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDayValidator.java
@@ -37,6 +37,7 @@ import
org.apache.fineract.organisation.workingdays.api.WorkingDaysApiConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
+//Not used
@Component
public class WorkingDayValidator {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java
index ef2e62ab7b..24d778779e 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysData.java
@@ -21,12 +21,18 @@ package org.apache.fineract.organisation.workingdays.data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Collection;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
+import lombok.experimental.FieldNameConstants;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
+@Builder
@Data
@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
public class WorkingDaysData implements Serializable {
@Serial
@@ -42,37 +48,7 @@ public class WorkingDaysData implements Serializable {
private Boolean extendTermForRepaymentsOnHolidays;
- // template date
@SuppressWarnings("unused")
private Collection<EnumOptionData> repaymentRescheduleOptions;
- public WorkingDaysData(Long id, String recurrence, EnumOptionData
repaymentRescheduleType, Boolean extendTermForDailyRepayments,
- Boolean extendTermForRepaymentsOnHolidays) {
- this.id = id;
- this.recurrence = recurrence;
- this.repaymentRescheduleType = repaymentRescheduleType;
- this.repaymentRescheduleOptions = null;
- this.extendTermForDailyRepayments = extendTermForDailyRepayments;
- this.extendTermForRepaymentsOnHolidays =
extendTermForRepaymentsOnHolidays;
- }
-
- public WorkingDaysData(Long id, String recurrence, EnumOptionData
repaymentRescheduleType,
- Collection<EnumOptionData> repaymentRescheduleOptions, Boolean
extendTermForDailyRepayments,
- Boolean extendTermForRepaymentsOnHolidays) {
- this.id = id;
- this.recurrence = recurrence;
- this.repaymentRescheduleType = repaymentRescheduleType;
- this.repaymentRescheduleOptions = repaymentRescheduleOptions;
- this.extendTermForDailyRepayments = extendTermForDailyRepayments;
- this.extendTermForRepaymentsOnHolidays =
extendTermForRepaymentsOnHolidays;
- }
-
- public WorkingDaysData(WorkingDaysData data, Collection<EnumOptionData>
repaymentRescheduleOptions) {
- this.id = data.id;
- this.recurrence = data.recurrence;
- this.repaymentRescheduleType = data.repaymentRescheduleType;
- this.repaymentRescheduleOptions = repaymentRescheduleOptions;
- this.extendTermForDailyRepayments = data.extendTermForDailyRepayments;
- this.extendTermForRepaymentsOnHolidays =
data.extendTermForRepaymentsOnHolidays;
- }
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequest.java
old mode 100755
new mode 100644
similarity index 53%
copy from
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
copy to
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequest.java
index dcdb3d1e40..8eebb989b7
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequest.java
@@ -16,12 +16,32 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.fineract.organisation.workingdays.service;
+package org.apache.fineract.organisation.workingdays.data;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import java.io.Serial;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
-public interface WorkingDaysWritePlatformService {
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class WorkingDaysUpdateRequest implements Serializable {
+
+ @Serial
+ public static final long serialVersionUID = 1L;
+
+ private String recurrence;
+
+ private Integer repaymentRescheduleType;
+
+ private Boolean extendTermForDailyRepayments;
+
+ private Boolean extendTermForRepaymentsOnHolidays;
- CommandProcessingResult updateWorkingDays(JsonCommand command);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequestValidator.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequestValidator.java
new file mode 100644
index 0000000000..b0a8317834
--- /dev/null
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateRequestValidator.java
@@ -0,0 +1,62 @@
+/**
+ * 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.organisation.workingdays.data;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
+import
org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
+import
org.apache.fineract.organisation.workingdays.api.WorkingDaysApiConstants;
+import org.springframework.stereotype.Component;
+
+@Component
+public class WorkingDaysUpdateRequestValidator {
+
+ public void validateForUpdate(final WorkingDaysUpdateRequest request) {
+
+ List<ApiParameterError> validationErrors = new ArrayList<>();
+ DataValidatorBuilder validator = new
DataValidatorBuilder(validationErrors)
+ .resource(WorkingDaysApiConstants.WORKING_DAYS_RESOURCE_NAME);
+
+ // recurrence (mandatory)
+ String recurrence = request.getRecurrence();
+
validator.reset().parameter(WorkingDaysApiConstants.recurrence).value(recurrence).notNull();
+
+ // repaymentRescheduleType (optional, but must be 1–4 if present)
+
validator.reset().parameter(WorkingDaysApiConstants.repayment_rescheduling_enum).value(request.getRepaymentRescheduleType())
+ .ignoreIfNull().inMinMaxRange(1, 4);
+
+ // extendTermForDailyRepayments (optional but must be boolean if
provided)
+
validator.reset().parameter(WorkingDaysApiConstants.extendTermForDailyRepayments).value(request.getExtendTermForDailyRepayments())
+ .ignoreIfNull().validateForBooleanValue();
+
+ // extendTermForRepaymentsOnHolidays (optional but must be boolean if
provided)
+
validator.reset().parameter(WorkingDaysApiConstants.extendTermForRepaymentsOnHolidays)
+
.value(request.getExtendTermForRepaymentsOnHolidays()).ignoreIfNull().validateForBooleanValue();
+
+ throwExceptionIfValidationWarningsExist(validationErrors);
+ }
+
+ private void throwExceptionIfValidationWarningsExist(final
List<ApiParameterError> validationErrors) {
+ if (!validationErrors.isEmpty()) {
+ throw new PlatformApiDataValidationException(validationErrors);
+ }
+ }
+}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateResponse.java
old mode 100755
new mode 100644
similarity index 54%
copy from
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
copy to
fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateResponse.java
index dcdb3d1e40..725c3e9e77
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/data/WorkingDaysUpdateResponse.java
@@ -16,12 +16,28 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.fineract.organisation.workingdays.service;
+package org.apache.fineract.organisation.workingdays.data;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
-public interface WorkingDaysWritePlatformService {
+@Builder
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WorkingDaysUpdateResponse implements Serializable {
- CommandProcessingResult updateWorkingDays(JsonCommand command);
+ @Serial
+ private static final long serialVersionUID = 1L;
+ private Long resourceId;
+ private String recurrence;
+ private Integer repaymentRescheduleType;
+ private Boolean extendTermForDailyRepayments;
+ private Boolean extendTermForRepaymentsOnHolidays;
+ private Map<String, Object> changes;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/handler/UpdateWorkingDaysCommandHandler.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/handler/UpdateWorkingDaysCommandHandler.java
index 0f1fc6bad1..2528d818f8 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/handler/UpdateWorkingDaysCommandHandler.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/handler/UpdateWorkingDaysCommandHandler.java
@@ -18,29 +18,38 @@
*/
package org.apache.fineract.organisation.workingdays.handler;
-import org.apache.fineract.commands.annotation.CommandType;
-import org.apache.fineract.commands.handler.NewCommandSourceHandler;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import java.util.Collections;
+import java.util.Map;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.command.core.Command;
+import org.apache.fineract.command.core.CommandHandler;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateResponse;
import
org.apache.fineract.organisation.workingdays.service.WorkingDaysWritePlatformService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
+import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
-@Service
-@CommandType(entity = "WORKINGDAYS", action = "UPDATE")
-public class UpdateWorkingDaysCommandHandler implements
NewCommandSourceHandler {
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class UpdateWorkingDaysCommandHandler implements
CommandHandler<WorkingDaysUpdateRequest, WorkingDaysUpdateResponse> {
private final WorkingDaysWritePlatformService
workingDaysWritePlatformService;
- @Autowired
- public UpdateWorkingDaysCommandHandler(final
WorkingDaysWritePlatformService workingDaysWritePlatformService) {
- this.workingDaysWritePlatformService = workingDaysWritePlatformService;
- }
-
@Transactional
@Override
- public CommandProcessingResult processCommand(JsonCommand command) {
- return this.workingDaysWritePlatformService.updateWorkingDays(command);
+ public WorkingDaysUpdateResponse handle(Command<WorkingDaysUpdateRequest>
command) {
+ WorkingDaysUpdateRequest request = command.getPayload();
+ Map<String, Object> changes =
this.workingDaysWritePlatformService.updateWorkingDays(request);
+ if (changes == null) {
+ changes = Collections.emptyMap();
+ }
+
+ return WorkingDaysUpdateResponse.builder().resourceId((Long)
changes.get("resourceId")).changes(changes)
+
.recurrence(request.getRecurrence()).repaymentRescheduleType(request.getRepaymentRescheduleType())
+
.extendTermForDailyRepayments(request.getExtendTermForDailyRepayments())
+
.extendTermForRepaymentsOnHolidays(request.getExtendTermForRepaymentsOnHolidays()).build();
}
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java
index 59d6deeaa7..1b4ecbafc2 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysReadPlatformServiceImpl.java
@@ -65,7 +65,9 @@ public class WorkingDaysReadPlatformServiceImpl implements
WorkingDaysReadPlatfo
final Boolean extendTermForDailyRepayments =
rs.getBoolean("extendTermForDailyRepayments");
final Boolean extendTermForRepaymentsOnHolidays =
rs.getBoolean("extendTermForRepaymentsOnHolidays");
- return new WorkingDaysData(id, recurrence, status,
extendTermForDailyRepayments, extendTermForRepaymentsOnHolidays);
+ return
WorkingDaysData.builder().id(id).recurrence(recurrence).repaymentRescheduleType(status)
+ .extendTermForDailyRepayments(extendTermForDailyRepayments)
+
.extendTermForRepaymentsOnHolidays(extendTermForRepaymentsOnHolidays).build();
}
}
@@ -77,7 +79,11 @@ public class WorkingDaysReadPlatformServiceImpl implements
WorkingDaysReadPlatfo
final String sql = " select " + rm.schema();
WorkingDaysData data = this.jdbcTemplate.queryForObject(sql, rm);
// NOSONAR
Collection<EnumOptionData> repaymentRescheduleOptions =
repaymentRescheduleTypeOptions();
- return new WorkingDaysData(data, repaymentRescheduleOptions);
+ return
WorkingDaysData.builder().id(data.getId()).recurrence(data.getRecurrence())
+ .repaymentRescheduleType(data.getRepaymentRescheduleType())
+
.extendTermForDailyRepayments(data.getExtendTermForDailyRepayments())
+
.extendTermForRepaymentsOnHolidays(data.getExtendTermForRepaymentsOnHolidays())
+
.repaymentRescheduleOptions(repaymentRescheduleOptions).build();
} catch (final EmptyResultDataAccessException e) {
throw new WorkingDaysNotFoundException(e);
}
@@ -86,7 +92,7 @@ public class WorkingDaysReadPlatformServiceImpl implements
WorkingDaysReadPlatfo
@Override
public WorkingDaysData repaymentRescheduleType() {
Collection<EnumOptionData> repaymentRescheduleOptions =
repaymentRescheduleTypeOptions();
- return new WorkingDaysData(null, null, null,
repaymentRescheduleOptions, null, null);
+ return
WorkingDaysData.builder().repaymentRescheduleOptions(repaymentRescheduleOptions).build();
}
private Collection<EnumOptionData> repaymentRescheduleTypeOptions() {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
index dcdb3d1e40..411991cd65 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformService.java
@@ -18,10 +18,12 @@
*/
package org.apache.fineract.organisation.workingdays.service;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
+import java.util.Map;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;
+import org.springframework.transaction.annotation.Transactional;
public interface WorkingDaysWritePlatformService {
- CommandProcessingResult updateWorkingDays(JsonCommand command);
+ @Transactional
+ Map<String, Object> updateWorkingDays(WorkingDaysUpdateRequest request);
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformServiceJpaRepositoryImpl.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformServiceJpaRepositoryImpl.java
index b0611c28bf..c7e866bd6f 100755
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformServiceJpaRepositoryImpl.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/service/WorkingDaysWritePlatformServiceJpaRepositoryImpl.java
@@ -19,16 +19,15 @@
package org.apache.fineract.organisation.workingdays.service;
import java.text.ParseException;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Objects;
import lombok.RequiredArgsConstructor;
import net.fortuna.ical4j.model.property.RRule;
import net.fortuna.ical4j.validate.ValidationException;
-import org.apache.fineract.infrastructure.core.api.JsonCommand;
-import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
-import
org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import
org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
-import
org.apache.fineract.organisation.workingdays.api.WorkingDaysApiConstants;
-import org.apache.fineract.organisation.workingdays.data.WorkingDayValidator;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequestValidator;
import org.apache.fineract.organisation.workingdays.domain.WorkingDays;
import
org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.springframework.transaction.annotation.Transactional;
@@ -37,25 +36,27 @@ import
org.springframework.transaction.annotation.Transactional;
public class WorkingDaysWritePlatformServiceJpaRepositoryImpl implements
WorkingDaysWritePlatformService {
private final WorkingDaysRepositoryWrapper daysRepositoryWrapper;
- private final WorkingDayValidator fromApiJsonDeserializer;
+ private final WorkingDaysUpdateRequestValidator validator;
@Transactional
@Override
- public CommandProcessingResult updateWorkingDays(JsonCommand command) {
+ public Map<String, Object> updateWorkingDays(WorkingDaysUpdateRequest
request) {
String recurrence = "";
RRule rrule = null;
try {
- this.fromApiJsonDeserializer.validateForUpdate(command.json());
+ this.validator.validateForUpdate(request);
final WorkingDays workingDays =
this.daysRepositoryWrapper.findOne();
- recurrence =
command.stringValueOfParameterNamed(WorkingDaysApiConstants.recurrence);
+ recurrence = request.getRecurrence();
rrule = new RRule(recurrence);
rrule.validate();
- Map<String, Object> changes = workingDays.update(command);
+ Map<String, Object> changes = update(workingDays, request);
+ // include the current WorkingDays resource id in the changes for
response consumption
+ changes.put("resourceId", workingDays.getId());
this.daysRepositoryWrapper.saveAndFlush(workingDays);
- return new
CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(workingDays.getId()).with(changes)
- .build();
+ return changes;
+
} catch (final ValidationException e) {
throw new
PlatformDataIntegrityException("error.msg.invalid.recurring.rule",
"The Recurring Rule value: " + recurrence + " is not
valid.", "recurrence", recurrence, e);
@@ -65,4 +66,32 @@ public class
WorkingDaysWritePlatformServiceJpaRepositoryImpl implements Working
}
}
+ public HashMap<String, Object> update(WorkingDays workingDays,
WorkingDaysUpdateRequest request) {
+ HashMap<String, Object> changes = new HashMap<>();
+
+ if (!Objects.equals(request.getRecurrence(),
workingDays.getRecurrence())) {
+ workingDays.setRecurrence(request.getRecurrence());
+ changes.put("recurrence", request.getRecurrence());
+ }
+
+ Integer repaymentRescheduleType = request.getRepaymentRescheduleType();
+ if (repaymentRescheduleType != null &&
!Objects.equals(repaymentRescheduleType,
workingDays.getRepaymentReschedulingType())) {
+ workingDays.setRepaymentReschedulingType(repaymentRescheduleType);
+ changes.put("repaymentRescheduleType", repaymentRescheduleType);
+ }
+
+ Boolean extendDaily = request.getExtendTermForDailyRepayments();
+ if (extendDaily != null && !Objects.equals(extendDaily,
workingDays.getExtendTermForDailyRepayments())) {
+ workingDays.setExtendTermForDailyRepayments(extendDaily);
+ changes.put("extendTermForDailyRepayments", extendDaily);
+ }
+
+ Boolean extendHolidays =
request.getExtendTermForRepaymentsOnHolidays();
+ if (extendHolidays != null && !Objects.equals(extendHolidays,
workingDays.getExtendTermForRepaymentsOnHolidays())) {
+ workingDays.setExtendTermForRepaymentsOnHolidays(extendHolidays);
+ changes.put("extendTermForRepaymentsOnHolidays", extendHolidays);
+ }
+ return changes;
+ }
+
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/starter/OrganisationWorkingDaysConfiguration.java
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/starter/OrganisationWorkingDaysConfiguration.java
index 256909f513..14f0e5c096 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/starter/OrganisationWorkingDaysConfiguration.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/starter/OrganisationWorkingDaysConfiguration.java
@@ -18,7 +18,7 @@
*/
package org.apache.fineract.organisation.workingdays.starter;
-import org.apache.fineract.organisation.workingdays.data.WorkingDayValidator;
+import
org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequestValidator;
import
org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import
org.apache.fineract.organisation.workingdays.service.WorkingDaysReadPlatformService;
import
org.apache.fineract.organisation.workingdays.service.WorkingDaysReadPlatformServiceImpl;
@@ -41,7 +41,7 @@ public class OrganisationWorkingDaysConfiguration {
@Bean
@ConditionalOnMissingBean(WorkingDaysWritePlatformService.class)
public WorkingDaysWritePlatformService
workingDaysWritePlatformService(WorkingDaysRepositoryWrapper
daysRepositoryWrapper,
- WorkingDayValidator fromApiJsonDeserializer) {
- return new
WorkingDaysWritePlatformServiceJpaRepositoryImpl(daysRepositoryWrapper,
fromApiJsonDeserializer);
+ WorkingDaysUpdateRequestValidator validator) {
+ return new
WorkingDaysWritePlatformServiceJpaRepositoryImpl(daysRepositoryWrapper,
validator);
}
}