MIFOSX-518: capture alternative working date

This commit is contained in:
ashok-conflux
2013-07-01 18:14:49 +05:30
parent cf20cae7d7
commit 7e9fc03dc5
6 changed files with 87 additions and 32 deletions
@@ -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`;
@@ -19,7 +19,9 @@ public class HolidayApiConstants {
public static final String description = "description"; public static final String description = "description";
public static final String offices = "offices"; public static final String offices = "offices";
public static final String officeId = "officeId"; public static final String officeId = "officeId";
public static final String repaymentsRescheduledTo = "repaymentsRescheduledTo";
public static final String processed = "processed";
public static final Set<String> HOLIDAY_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName, public static final Set<String> HOLIDAY_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, name, fromDate, toDate, description, offices)); dateFormatParamName, name, fromDate, toDate, description, offices, repaymentsRescheduledTo));
} }
@@ -55,6 +55,9 @@ public class HolidayDataValidator {
final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.toDate, element); final LocalDate toDate = this.fromApiJsonHelper.extractLocalDateNamed(HolidayApiConstants.toDate, element);
baseDataValidator.reset().parameter(HolidayApiConstants.toDate).value(toDate).notNull(); 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<Long> offices = null; Set<Long> offices = null;
final JsonObject topLevelJsonElement = element.getAsJsonObject(); final JsonObject topLevelJsonElement = element.getAsJsonObject();
@@ -44,6 +44,13 @@ public class Holiday extends AbstractPersistable<Long> {
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date toDate; 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") @SuppressWarnings("unused")
@Column(name = "description", length = 100) @Column(name = "description", length = 100)
private String description; private String description;
@@ -57,11 +64,13 @@ public class Holiday extends AbstractPersistable<Long> {
final String name = command.stringValueOfParameterNamed(HolidayApiConstants.name); final String name = command.stringValueOfParameterNamed(HolidayApiConstants.name);
final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate); final LocalDate fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate);
final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); 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); 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<Office> offices) { private Holiday(final String name, final LocalDate fromDate, final LocalDate toDate, final LocalDate repaymentsRescheduledTo, final boolean processed, final String description, final Set<Office> offices) {
if (StringUtils.isNotBlank(name)) { if (StringUtils.isNotBlank(name)) {
this.name = name.trim(); this.name = name.trim();
} }
@@ -74,6 +83,12 @@ public class Holiday extends AbstractPersistable<Long> {
this.toDate = toDate.toDate(); this.toDate = toDate.toDate();
} }
if (repaymentsRescheduledTo != null) {
this.repaymentsRescheduledTo = repaymentsRescheduledTo.toDate();
}
this.processed = processed;
if (StringUtils.isNotBlank(name)) { if (StringUtils.isNotBlank(name)) {
this.description = description.trim(); this.description = description.trim();
} else { } else {
@@ -85,4 +100,11 @@ public class Holiday extends AbstractPersistable<Long> {
} }
} }
public Date getRepaymentsRescheduledTo() {
return this.repaymentsRescheduledTo;
}
public boolean isProcessed() {
return this.processed;
}
} }
@@ -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);
}
}
@@ -1,16 +1,12 @@
package org.mifosplatform.organisation.holiday.service; package org.mifosplatform.organisation.holiday.service;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand; 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.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; 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.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; 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.data.HolidayDataValidator;
import org.mifosplatform.organisation.holiday.domain.Holiday; import org.mifosplatform.organisation.holiday.domain.Holiday;
import org.mifosplatform.organisation.holiday.domain.HolidayRepository; 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.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
@@ -61,22 +58,9 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
this.context.authenticatedUser(); this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForCreate(command.json()); this.fromApiJsonDeserializer.validateForCreate(command.json());
validateToDateBeforeFromDate(command); validateInputDates(command);
Set<Office> offices = null; final Set<Office> offices = getSelectedOffices(command);
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<Office>(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);
}
}
final Holiday holiday = Holiday.createNew(offices, command); final Holiday holiday = Holiday.createNew(offices, command);
@@ -89,6 +73,24 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
} }
} }
private Set<Office> getSelectedOffices(final JsonCommand command) {
Set<Office> 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<Office>(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) { private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause(); final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("holiday_name")) { if (realCause.getMessage().contains("holiday_name")) {
@@ -102,18 +104,24 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit
"Unknown data integrity issue with resource."); "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 fromDate = command.localDateValueOfParameterNamed(HolidayApiConstants.fromDate);
final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate); final LocalDate toDate = command.localDateValueOfParameterNamed(HolidayApiConstants.toDate);
final LocalDate repaymentsRescheduledTo = command.localDateValueOfParameterNamed(HolidayApiConstants.repaymentsRescheduledTo);
if (toDate.isBefore(fromDate)) { if (toDate.isBefore(fromDate)) {
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());
}
final String defaultUserMessage = "ToDate date cannot be before the FromDate."; //validate alternative working date
final ApiParameterError error = ApiParameterError.parameterError("error.msg.holiday.toDate.cannot be.before.the.FromDate", //1. should be within a 7 days date range.
defaultUserMessage, "ToDate"); //2. Alternative date should not be an exist holiday.//TBD
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); //3. Holiday should not be on an alternate working date of another holiday.//TBD
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors); //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());
} }
} }
} }