From 7e9fc03dc59536f89b9372e1f0fdcb36dbb5e108 Mon Sep 17 00:00:00 2001 From: ashok-conflux Date: Fri, 28 Jun 2013 18:08:42 +0530 Subject: [PATCH] MIFOSX-518: capture alternative working date --- ...led_to_and_processed_column_to_holiday.sql | 3 + .../holiday/api/HolidayApiConstants.java | 4 +- .../holiday/data/HolidayDataValidator.java | 3 + .../organisation/holiday/domain/Holiday.java | 26 +++++++- .../exception/HolidayDateException.java | 17 +++++ ...WritePlatformServiceJpaRepositoryImpl.java | 66 +++++++++++-------- 6 files changed, 87 insertions(+), 32 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V73__add_repayments_rescheduled_to_and_processed_column_to_holiday.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/exception/HolidayDateException.java diff --git a/mifosng-db/migrations/core_db/V73__add_repayments_rescheduled_to_and_processed_column_to_holiday.sql b/mifosng-db/migrations/core_db/V73__add_repayments_rescheduled_to_and_processed_column_to_holiday.sql new file mode 100644 index 000000000..a6f57a7b8 --- /dev/null +++ b/mifosng-db/migrations/core_db/V73__add_repayments_rescheduled_to_and_processed_column_to_holiday.sql @@ -0,0 +1,3 @@ +ALTER TABLE `m_holiday` + ADD COLUMN `repayments_rescheduled_to` DATETIME NOT NULL AFTER `to_date`, + ADD COLUMN `processed` TINYINT(1) NOT NULL DEFAULT '0' AFTER `repayments_rescheduled_to`; \ 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 index c58e64b91..2c06aeef8 100644 --- 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 @@ -19,7 +19,9 @@ public class HolidayApiConstants { public static final String description = "description"; public static final String offices = "offices"; public static final String officeId = "officeId"; + public static final String repaymentsRescheduledTo = "repaymentsRescheduledTo"; + public static final String processed = "processed"; public static final Set HOLIDAY_CREATE_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, - dateFormatParamName, name, fromDate, toDate, description, offices)); + dateFormatParamName, name, fromDate, toDate, description, offices, repaymentsRescheduledTo)); } 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 index c141ac56f..413dec54f 100644 --- 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 @@ -54,6 +54,9 @@ public class HolidayDataValidator { final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.toDate, element); baseDataValidator.reset().parameter(HolidayApiConstants.toDate).value(toDate).notNull(); + + final LocalDate repaymentsRescheduledTo = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.repaymentsRescheduledTo, element); + baseDataValidator.reset().parameter(HolidayApiConstants.repaymentsRescheduledTo).value(repaymentsRescheduledTo).notNull(); Set offices = null; final JsonObject topLevelJsonElement = element.getAsJsonObject(); 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 index 3fe735b76..e620e40f8 100644 --- 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 @@ -44,6 +44,13 @@ public class Holiday extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date toDate; + @Column(name = "repayments_rescheduled_to", nullable = false) + @Temporal(TemporalType.DATE) + private Date repaymentsRescheduledTo; + + @Column(name = "processed", nullable = false) + private boolean processed; + @SuppressWarnings("unused") @Column(name = "description", length = 100) private String description; @@ -57,11 +64,13 @@ public class Holiday extends AbstractPersistable { final String name = command.stringValueOfParameterNamed(HolidayApiConstants.name); final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate); final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); + final LocalDate repaymentsRescheduledTo = command.localDateValueOfParameterNamed(HolidayApiConstants.repaymentsRescheduledTo); + final boolean processed = false;//default it to false. Only batch job should update this field. final String description = command.stringValueOfParameterNamed(HolidayApiConstants.description); - return new Holiday(name, fromDate, toDate, description, offices); + return new Holiday(name, fromDate, toDate, repaymentsRescheduledTo, processed, description, offices); } - private Holiday(final String name, final LocalDate fromDate, final LocalDate toDate, final String description, final Set offices) { + private Holiday(final String name, final LocalDate fromDate, final LocalDate toDate, final LocalDate repaymentsRescheduledTo, final boolean processed, final String description, final Set offices) { if (StringUtils.isNotBlank(name)) { this.name = name.trim(); } @@ -73,7 +82,13 @@ public class Holiday extends AbstractPersistable { if (toDate != null) { this.toDate = toDate.toDate(); } + + if (repaymentsRescheduledTo != null) { + this.repaymentsRescheduledTo = repaymentsRescheduledTo.toDate(); + } + this.processed = processed; + if (StringUtils.isNotBlank(name)) { this.description = description.trim(); } else { @@ -85,4 +100,11 @@ public class Holiday extends AbstractPersistable { } } + public Date getRepaymentsRescheduledTo() { + return this.repaymentsRescheduledTo; + } + + public boolean isProcessed() { + return this.processed; + } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/exception/HolidayDateException.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/exception/HolidayDateException.java new file mode 100644 index 000000000..d5e577b80 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/holiday/exception/HolidayDateException.java @@ -0,0 +1,17 @@ +/** + * 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.exception; + +import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException; + +public class HolidayDateException extends AbstractPlatformDomainRuleException { + + public HolidayDateException(String postFix, String defaultUserMessage, + Object... defaultUserMessageArgs) { + super("error.msg.holiday." + postFix, defaultUserMessage, defaultUserMessageArgs); + } + +} 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 index 15fff1f08..019ffc5be 100644 --- 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 @@ -1,16 +1,12 @@ 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; @@ -18,6 +14,7 @@ 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.holiday.exception.HolidayDateException; import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; @@ -61,22 +58,9 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit 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(HolidayApiConstants.officeId, officeElement); - final Office office = this.officeRepository.findOne(officeId); - if (office == null) { throw new OfficeNotFoundException(officeId); } - offices.add(office); - } - } + validateInputDates(command); + + final Set offices = getSelectedOffices(command); final Holiday holiday = Holiday.createNew(offices, command); @@ -89,6 +73,24 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit } } + private Set getSelectedOffices(final JsonCommand 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(HolidayApiConstants.officeId, officeElement); + final Office office = this.officeRepository.findOne(officeId); + if (office == null) { throw new OfficeNotFoundException(officeId); } + offices.add(office); + } + } + return offices; + } + private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("holiday_name")) { @@ -102,18 +104,24 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit "Unknown data integrity issue with resource."); } - private void validateToDateBeforeFromDate(final JsonCommand command) { + private void validateInputDates(final JsonCommand command) { final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate); final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); + final LocalDate repaymentsRescheduledTo = command.localDateValueOfParameterNamed(HolidayApiConstants.repaymentsRescheduledTo); 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); + final String defaultUserMessage = "To Date date cannot be before the From Date."; + throw new HolidayDateException("to.date.cannot.be.before.from.date", defaultUserMessage, fromDate.toString(), toDate.toString()); + } + + //validate alternative working date + //1. should be within a 7 days date range. + //2. Alternative date should not be an exist holiday.//TBD + //3. Holiday should not be on an alternate working date of another holiday.//TBD + + //restricting alternative working date to be within 7 days range before or after from date and to date. + if(repaymentsRescheduledTo.isBefore(fromDate.minusDays(7)) || repaymentsRescheduledTo.isAfter(toDate.plusDays(7))){ + final String defaultUserMessage = "Alternative working date must be within 7 days before or after from and to dates"; + throw new HolidayDateException("repayments.rescheduled.to.must.be.within.range", defaultUserMessage, fromDate.toString(), toDate.toString(), repaymentsRescheduledTo.toString()); } } }