From 59f1c0ce8ab2a5c1d6a77dc64b113090e096d94b Mon Sep 17 00:00:00 2001 From: goutham-M Date: Wed, 12 Jun 2013 16:31:22 +0530 Subject: [PATCH] holiday functionality to apply holidays for offices --- .../core_db/v58__create-holiday-tables.sql | 22 ++++ .../commands/domain/CommandWrapper.java | 4 + .../service/CommandWrapperBuilder.java | 8 ++ .../SynchronousCommandProcessingService.java | 7 +- .../core/data/CommandProcessingResult.java | 10 +- .../data/CommandProcessingResultBuilder.java | 8 +- .../holiday/api/HolidayApiConstants.java | 24 ++++ .../holiday/api/HolidaysApiResource.java | 45 +++++++ .../holiday/data/HolidayDataValidator.java | 85 +++++++++++++ .../organisation/holiday/domain/Holiday.java | 88 +++++++++++++ .../holiday/domain/HolidayRepository.java | 15 +++ .../handler/CreateHolidayCommandHandler.java | 27 ++++ .../HolidayReadPlatformServiceImpl.java | 5 + .../service/HolidayWritePlatformService.java | 9 ++ ...WritePlatformServiceJpaRepositoryImpl.java | 120 ++++++++++++++++++ .../office/api/OfficesApiResource.java | 2 +- 16 files changed, 473 insertions(+), 6 deletions(-) create mode 100644 mifosng-db/migrations/core_db/v58__create-holiday-tables.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidayApiConstants.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidaysApiResource.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/data/HolidayDataValidator.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/Holiday.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/handler/CreateHolidayCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayReadPlatformServiceImpl.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformService.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java diff --git a/mifosng-db/migrations/core_db/v58__create-holiday-tables.sql b/mifosng-db/migrations/core_db/v58__create-holiday-tables.sql new file mode 100644 index 000000000..35d832626 --- /dev/null +++ b/mifosng-db/migrations/core_db/v58__create-holiday-tables.sql @@ -0,0 +1,22 @@ + +create table `m_holiday`( +`id` BIGINT(20) NOT NULL AUTO_INCREMENT, +`name` varchar(100) NOT NULL, +`from_date` DATETIME NOT NULL, +`to_date` DATETIME NOT NULL, +`description` varchar(100) NULL DEFAULT NULL, +PRIMARY KEY (`id`), +UNIQUE INDEX `holiday_name` (`name`) +); + +CREATE TABLE `m_holiday_office` ( + `holiday_id` BIGINT(20) NOT NULL, + `office_id` BIGINT(20) NOT NULL, + PRIMARY KEY (`holiday_id`, `office_id`), + INDEX `m_holiday_id_ibfk_1` (`holiday_id`), + INDEX `m_office_id_ibfk_2` (`office_id`), + CONSTRAINT `m_holiday_id_ibfk_1` FOREIGN KEY (`holiday_id`) REFERENCES `m_holiday` (`id`), + CONSTRAINT `m_office_id_ibfk_2` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`) +); + +INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('organisation', 'CREATE_HOLIDAY', 'HOLIDAY', 'CREATE', 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 613188160..dc7b6a09c 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 @@ -531,4 +531,8 @@ public class CommandWrapper { public boolean isAccountingRuleResource() { return this.entityName.equalsIgnoreCase("ACCOUNTINGRULE"); } + + public boolean isHolidayResource() { + return this.entityName.equalsIgnoreCase("HOLIDAY"); + } } \ 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 e275acbe6..132a79d8e 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 @@ -1018,4 +1018,12 @@ public class CommandWrapperBuilder { this.href = "/accountingrules/" + accountingRuleId; return this; } + + public CommandWrapperBuilder createHoliday() { + this.actionName = "CREATE"; + this.entityName = "HOLIDAY"; + this.entityId = null; + this.href = "/holidays/template"; + return this; + } } \ No newline at end of file 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 6fd1d3d66..692c12bcf 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 @@ -461,7 +461,12 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer throw new UnsupportedCommandException(wrapper.commandName()); } - }else { + } else if(wrapper.isHolidayResource()) { + + if (wrapper.isCreate()) { + handler = applicationContext.getBean("createHolidayCommandHandler", NewCommandSourceHandler.class); + } + } else { throw new UnsupportedCommandException(wrapper.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java index c0a1bcc60..d1c23560f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResult.java @@ -22,15 +22,16 @@ public class CommandProcessingResult { private final Long savingsId; private final Long resourceId; private final String transactionId; + private final Long holidayId; private final Map changes; @SuppressWarnings("unused") private final String resourceIdentifier; public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final String transactionId, - final Map changes) { + final Long holidayId, final Map changes) { return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId, - transactionId, changes); + transactionId, holidayId, changes); } public static CommandProcessingResult commandOnlyResult(final Long commandId) { @@ -78,11 +79,12 @@ public class CommandProcessingResult { this.loanId = null; this.savingsId = null; this.transactionId = null; + this.holidayId = null; this.changes = new HashMap(); } private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId, - final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId, + final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId, final Long holidayId, final Map changesOnly) { this.commandId = commandId; this.officeId = officeId; @@ -94,6 +96,7 @@ public class CommandProcessingResult { this.resourceId = resourceId; this.changes = changesOnly; this.transactionId = transactionId; + this.holidayId = holidayId; } private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map changesOnly) { @@ -109,6 +112,7 @@ public class CommandProcessingResult { this.loanId = null; this.savingsId = null; this.transactionId = null; + this.holidayId = null; this.commandId = commandId; this.changes = changesOnly; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java index f55f44325..20d977079 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/core/data/CommandProcessingResultBuilder.java @@ -22,11 +22,12 @@ public class CommandProcessingResultBuilder { private String resourceIdentifier; private Long entityId; private String transactionId; + private Long holidayId; private Map changes; public CommandProcessingResult build() { return CommandProcessingResult.fromDetails(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId, - transactionId, changes); + transactionId, holidayId, changes); } public CommandProcessingResultBuilder withCommandId(final Long withCommandId) { @@ -78,4 +79,9 @@ public class CommandProcessingResultBuilder { this.transactionId = withTransactionId; return this; } + + public CommandProcessingResultBuilder withHolidayId(final Long withHolidayId) { + this.holidayId = withHolidayId; + return this; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidayApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidayApiConstants.java new file mode 100644 index 000000000..463e0d367 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidayApiConstants.java @@ -0,0 +1,24 @@ +package org.mifosplatform.organisation.holiday.api; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class HolidayApiConstants { + + public static final String HOLIDAY_RESOURCE_NAME = "holiday"; + + // general + public static final String localeParamName = "locale"; + public static final String dateFormatParamName = "dateFormat"; + + //request parameters + public static final String name = "name"; + public static final String fromDate = "fromDate"; + public static final String toDate = "toDate"; + public static final String description = "description"; + public static final String offices = "offices"; + + public static final Set HOLIDAY_CREATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, + dateFormatParamName, name, fromDate, toDate, description, offices)); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidaysApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidaysApiResource.java new file mode 100644 index 000000000..da3394da4 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/api/HolidaysApiResource.java @@ -0,0 +1,45 @@ +package org.mifosplatform.organisation.holiday.api; + +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +import org.mifosplatform.commands.domain.CommandWrapper; +import org.mifosplatform.commands.service.CommandWrapperBuilder; +import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +@Path("/holidays") +@Component +@Scope("singleton") +public class HolidaysApiResource { + + private final DefaultToApiJsonSerializer toApiJsonSerializer; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + + @Autowired + public HolidaysApiResource(final DefaultToApiJsonSerializer toApiJsonSerializer, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { + this.toApiJsonSerializer = toApiJsonSerializer; + this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; + } + + @POST + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String createNewHoliday(final String apiRequestBodyAsJson) { + + final CommandWrapper commandRequest = new CommandWrapperBuilder().createHoliday().withJson(apiRequestBodyAsJson).build(); + + final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + + return this.toApiJsonSerializer.serialize(result); + } + + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/data/HolidayDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/data/HolidayDataValidator.java new file mode 100644 index 000000000..0076353e0 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/data/HolidayDataValidator.java @@ -0,0 +1,85 @@ + package org.mifosplatform.organisation.holiday.data; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashSet; +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.FromJsonHelper; +import org.mifosplatform.organisation.holiday.api.HolidayApiConstants; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +@Component +public class HolidayDataValidator { + + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public HolidayDataValidator(final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonHelper = fromApiJsonHelper; + } + + public void validateForCreate(final String json) { + + if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } + + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, HolidayApiConstants.HOLIDAY_CREATE_REQUEST_DATA_PARAMETERS); + final JsonElement element = fromApiJsonHelper.parse(json); + + final List dataValidationErrors = new ArrayList(); + + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(HolidayApiConstants.HOLIDAY_RESOURCE_NAME); + + final String name = this.fromApiJsonHelper.extractStringNamed(HolidayApiConstants.name, element); + baseDataValidator.reset().parameter(HolidayApiConstants.name).value(name).notBlank().notNull().notExceedingLengthOf(100); + + final LocalDate fromDate = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.fromDate, element); + baseDataValidator.reset().parameter(HolidayApiConstants.fromDate).value(fromDate).notNull(); + + final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.toDate, element); + baseDataValidator.reset().parameter(HolidayApiConstants.toDate).value(toDate).notNull(); + + + Set offices = null; + final JsonObject topLevelJsonElement = element.getAsJsonObject(); + + if (topLevelJsonElement.has(HolidayApiConstants.offices)&&topLevelJsonElement.get(HolidayApiConstants.offices).isJsonArray()) { + + final JsonArray array = topLevelJsonElement.get(HolidayApiConstants.offices).getAsJsonArray(); + if(array.size()>0) { + offices = new HashSet(array.size()); + for (int i = 0; i < array.size(); i++) { + final JsonObject officeElement = array.get(i).getAsJsonObject(); + final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", officeElement); + baseDataValidator.reset().parameter(HolidayApiConstants.offices).value(officeId).notNull(); + offices.add(officeId); + } + } + } + baseDataValidator.reset().parameter(HolidayApiConstants.offices).value(offices).notNull(); + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + + private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { + if (!dataValidationErrors.isEmpty()) { + // + throw new PlatformApiDataValidationException(dataValidationErrors); + } + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/Holiday.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/Holiday.java new file mode 100644 index 000000000..3fe735b76 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/Holiday.java @@ -0,0 +1,88 @@ +/** + * 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.organisation.holiday.domain; + +import java.util.Date; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.organisation.holiday.api.HolidayApiConstants; +import org.mifosplatform.organisation.office.domain.Office; +import org.springframework.data.jpa.domain.AbstractPersistable; + +@Entity +@Table(name = "m_holiday", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "holiday_name") }) +public class Holiday extends AbstractPersistable { + + @SuppressWarnings("unused") + @Column(name = "name", unique = true, nullable = false, length = 100) + private String name; + + @SuppressWarnings("unused") + @Column(name = "from_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date fromDate; + + @SuppressWarnings("unused") + @Column(name = "to_date", nullable = false) + @Temporal(TemporalType.DATE) + private Date toDate; + + @SuppressWarnings("unused") + @Column(name = "description", length = 100) + private String description; + + @SuppressWarnings("unused") + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = "m_holiday_office", joinColumns = @JoinColumn(name = "holiday_id"), inverseJoinColumns = @JoinColumn(name = "office_id")) + private Set offices; + + public static Holiday createNew(final Set offices, final JsonCommand command) { + final String name = command.stringValueOfParameterNamed(HolidayApiConstants.name); + final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate); + final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); + final String description = command.stringValueOfParameterNamed(HolidayApiConstants.description); + return new Holiday(name, fromDate, toDate, description, offices); + } + + private Holiday(final String name, final LocalDate fromDate, final LocalDate toDate, final String description, final Set offices) { + if (StringUtils.isNotBlank(name)) { + this.name = name.trim(); + } + + if (fromDate != null) { + this.fromDate = fromDate.toDate(); + } + + if (toDate != null) { + this.toDate = toDate.toDate(); + } + + if (StringUtils.isNotBlank(name)) { + this.description = description.trim(); + } else { + this.description = null; + } + + if (offices != null) { + this.offices = offices; + } + } + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java new file mode 100644 index 000000000..985351c1c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/domain/HolidayRepository.java @@ -0,0 +1,15 @@ +/** + * 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.organisation.holiday.domain; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +public interface HolidayRepository extends JpaRepository, + JpaSpecificationExecutor { + // no added behaviour +} + diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/handler/CreateHolidayCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/handler/CreateHolidayCommandHandler.java new file mode 100644 index 000000000..bbbc93e5f --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/handler/CreateHolidayCommandHandler.java @@ -0,0 +1,27 @@ +package org.mifosplatform.organisation.holiday.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class CreateHolidayCommandHandler implements NewCommandSourceHandler { + + private final HolidayWritePlatformService holidayWritePlatformService; + + @Autowired + public CreateHolidayCommandHandler(final HolidayWritePlatformService holidayWritePlatformService) { + this.holidayWritePlatformService = holidayWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.holidayWritePlatformService.createHoliday(command); + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayReadPlatformServiceImpl.java new file mode 100644 index 000000000..9cbbb708c --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayReadPlatformServiceImpl.java @@ -0,0 +1,5 @@ +package org.mifosplatform.organisation.holiday.service; + +public class HolidayReadPlatformServiceImpl { + +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformService.java new file mode 100644 index 000000000..8becdc951 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.organisation.holiday.service; + +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; + +public interface HolidayWritePlatformService { + + CommandProcessingResult createHoliday(JsonCommand command); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java new file mode 100644 index 000000000..18fe2b2de --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java @@ -0,0 +1,120 @@ +package org.mifosplatform.organisation.holiday.service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; +import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; +import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.organisation.holiday.api.HolidayApiConstants; +import org.mifosplatform.organisation.holiday.data.HolidayDataValidator; +import org.mifosplatform.organisation.holiday.domain.Holiday; +import org.mifosplatform.organisation.holiday.domain.HolidayRepository; +import org.mifosplatform.organisation.office.domain.Office; +import org.mifosplatform.organisation.office.domain.OfficeRepository; +import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +@Service +public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWritePlatformService { + + private final static Logger logger = LoggerFactory.getLogger(HolidayWritePlatformServiceJpaRepositoryImpl.class); + + private final HolidayDataValidator fromApiJsonDeserializer; + private final HolidayRepository holidayRepository; + private final PlatformSecurityContext context; + private final OfficeRepository officeRepository; + private final FromJsonHelper fromApiJsonHelper; + + @Autowired + public HolidayWritePlatformServiceJpaRepositoryImpl(final HolidayDataValidator fromApiJsonDeserializer, + final HolidayRepository holidayRepository, final PlatformSecurityContext context, final OfficeRepository officeRepository, + final FromJsonHelper fromApiJsonHelper) { + this.fromApiJsonDeserializer = fromApiJsonDeserializer; + this.holidayRepository = holidayRepository; + this.context = context; + this.officeRepository = officeRepository; + this.fromApiJsonHelper = fromApiJsonHelper; + } + + @Transactional + @Override + public CommandProcessingResult createHoliday(final JsonCommand command) { + + try { + this.context.authenticatedUser(); + this.fromApiJsonDeserializer.validateForCreate(command.json()); + + validateToDateBeforeFromDate(command); + + Set offices = null; + final JsonObject topLevelJsonElement = this.fromApiJsonHelper.parse(command.json()).getAsJsonObject(); + if (topLevelJsonElement.has(HolidayApiConstants.offices) && topLevelJsonElement.get(HolidayApiConstants.offices).isJsonArray()) { + + final JsonArray array = topLevelJsonElement.get(HolidayApiConstants.offices).getAsJsonArray(); + offices = new HashSet(array.size()); + for (int i = 0; i < array.size(); i++) { + final JsonObject officeElement = array.get(i).getAsJsonObject(); + final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", officeElement); + final Office office = this.officeRepository.findOne(officeId); + if (office == null) { throw new OfficeNotFoundException(officeId); } + offices.add(office); + } + } + + final Holiday holiday = Holiday.createNew(offices, command); + + this.holidayRepository.save(holiday); + + return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(holiday.getId()) + .withHolidayId(holiday.getId()).build(); + } catch (final DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve); + return CommandProcessingResult.empty(); + } + } + + private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + final Throwable realCause = dve.getMostSpecificCause(); + if (realCause.getMessage().contains("holiday_name")) { + final String name = command.stringValueOfParameterNamed("name"); + throw new PlatformDataIntegrityException("error.msg.holiday.duplicate.name", "Holiday with name `" + name + "` already exists", + "name", name); + } + + logger.error(dve.getMessage(), dve); + throw new PlatformDataIntegrityException("error.msg.office.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } + + private void validateToDateBeforeFromDate(final JsonCommand command) { + final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate); + final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); + if (toDate.isBefore(fromDate)) { + + final String defaultUserMessage = "ToDate date cannot be before the FromDate."; + final ApiParameterError error = ApiParameterError.parameterError("error.msg.holiday.toDate.cannot be.before.the.FromDate", + defaultUserMessage, "ToDate"); + final List dataValidationErrors = new ArrayList(); + dataValidationErrors.add(error); + + throw new PlatformApiDataValidationException(dataValidationErrors); + } + } +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/api/OfficesApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/api/OfficesApiResource.java index a5a1f09c0..6e9c6c249 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/api/OfficesApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/office/api/OfficesApiResource.java @@ -53,7 +53,7 @@ public class OfficesApiResource { private final OfficeReadPlatformService readPlatformService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; - private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; + private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @Autowired public OfficesApiResource(final PlatformSecurityContext context, final OfficeReadPlatformService readPlatformService,