From 194510964744d6c68ea2aff3ff0443e096863220 Mon Sep 17 00:00:00 2001 From: ashok-conflux Date: Fri, 1 Mar 2013 21:35:02 +0530 Subject: [PATCH] Implemented basic Calendar services, GET, POST and PUT --- mifosng-db/patches/16-calendar_table.sql | 19 ++ .../patches/17-calendar_permissions.sql | 8 + .../commands/domain/CommandWrapper.java | 22 +- .../service/CommandWrapperBuilder.java | 28 +- ...CommandSourceWritePlatformServiceImpl.java | 4 +- .../SynchronousCommandProcessingService.java | 10 + .../infrastructure/core/api/JsonCommand.java | 23 +- .../portfolio/calendar/CalendarConstants.java | 41 +++ .../calendar/api/CalendarsApiResource.java | 172 ++++++++++ .../calendar/command/CalendarCommand.java | 57 ++++ .../portfolio/calendar/data/CalendarData.java | 113 +++++++ .../portfolio/calendar/domain/Calendar.java | 316 ++++++++++++++++++ .../calendar/domain/CalendarEntityType.java | 64 ++++ .../calendar/domain/CalendarRemindBy.java | 63 ++++ .../calendar/domain/CalendarRepository.java | 8 + .../calendar/domain/CalendarType.java | 64 ++++ .../exception/CalendarNotFoundException.java | 18 + .../handler/CreateCalendarCommandHandler.java | 32 ++ .../handler/DeleteCalendarCommandHandler.java | 31 ++ .../handler/UpdateCalendarCommandHandler.java | 28 ++ ...alendarCommandFromApiJsonDeserializer.java | 262 +++++++++++++++ .../CalendarDropdownReadPlatformService.java | 20 ++ ...lendarDropdownReadPlatformServiceImpl.java | 29 ++ .../service/CalendarEnumerations.java | 63 ++++ .../service/CalendarReadPlatformService.java | 21 ++ .../CalendarReadPlatformServiceImpl.java | 110 ++++++ .../service/CalendarWritePlatformService.java | 13 + ...WritePlatformServiceJpaRepositoryImpl.java | 81 +++++ 28 files changed, 1710 insertions(+), 10 deletions(-) create mode 100644 mifosng-db/patches/16-calendar_table.sql create mode 100644 mifosng-db/patches/17-calendar_permissions.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/CalendarConstants.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/command/CalendarCommand.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/data/CalendarData.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/Calendar.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarEntityType.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRemindBy.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRepository.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarType.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/exception/CalendarNotFoundException.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/CreateCalendarCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/DeleteCalendarCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/UpdateCalendarCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarEnumerations.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformServiceJpaRepositoryImpl.java diff --git a/mifosng-db/patches/16-calendar_table.sql b/mifosng-db/patches/16-calendar_table.sql new file mode 100644 index 000000000..0257082b5 --- /dev/null +++ b/mifosng-db/patches/16-calendar_table.sql @@ -0,0 +1,19 @@ +CREATE TABLE IF NOT EXISTS `m_calendar` ( + `id` bigint(20) NOT NULL AUTO_INCREMENT, + `entity_id` bigint(20) NOT NULL DEFAULT '0', + `entity_type_enum` smallint(5) NOT NULL DEFAULT '0', + `title` varchar(50) NOT NULL, + `description` varchar(100) DEFAULT NULL, + `location` varchar(50) DEFAULT NULL, + `start_date` date NOT NULL, + `end_date` date DEFAULT NULL, + `created_date` datetime DEFAULT NULL, + `duration` smallint(6) DEFAULT NULL, + `calendar_type_enum` smallint(5) NOT NULL, + `repeating` tinyint(1) NOT NULL DEFAULT '0', + `recurrence` varchar(100) NOT NULL, + `remind_by_enum` smallint(5) DEFAULT NULL, + `first_reminder` smallint(11) NOT NULL, + `second_reminder` smallint(11) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/mifosng-db/patches/17-calendar_permissions.sql b/mifosng-db/patches/17-calendar_permissions.sql new file mode 100644 index 000000000..77561ffda --- /dev/null +++ b/mifosng-db/patches/17-calendar_permissions.sql @@ -0,0 +1,8 @@ +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) +VALUES('configuration', 'CREATE_CALENDAR', 'CALENDAR', 'CREATE', '0'), +('configuration', 'READ_CALENDAR', 'CALENDAR', 'READ', '0'), +('configuration', 'UPDATE_CALENDAR', 'CALENDAR', 'UPDATE', '0'), +('configuration', 'DELETE_CALENDAR', 'CALENDAR', 'DELETE', '0'), +('configuration', 'CREATE_CALENDAR_CHECKER', 'CALENDAR', 'CREATE', '0'), +('configuration', 'UPDATE_CALENDAR_CHECKER', 'CALENDAR', 'UPDATE', '0'), +('configuration', 'DELETE_CALENDAR_CHECKER', 'CALENDAR', 'DELETE', '0'); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java index 0502359df..a971c11fa 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/domain/CommandWrapper.java @@ -23,6 +23,8 @@ public class CommandWrapper { private final Long datatableId; private final Long codeId; private final String transactionId; + private String supportedEntityType; + private Long supportedEntityId; public static CommandWrapper wrap(final String actionName, final String enityName, final Long resourceId) { return new CommandWrapper(null, actionName, enityName, resourceId); @@ -46,14 +48,16 @@ public class CommandWrapper { this.apptableId = null; this.datatableId = null; this.codeId = null; + this.supportedEntityType = null; + this.supportedEntityId = null; this.href = null; this.json = null; this.transactionId = null; } public CommandWrapper(final Long officeId, final Long groupId, final Long clientId, final Long loanId, final String actionName, - final String entityName, final Long entityId, final Long apptableId, final Long datatableId, final Long codeId, final String href, - final String json, final String transactionId) { + final String entityName, final Long entityId, final Long apptableId, final Long datatableId, final Long codeId, + final String supportedEntityType, final Long supportedEntityId, final String href, final String json, final String transactionId) { this.commandId = null; this.officeId = officeId; this.groupId = groupId; @@ -66,6 +70,8 @@ public class CommandWrapper { this.apptableId = apptableId; this.datatableId = datatableId; this.codeId = codeId; + this.supportedEntityType = supportedEntityType; + this.supportedEntityId = supportedEntityId; this.href = href; this.json = json; this.transactionId = transactionId; @@ -143,6 +149,14 @@ public class CommandWrapper { return this.datatableId; } + public Long getSupportedEntityId() { + return this.supportedEntityId; + } + + public String getSupportedEntityType() { + return this.supportedEntityType; + } + public boolean isUpdate() { // permissions resource has special update which involves no resource. return (isPermissionResource() && isUpdateOperation()) || (isCurrencyResource() && isUpdateOperation()) @@ -431,4 +445,8 @@ public class CommandWrapper { + public boolean isCalendarResource() { + return this.entityName.equalsIgnoreCase("CALENDAR"); + } + } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java index c8b7b6515..086ade266 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/CommandWrapperBuilder.java @@ -22,10 +22,12 @@ public class CommandWrapperBuilder { private Long datatableId; private Long codeId; private String transactionId; + private String supportedEntityType; + private Long supportedEntityId; public CommandWrapper build() { return new CommandWrapper(this.officeId, this.groupId, this.clientId, this.loanId, this.actionName, this.entityName, this.entityId, - this.apptableId, this.datatableId, this.codeId, this.href, this.json, this.transactionId); + this.apptableId, this.datatableId, this.codeId, this.supportedEntityType, this.supportedEntityId, this.href, this.json, this.transactionId); } // public CommandWrapperBuilder withEntityId(final Long withId) { @@ -866,4 +868,28 @@ public class CommandWrapperBuilder { return this; } + public CommandWrapperBuilder createCalendar(final String supportedEntityType, final Long supportedEntityId) { + this.actionName = "CREATE"; + this.entityName = "CALENDAR"; + this.supportedEntityType = supportedEntityType; + this.supportedEntityId = supportedEntityId; + this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/calendars/template"; + return this; + } + + public CommandWrapperBuilder updateCalendar(final String supportedEntityType, final Long supportedEntityId, final Long calendarId) { + this.actionName = "UPDATE"; + this.entityName = "CALENDAR"; + this.entityId = calendarId; + this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/calendars/" + calendarId; + return this; + } + + public CommandWrapperBuilder deleteCalendar(final String supportedEntityType, final Long supportedEntityId, final Long calendarId) { + this.actionName = "DELETE"; + this.entityName = "CALENDAR"; + this.entityId = calendarId; + this.href = "/" + supportedEntityType + "/" + supportedEntityId + "/calendars/" + calendarId; + return this; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java index 10fda9183..2b52ba4c1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/PortfolioCommandSourceWritePlatformServiceImpl.java @@ -58,7 +58,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio final JsonElement parsedCommand = this.fromApiJsonHelper.parse(json); final JsonCommand command = JsonCommand.from(json, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getApptableId(), - wrapper.getDatatableId(), wrapper.getCodeId(), wrapper.getTransactionId()); + wrapper.getDatatableId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(), wrapper.getTransactionId()); result = this.processAndLogCommandService.processAndLogCommand(wrapper, command, isApprovedByChecker); } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { @@ -68,7 +68,7 @@ public class PortfolioCommandSourceWritePlatformServiceImpl implements Portfolio final JsonElement parsedCommand = this.fromApiJsonHelper.parse(jsonToUse); final JsonCommand command = JsonCommand.from(jsonToUse, parsedCommand, this.fromApiJsonHelper, wrapper.getEntityName(), wrapper.getEntityId(), wrapper.getGroupId(), wrapper.getClientId(), wrapper.getLoanId(), wrapper.getApptableId(), - wrapper.getDatatableId(), wrapper.getCodeId(), wrapper.getTransactionId()); + wrapper.getDatatableId(), wrapper.getCodeId(), wrapper.getSupportedEntityType(), wrapper.getSupportedEntityId(), wrapper.getTransactionId()); result = this.processAndLogCommandService.logCommand(wrapper, command); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java index c840804a9..763669bb0 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/commands/service/SynchronousCommandProcessingService.java @@ -403,6 +403,16 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer } else { throw new UnsupportedCommandException(wrapper.commandName()); } + } else if (wrapper.isCalendarResource()) { + if (wrapper.isCreate()) { + handler = applicationContext.getBean("createCalendarCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isUpdate()) { + handler = applicationContext.getBean("updateCalendarCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isDelete()) { + handler = applicationContext.getBean("deleteCalendarCommandHandler", NewCommandSourceHandler.class); + } else { + throw new UnsupportedCommandException(wrapper.commandName()); + } } else { throw new UnsupportedCommandException(wrapper.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java index 14d519578..c2ecfb645 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/api/JsonCommand.java @@ -39,25 +39,28 @@ public final class JsonCommand { private final Long apptableId; private final Long datatableId; private final Long codeId; + private String supportedEntityType; + private Long supportedEntityId; private final String transactionId; public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long groupId, final Long clientId, final Long loanId, - final Long apptableId, final Long datatableId, final Long codeId, final String transactionId) { + final Long apptableId, final Long datatableId, final Long codeId, final String supportedEntityType, final Long supportedEntityId, + final String transactionId) { return new JsonCommand(null, jsonCommand, parsedCommand, fromApiJsonHelper, entityName, resourceId, groupId, clientId, loanId, - apptableId, datatableId, codeId, transactionId); + apptableId, datatableId, codeId, supportedEntityType, supportedEntityId, transactionId); } public static JsonCommand fromExistingCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, final Long resourceId) { return new JsonCommand(commandId, jsonCommand, parsedCommand, fromApiJsonHelper, null, resourceId, null, null, null, null, null, - null, null); + null, null, null, null); } public JsonCommand(final Long commandId, final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, final String entityName, final Long resourceId, final Long groupId, - final Long clientId, final Long loanId, final Long apptableId, final Long datatableId, final Long codeId, - final String transactionId) { + final Long clientId, final Long loanId, final Long apptableId, final Long datatableId, final Long codeId, + final String supportedEntityType, final Long supportedEntityId, final String transactionId) { this.commandId = commandId; this.jsonCommand = jsonCommand; this.parsedCommand = parsedCommand; @@ -70,6 +73,8 @@ public final class JsonCommand { this.apptableId = apptableId; this.datatableId = datatableId; this.codeId = codeId; + this.supportedEntityType = supportedEntityType; + this.supportedEntityId = supportedEntityId; this.transactionId = transactionId; } @@ -116,7 +121,15 @@ public final class JsonCommand { public Long getCodeId() { return this.codeId; } + + public Long getSupportedEntityId() { + return this.supportedEntityId; + } + public String getSupportedEntityType() { + return this.supportedEntityType; + } + public String getTransactionId(){ return this.transactionId; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/CalendarConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/CalendarConstants.java new file mode 100644 index 000000000..0fe2b0dca --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/CalendarConstants.java @@ -0,0 +1,41 @@ +package org.mifosplatform.portfolio.calendar; + +import java.util.HashSet; +import java.util.Set; + +public class CalendarConstants { + + public static enum CALENDAR_SUPPORTED_PARAMETERS { + CALENDAR_ID("id"), ENTITY_TYPE("entityType"), ENTITY_ID("entityId"), TITLE("title"), DESCRIPTION("description"), LOCATION( + "location"), START_DATE("startDate"), END_DATE("endDate"), CREATED_DATE("createdDate"), DURATION("duration"), TYPE_ID( + "typeId"), REPEATING("repeating"), RECURRENCE("recurrence"), REMIND_BY_ID("remindById"), FIRST_REMINDER("firstReminder"), SECOND_REMINDER( + "secondReminder"), LOCALE("locale"), DATE_FORMAT("dateFormat"); + + private final String value; + + private CALENDAR_SUPPORTED_PARAMETERS(final String value) { + this.value = value; + } + + private static final Set values = new HashSet(); + static { + for (final CALENDAR_SUPPORTED_PARAMETERS param : CALENDAR_SUPPORTED_PARAMETERS.values()) { + values.add(param.value); + } + } + + public static Set getAllValues() { + return values; + } + + @Override + public String toString() { + return name().toString().replaceAll("_", " "); + } + + public String getValue() { + return this.value; + } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java new file mode 100644 index 000000000..4bcfa3c6d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/api/CalendarsApiResource.java @@ -0,0 +1,172 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.api; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriInfo; + +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.calendar.data.CalendarData; +import org.mifosplatform.portfolio.calendar.domain.Calendar; +import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType; +import org.mifosplatform.portfolio.calendar.service.CalendarDropdownReadPlatformService; +import org.mifosplatform.portfolio.calendar.service.CalendarReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/{entityType}/{entityId}/calendars") +@Component +@Scope("singleton") +public class CalendarsApiResource { + + /** + * The set of parameters that are supported in response for {@link Calendar} + */ + private final Set RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "entityId", "entityType", "title", + "description", "location", "startDate", "endDate", "createdDate", "duration", "type", "repeating", "recurrence", "remindBy", + "firstReminder", "secondReminder")); + private final String resourceNameForPermissions = "CALENDAR"; + + private final PlatformSecurityContext context; + private final CalendarReadPlatformService readPlatformService; + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final ApiRequestParameterHelper apiRequestParameterHelper; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final CalendarDropdownReadPlatformService dropdownReadPlatformService; + + @Autowired + public CalendarsApiResource(final PlatformSecurityContext context, final CalendarReadPlatformService readPlatformService, + final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, + final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService, + final CalendarDropdownReadPlatformService dropdownReadPlatformService) { + this.context = context; + this.readPlatformService = readPlatformService; + this.toApiJsonSerializer = toApiJsonSerializer; + this.apiRequestParameterHelper = apiRequestParameterHelper; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + this.dropdownReadPlatformService = dropdownReadPlatformService; + } + + @GET + @Path("{calendarId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveCalendar(@PathParam("calendarId") final Long calendarId, @PathParam("entityType") final String entityType, @PathParam("entityId") final Long entityId, @Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); + final Integer entityTypeId = CalendarEntityType.valueOf(entityType.toUpperCase()).getValue(); + final CalendarData calendar = this.readPlatformService.retrieveCalendar(calendarId, entityId, entityTypeId); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, calendar, this.RESPONSE_DATA_PARAMETERS); + } + + @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) { + + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); + + final Collection calendars = this.readPlatformService.retrieveCalendarsByEntity(entityId, + CalendarEntityType.valueOf(entityType.toUpperCase()).getValue()); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, calendars, this.RESPONSE_DATA_PARAMETERS); + } + + @GET + @Path("template") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveNewCalendarDetails(@Context final UriInfo uriInfo) { + + this.context.authenticatedUser().validateHasReadPermission(this.resourceNameForPermissions); + + CalendarData calendarData = this.readPlatformService.retrieveNewCalendarDetails(); + calendarData = handleTemplate(calendarData); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.toApiJsonSerializer.serialize(settings, calendarData, this.RESPONSE_DATA_PARAMETERS); + } + + @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) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().createCalendar(entityType, entityId) + .withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + + } + + @PUT + @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) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().updateCalendar(entityType, entityId, calendarId) + .withJson(jsonRequestBody).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + @DELETE + @Path("{calendarId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String deleteGLAccount(@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); + } + + private CalendarData handleTemplate(final CalendarData calendarData) { + final List entityTypeOptions = this.dropdownReadPlatformService.retrieveCalendarEntityTypeOptions(); + final List calendarTypeOptions = this.dropdownReadPlatformService.retrieveCalendarTypeOptions(); + final List remindByOptions = this.dropdownReadPlatformService.retrieveCalendarRemindByOptions(); + return new CalendarData(calendarData, entityTypeOptions, calendarTypeOptions, remindByOptions); + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/command/CalendarCommand.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/command/CalendarCommand.java new file mode 100644 index 000000000..5a9704a02 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/command/CalendarCommand.java @@ -0,0 +1,57 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.command; + +import org.joda.time.LocalDate; + +public class CalendarCommand { + + @SuppressWarnings("unused") + private final String title; + @SuppressWarnings("unused") + private final String description; + @SuppressWarnings("unused") + private final String location; + @SuppressWarnings("unused") + private final LocalDate startDate; + @SuppressWarnings("unused") + private final LocalDate endDate; + @SuppressWarnings("unused") + private final LocalDate createdDate; + @SuppressWarnings("unused") + private final Integer duration; + @SuppressWarnings("unused") + private final Integer typeId; + @SuppressWarnings("unused") + private final boolean repeating; + @SuppressWarnings("unused") + private final String recurrence; + @SuppressWarnings("unused") + private final Integer remindById; + @SuppressWarnings("unused") + private final Integer firstReminder; + @SuppressWarnings("unused") + private final Integer secondReminder; + + public CalendarCommand(final String title, final String description, final String location, final LocalDate startDate, + final LocalDate endDate, final LocalDate createdDate, final Integer duration, final Integer typeId, final boolean repeating, + final String recurrence, final Integer remindById, final Integer firstReminder, final Integer secondReminder) { + this.title = title; + this.description = description; + this.location = location; + this.startDate = startDate; + this.endDate = endDate; + this.createdDate = createdDate; + this.duration = duration; + this.typeId = typeId; + this.repeating = repeating; + this.recurrence = recurrence; + this.remindById = remindById; + this.firstReminder = firstReminder; + this.secondReminder = secondReminder; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/data/CalendarData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/data/CalendarData.java new file mode 100644 index 000000000..61a70bef2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/data/CalendarData.java @@ -0,0 +1,113 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.data; + +import java.util.List; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.calendar.domain.CalendarRemindBy; +import org.mifosplatform.portfolio.calendar.domain.CalendarType; +import org.mifosplatform.portfolio.calendar.service.CalendarEnumerations; + +/** + * Immutable data object representing a Calendar. + */ +public class CalendarData { + + private final Long id; + private final Long entityId; + private final EnumOptionData entityType; + private final String title; + private final String description; + private final String location; + private final LocalDate startDate; + private final LocalDate endDate; + private final LocalDate createdDate; + private final Integer duration; + private final EnumOptionData type; + private final boolean repeating; + private final String recurrence; + private final EnumOptionData remindBy; + private final Integer firstReminder; + private final Integer secondReminder; + + // template related + final List entityTypeOptions; + final List calendarTypeOptions; + final List remindByOptions; + + public CalendarData(final Long id, final Long entityId, final EnumOptionData entityType, final String title, final String description, + final String location, final LocalDate startDate, final LocalDate endDate, final LocalDate createdDate, final Integer duration, + final EnumOptionData type, final boolean repeating, final String recurrence, final EnumOptionData remindBy, + final Integer firstReminder, final Integer secondReminder) { + + this.id = id; + this.entityId = entityId; + this.entityType = entityType; + this.title = title; + this.description = description; + this.location = location; + this.startDate = startDate; + this.endDate = endDate; + this.createdDate = createdDate; + this.duration = duration; + this.type = type; + this.repeating = repeating; + this.recurrence = recurrence; + this.remindBy = remindBy; + this.firstReminder = firstReminder; + this.secondReminder = secondReminder; + this.entityTypeOptions = null; + this.calendarTypeOptions = null; + this.remindByOptions = null; + } + + public CalendarData(final CalendarData calendarData, final List entityTypeOptions, + final List calendarTypeOptions, final List remindByOptions) { + this.id = calendarData.id; + this.entityId = calendarData.entityId; + this.entityType = calendarData.entityType; + this.title = calendarData.title; + this.description = calendarData.description; + this.location = calendarData.location; + this.startDate = calendarData.startDate; + this.endDate = calendarData.endDate; + this.createdDate = calendarData.createdDate; + this.duration = calendarData.duration; + this.type = calendarData.type; + this.repeating = calendarData.repeating; + this.recurrence = calendarData.recurrence; + this.remindBy = calendarData.remindBy; + this.firstReminder = calendarData.firstReminder; + this.secondReminder = calendarData.secondReminder; + this.entityTypeOptions = entityTypeOptions; + this.calendarTypeOptions = calendarTypeOptions; + this.remindByOptions = remindByOptions; + } + + public static CalendarData sensibleDefaultsForNewCalendarCreation() { + final Long id = null; + final Long entityId = null; + final EnumOptionData entityType = null; + final String title = null; + final String description = null; + final String location = null; + final LocalDate startDate = null; + final LocalDate endDate = null; + final LocalDate createdDate = null; + final Integer duration = new Integer(0); + final EnumOptionData type = CalendarEnumerations.calendarType(CalendarType.COLLECTION); + final boolean repeating = false; + final String recurrence = null; + final EnumOptionData remindBy = CalendarEnumerations.calendarRemindBy(CalendarRemindBy.EMAIL); + final Integer firstReminder = new Integer(0); + final Integer secondReminder = new Integer(0); + + return new CalendarData(id, entityId, entityType, title, description, location, startDate, endDate, createdDate, duration, type, + repeating, recurrence, remindBy, firstReminder, secondReminder); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/Calendar.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/Calendar.java new file mode 100644 index 000000000..607392a5f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/Calendar.java @@ -0,0 +1,316 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package org.mifosplatform.portfolio.calendar.domain; + +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.portfolio.calendar.CalendarConstants.CALENDAR_SUPPORTED_PARAMETERS; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_calendar") +public class Calendar extends AbstractPersistable { + + @Column(name = "entity_id", nullable = false) + private Long entityId; + + @Column(name = "entity_type_enum", nullable = false) + private Integer entityTypeId; + + @Column(name = "title", length = 50, nullable = false) + private String title; + + @Column(name = "description", length = 100, nullable = true) + private String description; + + @Column(name = "location", length = 100, nullable = true) + private String location; + + @Column(name = "start_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date startDate; + + @Column(name = "end_date", nullable = true) + @Temporal(TemporalType.DATE) + private Date endDate; + + @Column(name = "created_date", nullable = false) + @Temporal(TemporalType.TIMESTAMP) + private Date createdDate; + + @Column(name = "duration", nullable = true) + private Integer duration; + + @Column(name = "calendar_type_enum", nullable = false) + private Integer typeId; + + @Column(name = "repeating", nullable = false) + private boolean repeating = false; + + @Column(name = "recurrence", length = 100, nullable = true) + private String recurrence; + + @Column(name = "remind_by_enum", nullable = true) + private Integer remindById; + + @Column(name = "first_reminder", nullable = true) + private Integer firstReminder; + + @Column(name = "second_reminder", nullable = true) + private Integer secondReminder; + + protected Calendar() { + + } + + public Calendar(final Long entityId, final Integer entityTypeId, final String title, final String description, final String location, + final LocalDate startDate, final LocalDate endDate, final LocalDate createdDate, final Integer duration, final Integer typeId, + final boolean repeating, final String recurrence, final Integer remindById, final Integer firstReminder, + final Integer secondReminder) { + this.entityId = entityId; + this.entityTypeId = entityTypeId; + this.title = StringUtils.defaultIfEmpty(title, null); + this.description = StringUtils.defaultIfEmpty(description, null); + this.location = StringUtils.defaultIfEmpty(location, null); + + if (null != startDate) { + this.startDate = startDate.toDateMidnight().toDate(); + } else { + this.startDate = null; + } + + if (null != endDate) { + this.endDate = endDate.toDateMidnight().toDate(); + } else { + this.endDate = null; + } + + if (null != createdDate) { + this.createdDate = createdDate.toDateMidnight().toDate(); + } else { + this.createdDate = null; + } + + this.duration = duration; + this.typeId = typeId; + this.repeating = repeating; + this.recurrence = StringUtils.defaultIfEmpty(recurrence, null); + this.remindById = remindById; + this.firstReminder = firstReminder; + this.secondReminder = secondReminder; + } + + public static Calendar fromJson(final JsonCommand command) { + + final Long entityId = command.getSupportedEntityId(); + final Integer entityTypeId = CalendarEntityType.valueOf(command.getSupportedEntityType().toUpperCase()).getValue(); + final String title = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue()); + final String description = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue()); + final String location = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue()); + final LocalDate startDate = command.localDateValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue()); + final LocalDate endDate = command.localDateValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue()); + final LocalDate createdDate = command.localDateValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.CREATED_DATE.getValue()); + final Integer duration = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue()); + final Integer typeId = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue()); + final boolean repeating = command.booleanPrimitiveValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue()); + final String recurrence = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue()); + final Integer remindById = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue()); + final Integer firstReminder = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER + .getValue()); + final Integer secondReminder = command.integerValueSansLocaleOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER + .getValue()); + + return new Calendar(entityId, entityTypeId, title, description, location, startDate, endDate, createdDate, duration, typeId, + repeating, recurrence, remindById, firstReminder, secondReminder); + } + + public Map update(final JsonCommand command) { + + final Map actualChanges = new LinkedHashMap(9); + + if (command.isChangeInStringParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), this.title)) { + final String newValue = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue()); + actualChanges.put(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), newValue); + this.title = StringUtils.defaultIfEmpty(newValue, null); + } + + if (command.isChangeInStringParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), this.description)) { + final String newValue = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue()); + actualChanges.put(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), newValue); + this.description = StringUtils.defaultIfEmpty(newValue, null); + } + + if (command.isChangeInStringParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), this.location)) { + final String newValue = command.stringValueOfParameterNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue()); + actualChanges.put(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), newValue); + this.location = StringUtils.defaultIfEmpty(newValue, null); + } + + final String dateFormatAsInput = command.dateFormat(); + final String localeAsInput = command.locale(); + final String startDateParamName = CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(); + if (command.isChangeInLocalDateParameterNamed(startDateParamName, getStartDateLocalDate())) { + final String valueAsInput = command.stringValueOfParameterNamed(startDateParamName); + actualChanges.put(startDateParamName, valueAsInput); + actualChanges.put("dateFormat", dateFormatAsInput); + actualChanges.put("locale", localeAsInput); + + final LocalDate newValue = command.localDateValueOfParameterNamed(startDateParamName); + this.startDate = newValue.toDate(); + } + + final String endDateParamName = CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(); + if (command.isChangeInLocalDateParameterNamed(endDateParamName, getEndDateLocalDate())) { + final String valueAsInput = command.stringValueOfParameterNamed(endDateParamName); + actualChanges.put(endDateParamName, valueAsInput); + actualChanges.put("dateFormat", dateFormatAsInput); + actualChanges.put("locale", localeAsInput); + + final LocalDate newValue = command.localDateValueOfParameterNamed(endDateParamName); + this.endDate = newValue.toDate(); + } + + final String durationParamName = CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(); + if (command.isChangeInIntegerSansLocaleParameterNamed(durationParamName, this.duration)) { + final Integer newValue = command.integerValueSansLocaleOfParameterNamed(durationParamName); + actualChanges.put(durationParamName, newValue); + this.duration = newValue; + } + + final String typeParamName = CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue(); + if (command.isChangeInIntegerSansLocaleParameterNamed(typeParamName, this.typeId)) { + final Integer newValue = command.integerValueSansLocaleOfParameterNamed(typeParamName); + actualChanges.put(typeParamName, newValue); + this.typeId = newValue; + } + + final String repeatingParamName = CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(); + if (command.isChangeInBooleanParameterNamed(repeatingParamName, this.repeating)) { + final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(repeatingParamName); + actualChanges.put(repeatingParamName, newValue); + this.repeating = newValue; + } + + final String recurrenceParamName = CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue(); + if (command.isChangeInStringParameterNamed(recurrenceParamName, this.recurrence)) { + final String newValue = command.stringValueOfParameterNamed(recurrenceParamName); + actualChanges.put(recurrenceParamName, newValue); + this.recurrence = StringUtils.defaultIfEmpty(newValue, null); + } + + final String remindByParamName = CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(); + if (command.isChangeInIntegerSansLocaleParameterNamed(remindByParamName, this.remindById)) { + final Integer newValue = command.integerValueSansLocaleOfParameterNamed(remindByParamName); + actualChanges.put(remindByParamName, newValue); + this.remindById = newValue; + } + + final String firstRemindarParamName = CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(); + if (command.isChangeInIntegerSansLocaleParameterNamed(firstRemindarParamName, this.firstReminder)) { + final Integer newValue = command.integerValueSansLocaleOfParameterNamed(firstRemindarParamName); + actualChanges.put(firstRemindarParamName, newValue); + this.firstReminder = newValue; + } + + final String secondRemindarParamName = CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(); + if (command.isChangeInIntegerSansLocaleParameterNamed(secondRemindarParamName, this.secondReminder)) { + final Integer newValue = command.integerValueSansLocaleOfParameterNamed(secondRemindarParamName); + actualChanges.put(secondRemindarParamName, newValue); + this.secondReminder = newValue; + } + + return actualChanges; + } + + public Long getEntityId() { + return this.entityId; + } + + public Integer getEntityTypeId() { + return this.entityTypeId; + } + + public String getTitle() { + return this.title; + } + + public String getDescription() { + return this.description; + } + + public String getLocation() { + return this.location; + } + + public Date getStartDate() { + return this.startDate; + } + + public Date getEndDate() { + return this.endDate; + } + + public Date getCreatedDate() { + return this.createdDate; + } + + public Integer getDuration() { + return this.duration; + } + + public Integer getTypeId() { + return this.typeId; + } + + public boolean isRepeating() { + return this.repeating; + } + + public String getRecurrence() { + return this.recurrence; + } + + public Integer getRemindById() { + return this.remindById; + } + + public Integer getFirstReminder() { + return this.firstReminder; + } + + public Integer getSecondReminder() { + return this.secondReminder; + } + + private LocalDate getStartDateLocalDate() { + LocalDate startDateLocalDate = null; + if (this.startDate != null) { + startDateLocalDate = LocalDate.fromDateFields(this.startDate); + } + return startDateLocalDate; + } + + private LocalDate getEndDateLocalDate() { + LocalDate endDateLocalDate = null; + if (this.endDate != null) { + endDateLocalDate = LocalDate.fromDateFields(this.endDate); + } + return endDateLocalDate; + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarEntityType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarEntityType.java new file mode 100644 index 000000000..1ec184055 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarEntityType.java @@ -0,0 +1,64 @@ +package org.mifosplatform.portfolio.calendar.domain; + +import java.util.HashMap; +import java.util.Map; + +public enum CalendarEntityType { + + CLIENTS(1, "calendarEntityType.clients"), GROUPS(2, "calendarEntityType.groups"), LOANS(3, "calendarEntityType.loans"), CENTERS(4, + "calendarEntityType.centers"); + + private final Integer value; + private final String code; + + private CalendarEntityType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + private static final Map intToEnumMap = new HashMap(); + private static int minValue; + private static int maxValue; + static { + int i = 0; + for (final CalendarEntityType entityType : CalendarEntityType.values()) { + if (i == 0) { + minValue = entityType.value; + } + intToEnumMap.put(entityType.value, entityType); + if (minValue >= entityType.value) { + minValue = entityType.value; + } + if (maxValue < entityType.value) { + maxValue = entityType.value; + } + i = i + 1; + } + } + + 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; + } + + @Override + public String toString() { + return name().toString(); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRemindBy.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRemindBy.java new file mode 100644 index 000000000..6a1b5c8e2 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRemindBy.java @@ -0,0 +1,63 @@ +package org.mifosplatform.portfolio.calendar.domain; + +import java.util.HashMap; +import java.util.Map; + +public enum CalendarRemindBy { + + SMS(1, "calendarRemindBy.sms"), EMAIL(2, "calendarRemindBy.email"), SYSTEMALERT(3, "calendarRemindBy.systemalert"); + + private final Integer value; + private final String code; + + private CalendarRemindBy(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + private static final Map intToEnumMap = new HashMap(); + private static int minValue; + private static int maxValue; + static { + int i = 0; + for (final CalendarRemindBy remindBy : CalendarRemindBy.values()) { + if (i == 0) { + minValue = remindBy.value; + } + intToEnumMap.put(remindBy.value, remindBy); + if (minValue >= remindBy.value) { + minValue = remindBy.value; + } + if (maxValue < remindBy.value) { + maxValue = remindBy.value; + } + i = i + 1; + } + } + + public static CalendarRemindBy fromInt(final int i) { + final CalendarRemindBy remindBy = intToEnumMap.get(Integer.valueOf(i)); + return remindBy; + } + + public static int getMinValue() { + return minValue; + } + + public static int getMaxValue() { + return maxValue; + } + + @Override + public String toString() { + return name().toString(); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRepository.java new file mode 100644 index 000000000..7755d0f11 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarRepository.java @@ -0,0 +1,8 @@ +package org.mifosplatform.portfolio.calendar.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface CalendarRepository extends JpaRepository, JpaSpecificationExecutor { + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarType.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarType.java new file mode 100644 index 000000000..2937724c6 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/domain/CalendarType.java @@ -0,0 +1,64 @@ +package org.mifosplatform.portfolio.calendar.domain; + +import java.util.HashMap; +import java.util.Map; + +public enum CalendarType { + + COLLECTION(1, "calendarType.collection"), TRAINING(2, "calendarType.training"), AUDIT(3, "calendarType.audit"), GENERAL(4, + "calendarType.general"); + + private final Integer value; + private final String code; + + private CalendarType(final Integer value, final String code) { + this.value = value; + this.code = code; + } + + public Integer getValue() { + return this.value; + } + + public String getCode() { + return this.code; + } + + private static final Map intToEnumMap = new HashMap(); + private static int minValue; + private static int maxValue; + static { + int i = 0; + for (final CalendarType type : CalendarType.values()) { + if (i == 0) { + minValue = type.value; + } + intToEnumMap.put(type.value, type); + if (minValue >= type.value) { + minValue = type.value; + } + if (maxValue < type.value) { + maxValue = type.value; + } + i = i + 1; + } + } + + public static CalendarType fromInt(final int i) { + final CalendarType type = intToEnumMap.get(Integer.valueOf(i)); + return type; + } + + public static int getMinValue() { + return minValue; + } + + public static int getMaxValue() { + return maxValue; + } + + @Override + public String toString() { + return name().toString(); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/exception/CalendarNotFoundException.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/exception/CalendarNotFoundException.java new file mode 100644 index 000000000..93c9a6b20 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/exception/CalendarNotFoundException.java @@ -0,0 +1,18 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceNotFoundException; + +/** + * A {@link RuntimeException} thrown when Calendar resources are not found. + */ +public class CalendarNotFoundException extends AbstractPlatformResourceNotFoundException { + + public CalendarNotFoundException(final Long id) { + super("error.msg.calendar.id.invalid", "Calendar with identifier " + id + " does not exist", id); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/CreateCalendarCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/CreateCalendarCommandHandler.java new file mode 100644 index 000000000..c7b82f32e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/CreateCalendarCommandHandler.java @@ -0,0 +1,32 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.calendar.service.CalendarWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CreateCalendarCommandHandler implements NewCommandSourceHandler { + + private final CalendarWritePlatformService writePlatformService; + + @Autowired + public CreateCalendarCommandHandler(final CalendarWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + return this.writePlatformService.createCalendar(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/DeleteCalendarCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/DeleteCalendarCommandHandler.java new file mode 100644 index 000000000..657d81453 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/DeleteCalendarCommandHandler.java @@ -0,0 +1,31 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.calendar.service.CalendarWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class DeleteCalendarCommandHandler implements NewCommandSourceHandler { + + private final CalendarWritePlatformService writePlatformService; + + @Autowired + public DeleteCalendarCommandHandler(final CalendarWritePlatformService writePlatformService) { + this.writePlatformService = writePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + return this.writePlatformService.deleteCalendar(command.entityId()); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/UpdateCalendarCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/UpdateCalendarCommandHandler.java new file mode 100644 index 000000000..f3f53fe7e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/handler/UpdateCalendarCommandHandler.java @@ -0,0 +1,28 @@ +package org.mifosplatform.portfolio.calendar.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.calendar.service.CalendarWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UpdateCalendarCommandHandler implements NewCommandSourceHandler { + + private final CalendarWritePlatformService calendarWritePlatformService; + + @Autowired + public UpdateCalendarCommandHandler(final CalendarWritePlatformService calendarWritePlatformService) { + this.calendarWritePlatformService = calendarWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.calendarWritePlatformService.updateCalendar(command); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java new file mode 100644 index 000000000..34ee77990 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/serialization/CalendarCommandFromApiJsonDeserializer.java @@ -0,0 +1,262 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.serialization; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; +import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.portfolio.calendar.CalendarConstants.CALENDAR_SUPPORTED_PARAMETERS; +import org.mifosplatform.portfolio.calendar.command.CalendarCommand; +import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType; +import org.mifosplatform.portfolio.calendar.domain.CalendarRemindBy; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; + +@Component +public class CalendarCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer { + + /** + * The parameters supported for this command. + */ + private final Set supportedParameters = CALENDAR_SUPPORTED_PARAMETERS.getAllValues(); + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public CalendarCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + @Override + public CalendarCommand commandFromApiJson(final String json) { + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + + final JsonElement element = this.fromApiJsonHelper.parse(json); + final String title = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), element); + final String description = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), element); + final String location = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), element); + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), + element); + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), element); + final LocalDate createdDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.CREATED_DATE.getValue(), + element); + final Integer duration = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(), + element); + final Integer typeId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue(), + element); + final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(), element); + final String recurrence = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue(), element); + final Integer remindById = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(), element); + final Integer firstReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(), element); + final Integer secondReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(), element); + + return new CalendarCommand(title, description, location, startDate, endDate, createdDate, duration, typeId, repeating, recurrence, + remindById, firstReminder, secondReminder); + } + + public void validateForCreate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("calendar"); + + final String title = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue()).value(title).notBlank() + .notExceedingLengthOf(50); + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), element)) { + final String description = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue()).value(description).notNull() + .notExceedingLengthOf(100); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), element)) { + final String location = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue()).value(location).notNull() + .notExceedingLengthOf(50); + } + + final String startDateStr = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue()).value(startDateStr).notBlank(); + + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue()).value(startDate).notNull(); + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), element)) { + final String endDateStr = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue()).value(endDateStr).notBlank(); + + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue()).value(endDate).notNull(); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(), element)) { + final Integer duration = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue()).value(duration).ignoreIfNull(); + } + + final Integer typeId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue()).value(typeId).notNull() + .inMinMaxRange(CalendarEntityType.getMinValue(), CalendarEntityType.getMaxValue()); + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(), element)) { + // FIXME - Throws NullPointerException when boolean value is null + final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue()).value(repeating).notNull(); + } + + final String recurrence = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue()).value(recurrence).notNull() + .notExceedingLengthOf(100); + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(), element)) { + final Integer remindById = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue()).value(remindById).notNull() + .inMinMaxRange(CalendarRemindBy.getMinValue(), CalendarRemindBy.getMaxValue()); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(), element)) { + final Integer firstReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue()).value(firstReminder).notNull(); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(), element)) { + final Integer secondReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder).notNull(); + } + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + + public void validateForUpdate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters); + final JsonElement element = this.fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("calendar"); + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), element)) { + final String title = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.TITLE.getValue()).value(title).notBlank() + .notExceedingLengthOf(50); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), element)) { + final String description = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.DESCRIPTION.getValue()).value(description).notNull() + .notExceedingLengthOf(100); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), element)) { + final String location = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.LOCATION.getValue()).value(location).notNull() + .notExceedingLengthOf(50); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), element)) { + final String startDateStr = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue()).value(startDateStr).notNull(); + + final LocalDate startDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.START_DATE.getValue()).value(startDate).notNull(); + } + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), element)) { + final LocalDate endDate = this.fromApiJsonHelper.extractLocalDateNamed(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.END_DATE.getValue()).value(endDate).notNull(); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(), element)) { + final Integer duration = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.DURATION.getValue()).value(duration).ignoreIfNull(); + } + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue(), element)) { + final Integer typeId = this.fromApiJsonHelper.extractIntegerSansLocaleNamed(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.TYPE_ID.getValue()).value(typeId).notNull() + .inMinMaxRange(CalendarEntityType.getMinValue(), CalendarEntityType.getMaxValue()); + } + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(), element)) { + // FIXME - Throws NullPointerException when boolean value is null + final boolean repeating = this.fromApiJsonHelper.extractBooleanNamed(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REPEATING.getValue()).value(repeating).notNull(); + } + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue(), element)) { + final String recurrence = this.fromApiJsonHelper.extractStringNamed(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue(), + element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.RECURRENCE.getValue()).value(recurrence).notNull() + .notExceedingLengthOf(100); + } + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(), element)) { + final Integer remindById = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.REMIND_BY_ID.getValue()).value(remindById).notNull() + .inMinMaxRange(CalendarRemindBy.getMinValue(), CalendarRemindBy.getMaxValue()); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(), element)) { + final Integer firstReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.FIRST_REMINDER.getValue()).value(firstReminder).notNull(); + } + + if (this.fromApiJsonHelper.parameterExists(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(), element)) { + final Integer secondReminder = this.fromApiJsonHelper.extractIntegerSansLocaleNamed( + CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue(), element); + baseDataValidator.reset().parameter(CALENDAR_SUPPORTED_PARAMETERS.SECOND_REMINDER.getValue()).value(secondReminder).notNull(); + } + + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", + "Validation errors exist.", dataValidationErrors); } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformService.java new file mode 100644 index 000000000..cdcf7c40e --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformService.java @@ -0,0 +1,20 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.service; + +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; + +public interface CalendarDropdownReadPlatformService { + + List retrieveCalendarEntityTypeOptions(); + + List retrieveCalendarTypeOptions(); + + List retrieveCalendarRemindByOptions(); + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java new file mode 100644 index 000000000..9a83bfbe4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarDropdownReadPlatformServiceImpl.java @@ -0,0 +1,29 @@ +package org.mifosplatform.portfolio.calendar.service; + +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType; +import org.mifosplatform.portfolio.calendar.domain.CalendarRemindBy; +import org.mifosplatform.portfolio.calendar.domain.CalendarType; +import org.springframework.stereotype.Service; + +@Service +public class CalendarDropdownReadPlatformServiceImpl implements CalendarDropdownReadPlatformService { + + @Override + public List retrieveCalendarEntityTypeOptions() { + return CalendarEnumerations.calendarEntityType(CalendarEntityType.values()); + } + + @Override + public List retrieveCalendarTypeOptions() { + return CalendarEnumerations.calendarType(CalendarType.values()); + } + + @Override + public List retrieveCalendarRemindByOptions() { + return CalendarEnumerations.calendarRemindBy(CalendarRemindBy.values()); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarEnumerations.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarEnumerations.java new file mode 100644 index 000000000..f42039a1b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarEnumerations.java @@ -0,0 +1,63 @@ +package org.mifosplatform.portfolio.calendar.service; + +import java.util.ArrayList; +import java.util.List; + +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType; +import org.mifosplatform.portfolio.calendar.domain.CalendarRemindBy; +import org.mifosplatform.portfolio.calendar.domain.CalendarType; + +public class CalendarEnumerations { + + public static EnumOptionData calendarEntityType(final int id) { + return calendarEntityType(CalendarEntityType.fromInt(id)); + } + + public static EnumOptionData calendarEntityType(final CalendarEntityType entityType) { + final EnumOptionData optionData = new EnumOptionData(entityType.getValue().longValue(), entityType.getCode(), entityType.toString()); + return optionData; + } + + public static List calendarEntityType(final CalendarEntityType[] entityTypes) { + final List optionDatas = new ArrayList(); + for (final CalendarEntityType entityType : entityTypes) { + optionDatas.add(calendarEntityType(entityType)); + } + return optionDatas; + } + + public static EnumOptionData calendarType(final int id) { + return calendarType(CalendarType.fromInt(id)); + } + + public static EnumOptionData calendarType(final CalendarType type) { + final EnumOptionData optionData = new EnumOptionData(type.getValue().longValue(), type.getCode(), type.toString()); + return optionData; + } + + public static List calendarType(final CalendarType[] types) { + final List optionDatas = new ArrayList(); + for (final CalendarType type : types) { + optionDatas.add(calendarType(type)); + } + return optionDatas; + } + + public static EnumOptionData calendarRemindBy(final int id) { + return calendarRemindBy(CalendarRemindBy.fromInt(id)); + } + + public static EnumOptionData calendarRemindBy(final CalendarRemindBy remindBy) { + final EnumOptionData optionData = new EnumOptionData(remindBy.getValue().longValue(), remindBy.getCode(), remindBy.toString()); + return optionData; + } + + public static List calendarRemindBy(final CalendarRemindBy[] remindBys) { + final List optionDatas = new ArrayList(); + for (final CalendarRemindBy remindBy : remindBys) { + optionDatas.add(calendarRemindBy(remindBy)); + } + return optionDatas; + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java new file mode 100644 index 000000000..a9d464b4d --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformService.java @@ -0,0 +1,21 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.calendar.data.CalendarData; + +public interface CalendarReadPlatformService { + + CalendarData retrieveCalendar(final Long calendarId, Long entityId, Integer entityTypeId); + + Collection retrieveCalendarsByEntity(final Long entityId, final Integer entityTypeId); + + Collection retrieveAllCalendars(); + + CalendarData retrieveNewCalendarDetails(); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java new file mode 100644 index 000000000..b0e53f276 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarReadPlatformServiceImpl.java @@ -0,0 +1,110 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; +import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; +import org.mifosplatform.portfolio.calendar.data.CalendarData; +import org.mifosplatform.portfolio.calendar.exception.CalendarNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class CalendarReadPlatformServiceImpl implements CalendarReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + + @Autowired + public CalendarReadPlatformServiceImpl(final TenantAwareRoutingDataSource dataSource) { + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private static final class CalendarDataMapper implements RowMapper { + + public String schema() { + return " select c.id as id, c.entity_id as entityId, c.entity_type_enum as entityTypeId, c.title as title, " + + " c.description as description, c.location as location, c.start_date as startDate, c.end_date as endDate, " + + " c.created_date as createdDate, c.duration as duration, c.calendar_type_enum as typeId, c.repeating as repeating, " + + " c.recurrence as recurrence, c.remind_by_enum as remindById, c.first_reminder as firstReminder, c.second_reminder as secondReminder " + + " from m_calendar c "; + } + + @Override + public CalendarData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final Long entityId = rs.getLong("entityId"); + final Integer entityTypeId = rs.getInt("entityTypeId"); + final EnumOptionData entityType = CalendarEnumerations.calendarEntityType(entityTypeId); + final String title = rs.getString("title"); + final String description = rs.getString("description"); + final String location = rs.getString("location"); + final LocalDate startDate = JdbcSupport.getLocalDate(rs, "startDate"); + final LocalDate endDate = JdbcSupport.getLocalDate(rs, "endDate"); + final LocalDate createdDate = JdbcSupport.getLocalDate(rs, "createdDate"); + final Integer duration = rs.getInt("duration"); + final Integer typeId = rs.getInt("typeId"); + final EnumOptionData type = CalendarEnumerations.calendarType(typeId); + final boolean repeating = rs.getBoolean("repeating"); + final String recurrence = rs.getString("recurrence"); + final Integer remindById = rs.getInt("remindById"); + final EnumOptionData remindBy = CalendarEnumerations.calendarRemindBy(remindById); + final Integer firstReminder = rs.getInt("firstReminder"); + final Integer secondReminder = rs.getInt("secondReminder"); + + return new CalendarData(id, entityId, entityType, title, description, location, startDate, endDate, createdDate, duration, + type, repeating, recurrence, remindBy, firstReminder, secondReminder); + } + } + + @Override + public CalendarData retrieveCalendar(final Long calendarId, Long entityId, Integer entityTypeId) { + + try { + final CalendarDataMapper rm = new CalendarDataMapper(); + + final String sql = rm.schema() + "where c.id = ? and c.entity_id = ? and c.entity_type_enum = ?"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { calendarId, entityId, entityTypeId }); + } catch (final EmptyResultDataAccessException e) { + throw new CalendarNotFoundException(calendarId); + } + } + + @Override + public Collection retrieveCalendarsByEntity(final Long entityId, final Integer entityTypeId) { + final CalendarDataMapper rm = new CalendarDataMapper(); + + final String sql = rm.schema() + "where c.entity_id = ? and c.entity_type_enum = ?"; + + return this.jdbcTemplate.query(sql, rm, new Object[] { entityId, entityTypeId }); + } + + @Override + public Collection retrieveAllCalendars() { + + final CalendarDataMapper rm = new CalendarDataMapper(); + + final String sql = rm.schema(); + + return this.jdbcTemplate.query(sql, rm); + } + + @Override + public CalendarData retrieveNewCalendarDetails() { + return CalendarData.sensibleDefaultsForNewCalendarCreation(); + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformService.java new file mode 100644 index 000000000..d35aa5419 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformService.java @@ -0,0 +1,13 @@ +package org.mifosplatform.portfolio.calendar.service; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; + +public interface CalendarWritePlatformService { + + CommandProcessingResult createCalendar(JsonCommand command); + + CommandProcessingResult updateCalendar(JsonCommand command); + + CommandProcessingResult deleteCalendar(Long calendarId); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..09c4c5bb0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/calendar/service/CalendarWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,81 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package org.mifosplatform.portfolio.calendar.service; + +import java.util.Map; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.portfolio.calendar.domain.Calendar; +import org.mifosplatform.portfolio.calendar.domain.CalendarRepository; +import org.mifosplatform.portfolio.calendar.exception.CalendarNotFoundException; +import org.mifosplatform.portfolio.calendar.serialization.CalendarCommandFromApiJsonDeserializer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class CalendarWritePlatformServiceJpaRepositoryImpl implements CalendarWritePlatformService { + + private final CalendarRepository calendarRepository; + private final CalendarCommandFromApiJsonDeserializer fromApiJsonDeserializer; + + @Autowired + public CalendarWritePlatformServiceJpaRepositoryImpl(final CalendarRepository calendarRepository, + final CalendarCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + this.calendarRepository = calendarRepository; + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + } + + @Override + public CommandProcessingResult createCalendar(final JsonCommand command) { + + this.fromApiJsonDeserializer.validateForCreate(command.json()); + + final Calendar newCalendar = Calendar.fromJson(command); + this.calendarRepository.save(newCalendar); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(newCalendar.getId()) // + .build(); + + } + + @Override + public CommandProcessingResult updateCalendar(final JsonCommand command) { + + this.fromApiJsonDeserializer.validateForUpdate(command.json()); + + final Long calendarId = command.entityId(); + final Calendar calendarForUpdate = this.calendarRepository.findOne(calendarId); + if (calendarForUpdate == null) { throw new CalendarNotFoundException(calendarId); } + + final Map changes = calendarForUpdate.update(command); + + if (!changes.isEmpty()) { + this.calendarRepository.saveAndFlush(calendarForUpdate); + } + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withEntityId(calendarForUpdate.getId()) // + .with(changes) // + .build(); + } + + @Override + public CommandProcessingResult deleteCalendar(final Long calendarId) { + final Calendar calendarForDelete = this.calendarRepository.findOne(calendarId); + if (calendarForDelete == null) { throw new CalendarNotFoundException(calendarId); } + + this.calendarRepository.delete(calendarForDelete); + return new CommandProcessingResultBuilder() // + .withCommandId(null) // + .withEntityId(calendarId) // + .build(); + } + +}