From 3260f76ca7d32fbb5ed93134c19f4d0e0e46e8a5 Mon Sep 17 00:00:00 2001 From: viktorpavlenko Date: Fri, 4 Apr 2025 15:02:40 +0300 Subject: [PATCH] FINERACT-2169: Refactor calendar controller and service; --- .../portfolio/calendar/data/CalendarData.java | 4 + .../data/request/CalendarRequest.java | 42 +++++ .../calendar/domain/CalendarEntityType.java | 25 +-- .../calendar/api/CalendarsApiResource.java | 148 ++++++------------ .../service/CalendarReadPlatformService.java | 2 +- .../CalendarReadPlatformServiceImpl.java | 4 +- 6 files changed, 107 insertions(+), 118 deletions(-) create mode 100644 fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/request/CalendarRequest.java diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java index b8c1fd463..04d16e0ae 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/CalendarData.java @@ -18,6 +18,7 @@ */ package org.apache.fineract.portfolio.calendar.data; +import java.io.Serial; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalTime; @@ -42,6 +43,9 @@ import org.apache.fineract.portfolio.common.domain.NthDayType; @Accessors(chain = true) public final class CalendarData implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + private Long id; private Long calendarInstanceId; private Long entityId; diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/request/CalendarRequest.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/request/CalendarRequest.java new file mode 100644 index 000000000..fc7e15b81 --- /dev/null +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/data/request/CalendarRequest.java @@ -0,0 +1,42 @@ +/** + * 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.portfolio.calendar.data.request; + +import java.io.Serial; +import java.io.Serializable; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class CalendarRequest implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + private String repeatsOnDay; + private String dateFormat; + private String repeating; + private String interval; + private String typeId; + private String locale; + private String title; + private String startDate; + private String frequency; +} diff --git a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarEntityType.java b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarEntityType.java index e487c9253..d08f47267 100644 --- a/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarEntityType.java +++ b/fineract-core/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarEntityType.java @@ -20,7 +20,9 @@ package org.apache.fineract.portfolio.calendar.domain; import java.util.HashMap; import java.util.Map; +import lombok.Getter; +@Getter public enum CalendarEntityType { INVALID(0, "calendarEntityType.invalid"), // @@ -40,16 +42,10 @@ public enum CalendarEntityType { this.code = code; } - public Integer getValue() { - return this.value; - } - - public String getCode() { - return this.code; - } - private static final Map intToEnumMap = new HashMap<>(); + @Getter private static int minValue; + @Getter private static int maxValue; static { @@ -70,21 +66,12 @@ public enum CalendarEntityType { } public static CalendarEntityType fromInt(final int i) { - final CalendarEntityType entityType = intToEnumMap.get(Integer.valueOf(i)); - return entityType; - } - - public static int getMinValue() { - return minValue; - } - - public static int getMaxValue() { - return maxValue; + return intToEnumMap.get(i); } @Override public String toString() { - return name().toString(); + return name(); } public static boolean isGroup(final Integer value) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java index f4276dd0e..d418c9009 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/api/CalendarsApiResource.java @@ -18,6 +18,12 @@ */ package org.apache.fineract.portfolio.calendar.api; +import static org.apache.fineract.portfolio.calendar.domain.CalendarEntityType.CENTERS; +import static org.apache.fineract.portfolio.calendar.domain.CalendarEntityType.CLIENTS; +import static org.apache.fineract.portfolio.calendar.domain.CalendarEntityType.GROUPS; +import static org.apache.fineract.portfolio.calendar.domain.CalendarEntityType.LOANS; +import static org.apache.fineract.portfolio.calendar.domain.CalendarEntityType.SAVINGS; + import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.ws.rs.Consumes; import jakarta.ws.rs.DELETE; @@ -34,10 +40,9 @@ import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.UriInfo; import java.time.LocalDate; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.domain.CommandWrapper; @@ -51,7 +56,7 @@ import org.apache.fineract.infrastructure.core.serialization.ApiRequestJsonSeria import org.apache.fineract.infrastructure.core.serialization.DefaultToApiJsonSerializer; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.portfolio.calendar.data.CalendarData; -import org.apache.fineract.portfolio.calendar.domain.Calendar; +import org.apache.fineract.portfolio.calendar.data.request.CalendarRequest; import org.apache.fineract.portfolio.calendar.domain.CalendarEntityType; import org.apache.fineract.portfolio.calendar.exception.CalendarEntityTypeNotSupportedException; import org.apache.fineract.portfolio.calendar.service.CalendarDropdownReadPlatformService; @@ -65,15 +70,6 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class CalendarsApiResource { - /** - * The set of parameters that are supported in response for {@link Calendar} - */ - private static final Set RESPONSE_DATA_PARAMETERS = new HashSet<>( - Arrays.asList("id", "entityId", "entityType", "title", "description", "location", "startDate", "endDate", "duration", "type", - "repeating", "recurrence", "frequency", "interval", "repeatsOnDay", "remindBy", "firstReminder", "secondReminder", - "humanReadable", "createdDate", "lastUpdatedDate", "createdByUserId", "createdByUsername", "lastUpdatedByUserId", - "lastUpdatedByUsername", "recurringDates", "nextTenRecurringDates", "entityTypeOptions", "calendarTypeOptions", - "remindByOptions", "frequencyOptions", "repeatsOnDayOptions")); private static final String RESOURCE_NAME_FOR_PERMISSIONS = "CALENDAR"; private final PlatformSecurityContext context; @@ -87,26 +83,23 @@ public class CalendarsApiResource { @Path("{calendarId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveCalendar(@PathParam("calendarId") final Long calendarId, @PathParam("entityType") final String entityType, + public CalendarData retrieveCalendar(@PathParam("calendarId") final Long calendarId, @PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, @Context final UriInfo uriInfo) { - this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); + context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); final Integer entityTypeId = CalendarEntityType.valueOf(entityType.toUpperCase()).getValue(); - CalendarData calendarData = this.readPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId); + final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - // Include recurring date details - final boolean withHistory = true; - final LocalDate tillDate = null; - final Collection recurringDates = this.readPlatformService.generateRecurringDates(calendarData, withHistory, tillDate); - final Collection nextTenRecurringDates = this.readPlatformService.generateNextTenRecurringDates(calendarData); - final LocalDate recentEligibleMeetingDate = null; - calendarData = CalendarData.withRecurringDates(calendarData, recurringDates, nextTenRecurringDates, recentEligibleMeetingDate); + CalendarData calendarData = readPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId); + final Collection recurringDates = readPlatformService.generateRecurringDates(calendarData, true, null); + final Collection nextTenRecurringDates = readPlatformService.generateNextTenRecurringDates(calendarData); + calendarData.setRecurringDates(recurringDates); + calendarData.setNextTenRecurringDates(nextTenRecurringDates); - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); if (settings.isTemplate()) { calendarData = handleTemplate(calendarData); } - return this.toApiJsonSerializer.serialize(settings, calendarData, RESPONSE_DATA_PARAMETERS); + return calendarData; } /** @@ -119,53 +112,42 @@ public class CalendarsApiResource { @GET @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveCalendarsByEntity(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, - @Context final UriInfo uriInfo, @DefaultValue("all") @QueryParam("calendarType") final String calendarType) { - - this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); + public List retrieveCalendarsByEntity(@PathParam("entityType") final String entityType, + @PathParam("entityId") final Long entityId, @Context final UriInfo uriInfo, + @DefaultValue("all") @QueryParam("calendarType") final String calendarType) { + context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); final Set associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); - - Collection calendarsData = new ArrayList<>(); + final List calendarsData = new ArrayList<>(); final List calendarTypeOptions = CalendarUtils.createIntegerListFromQueryParameter(calendarType); if (!associationParameters.isEmpty() && associationParameters.contains("parentCalendars")) { - calendarsData.addAll(this.readPlatformService.retrieveParentCalendarsByEntity(entityId, + calendarsData.addAll(readPlatformService.retrieveParentCalendarsByEntity(entityId, CalendarEntityType.valueOf(entityType.toUpperCase()).getValue(), calendarTypeOptions)); } - calendarsData.addAll(this.readPlatformService.retrieveCalendarsByEntity(entityId, + calendarsData.addAll(readPlatformService.retrieveCalendarsByEntity(entityId, CalendarEntityType.valueOf(entityType.toUpperCase()).getValue(), calendarTypeOptions)); - // Add recurring dates - calendarsData = this.readPlatformService.updateWithRecurringDates(calendarsData); - - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, calendarsData, RESPONSE_DATA_PARAMETERS); + return readPlatformService.updateWithRecurringDates(calendarsData); } @GET @Path("template") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveNewCalendarDetails(@Context final UriInfo uriInfo, @PathParam("entityType") final String entityType, + public CalendarData retrieveNewCalendarDetails(@Context final UriInfo uriInfo, @PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId) { - - this.context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); - - CalendarData calendarData = this.readPlatformService.retrieveNewCalendarDetails(); - calendarData = handleTemplate(calendarData); - - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, calendarData, RESPONSE_DATA_PARAMETERS); + context.authenticatedUser().validateHasReadPermission(RESOURCE_NAME_FOR_PERMISSIONS); + return handleTemplate(readPlatformService.retrieveNewCalendarDetails()); } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String createCalendar(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, - final String apiRequestBodyAsJson) { + public CommandProcessingResult createCalendar(@PathParam("entityType") final String entityType, + @PathParam("entityId") final Long entityId, CalendarRequest calendarRequest) { final CalendarEntityType calendarEntityType = CalendarEntityType.getEntityType(entityType); if (calendarEntityType == null) { @@ -174,11 +156,9 @@ public class CalendarsApiResource { final CommandWrapper resourceDetails = getResourceDetails(calendarEntityType, entityId); final CommandWrapper commandRequest = new CommandWrapperBuilder().createCalendar(resourceDetails, entityType, entityId) - .withJson(apiRequestBodyAsJson).build(); + .withJson(toApiJsonSerializer.serialize(calendarRequest)).build(); - final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - - return this.toApiJsonSerializer.serialize(result); + return commandsSourceWritePlatformService.logCommandSource(commandRequest); } @@ -186,69 +166,45 @@ public class CalendarsApiResource { @Path("{calendarId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateCalendar(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, - @PathParam("calendarId") final Long calendarId, final String jsonRequestBody) { + public CommandProcessingResult updateCalendar(@PathParam("entityType") final String entityType, + @PathParam("entityId") final Long entityId, @PathParam("calendarId") final Long calendarId, final String jsonRequestBody) { final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCalendar(entityType, entityId, calendarId) .withJson(jsonRequestBody).build(); - final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - - return this.toApiJsonSerializer.serialize(result); + return commandsSourceWritePlatformService.logCommandSource(commandRequest); } @DELETE @Path("{calendarId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String deleteCalendar(@PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, - @PathParam("calendarId") final Long calendarId) { + public CommandProcessingResult deleteCalendar(@PathParam("entityType") final String entityType, + @PathParam("entityId") final Long entityId, @PathParam("calendarId") final Long calendarId) { final CommandWrapper commandRequest = new CommandWrapperBuilder().deleteCalendar(entityType, entityId, calendarId).build(); - final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); - - return this.toApiJsonSerializer.serialize(result); + return commandsSourceWritePlatformService.logCommandSource(commandRequest); } private CalendarData handleTemplate(final CalendarData calendarData) { - final List entityTypeOptions = this.dropdownReadPlatformService.retrieveCalendarEntityTypeOptions(); - final List calendarTypeOptions = this.dropdownReadPlatformService.retrieveCalendarTypeOptions(); - final List remindByOptions = this.dropdownReadPlatformService.retrieveCalendarRemindByOptions(); - final List frequencyOptions = this.dropdownReadPlatformService.retrieveCalendarFrequencyTypeOptions(); - final List repeatsOnDayOptions = this.dropdownReadPlatformService.retrieveCalendarWeekDaysTypeOptions(); - final List frequencyNthDayTypeOptions = this.dropdownReadPlatformService - .retrieveCalendarFrequencyNthDayTypeOptions(); - return CalendarData.withTemplateOptions(calendarData, entityTypeOptions, calendarTypeOptions, remindByOptions, frequencyOptions, - repeatsOnDayOptions, frequencyNthDayTypeOptions); + final List entityTypeOptions = dropdownReadPlatformService.retrieveCalendarEntityTypeOptions(); + final List calendarTypeOptions = dropdownReadPlatformService.retrieveCalendarTypeOptions(); + final List remindByOptions = dropdownReadPlatformService.retrieveCalendarRemindByOptions(); + final List frequencyOptions = dropdownReadPlatformService.retrieveCalendarFrequencyTypeOptions(); + final List repeatsOnDayOptions = dropdownReadPlatformService.retrieveCalendarWeekDaysTypeOptions(); + final List frequencyNthDayTypeOptions = dropdownReadPlatformService.retrieveCalendarFrequencyNthDayTypeOptions(); + + return calendarData.setEntityTypeOptions(entityTypeOptions).setCalendarTypeOptions(calendarTypeOptions) + .setRemindByOptions(remindByOptions).setFrequencyOptions(frequencyOptions).setRepeatsOnDayOptions(repeatsOnDayOptions) + .setFrequencyNthDayTypeOptions(frequencyNthDayTypeOptions); } private CommandWrapper getResourceDetails(final CalendarEntityType type, final Long entityId) { - CommandWrapperBuilder resourceDetails = new CommandWrapperBuilder(); - switch (type) { - case CENTERS: - resourceDetails.withGroupId(entityId); - break; - case CLIENTS: - resourceDetails.withClientId(entityId); - break; - case GROUPS: - resourceDetails.withGroupId(entityId); - break; - case LOANS: - resourceDetails.withLoanId(entityId); - break; - case SAVINGS: - resourceDetails.withSavingsId(entityId); - break; - case INVALID: - break; - case LOAN_RECALCULATION_REST_DETAIL: - break; - default: - break; - } - return resourceDetails.build(); + final CommandWrapperBuilder resourceDetails = new CommandWrapperBuilder(); + return Map.of(CENTERS, resourceDetails.withGroupId(entityId).build(), CLIENTS, resourceDetails.withClientId(entityId).build(), + GROUPS, resourceDetails.withGroupId(entityId).build(), LOANS, resourceDetails.withLoanId(entityId).build(), SAVINGS, + resourceDetails.withSavingsId(entityId).build()).getOrDefault(type, resourceDetails.build()); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java index a98b49362..c6ba6a1e7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformService.java @@ -40,7 +40,7 @@ public interface CalendarReadPlatformService { Collection generateNextTenRecurringDates(CalendarData calendarData); - Collection updateWithRecurringDates(Collection calendarsData); + List updateWithRecurringDates(Collection calendarsData); CalendarData retrieveLoanCalendar(Long loanId); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java index 5c4cb8a26..cf3553d24 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java @@ -355,8 +355,8 @@ public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformServ } @Override - public Collection updateWithRecurringDates(final Collection calendarsData) { - final Collection recuCalendarsData = new ArrayList<>(); + public List updateWithRecurringDates(final Collection calendarsData) { + final List recuCalendarsData = new ArrayList<>(); final boolean withHistory = true; final LocalDate tillDate = null; for (final CalendarData calendarData : calendarsData) {