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


Reply via email to