Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ licenses
**/.asciidoctor/diagram/*
**/images/diag-*.svg

fineract-provider/src/main/generated/

**/out/
gradleExp/

Expand Down
20 changes: 20 additions & 0 deletions config/docker/env/mariadb.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# 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.
#

MARIADB_ROOT_PASSWORD=mysql
34 changes: 34 additions & 0 deletions docker-compose-mariadb.yml
Original file line number Diff line number Diff line change
@@ -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:
mariadb:
container_name: mariadb
image: mariadb:11.4
volumes:
- ./config/docker/mysql/conf.d/server_collation.cnf:/etc/mysql/conf.d/server_collation.cnf:ro
- ./config/docker/mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d:Z,ro
restart: always
env_file:
- ./config/docker/env/mariadb.env
healthcheck:
test: [ "CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized" ]
timeout: 10s
retries: 10
ports:
- "3306:3306"
34 changes: 34 additions & 0 deletions docker-compose-mysql.yml
Original file line number Diff line number Diff line change
@@ -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"
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,21 @@
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> {

Expand All @@ -47,51 +52,57 @@ 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;
}
// 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;
// }
//
// public Map<String, Object> update(WorkingDaysUpdateRequest request) {
//
// }

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ public static EnumOptionData repaymentRescheduleType(final RepaymentRescheduleTy
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");
Expand All @@ -52,10 +52,12 @@ public static EnumOptionData repaymentRescheduleType(final RepaymentRescheduleTy
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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_CURRENCY")
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/currencies"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_CURRENCY")
// working days
.requestMatchers(antMatcher(HttpMethod.GET, "/api/*/workingdays"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_WORKING_DAYS")
.requestMatchers(antMatcher(HttpMethod.GET, "api/*/workingdays/template"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_READ", "READ_WORKING_DAYS")
.requestMatchers(antMatcher(HttpMethod.PUT, "/api/*/workingdays"))
.hasAnyAuthority("ALL_FUNCTIONS", "ALL_FUNCTIONS_WRITE", "UPDATE_WORKING_DAYS")
// ...
.requestMatchers(antMatcher(HttpMethod.POST, "/api/*/twofactor/validate")).fullyAuthenticated() //
.requestMatchers(antMatcher("/api/*/twofactor")).fullyAuthenticated() //
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,24 @@
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.responses.ApiResponses;
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.util.UUID;
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.infrastructure.core.service.DateUtils;
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;

Expand All @@ -52,17 +49,15 @@
@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();
}

Expand All @@ -71,16 +66,17 @@ public WorkingDaysData retrieveAll() {
@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)))
@ApiResponses({
@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.setId(UUID.randomUUID());
command.setCreatedAt(DateUtils.getAuditOffsetDateTime());
command.setPayload(request);

return this.toApiJsonSerializer.serialize(result);
final Supplier<WorkingDaysUpdateResponse> response = commandPipeline.send(command);

return response.get();
}

@GET
Expand All @@ -89,11 +85,7 @@ public String update(@Parameter(hidden = true) final String jsonRequestBody) {
@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")
@ApiResponses({
@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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 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.command;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.fineract.command.core.Command;
import org.apache.fineract.organisation.workingdays.data.WorkingDaysUpdateRequest;

@Data
@EqualsAndHashCode(callSuper = true)
public class WorkingDaysUpdateCommand extends Command<WorkingDaysUpdateRequest> {}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//Not used
@Component
public class WorkingDayValidator {

Expand Down
Loading