diff --git a/mifosng-data/src/main/java/org/mifosng/data/command/OfficeCommand.java b/mifosng-data/src/main/java/org/mifosng/data/command/OfficeCommand.java index 4382ba530..35c16de92 100644 --- a/mifosng-data/src/main/java/org/mifosng/data/command/OfficeCommand.java +++ b/mifosng-data/src/main/java/org/mifosng/data/command/OfficeCommand.java @@ -19,7 +19,7 @@ public class OfficeCommand { private LocalDate openingDate; private Long parentId; - private boolean rootOffice = false; + private Boolean rootOffice = false; protected OfficeCommand() { // diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java index 5c968d6b4..de35718da 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/infrastructure/ApiDataConversionServiceImpl.java @@ -27,7 +27,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService { eventLocalDate = DateTimeFormat.forPattern(dateFormat).withLocale(locale).parseLocalDate(dateAsString.toLowerCase(locale)); } catch (IllegalArgumentException e) { List dataValidationErrors = new ArrayList(); - ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.date.format", "The parameter " + parameterName + " is invalid.", parameterName, dateAsString); + ApiParameterError error = ApiParameterError.parameterError("validation.msg.invalid.date.format", "The parameter " + parameterName + " is invalid based on the dateFormat provided:" + dateFormat, parameterName, dateAsString, dateFormat); dataValidationErrors.add(error); throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java index 421e82a5e..4255e271e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/domain/Office.java @@ -17,6 +17,7 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.mifosng.data.command.OfficeCommand; import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.user.domain.AppUser; @@ -102,15 +103,25 @@ public class Office extends AbstractAuditableCustom { return this.parent == null; } - public void update(final String newNname, final String newExternalId, - final LocalDate newOpeningDate) { - this.name = newNname; - this.externalId = newExternalId; - this.openingDate = newOpeningDate.toDateMidnight().toDate(); - } + public void update(OfficeCommand command) { + // ignore nulls when updating + if (command.getName() != null) { + this.name = command.getName().trim(); + } + + if (command.getExternalId() != null) { + this.externalId = command.getExternalId().trim(); + } + + if (command.getOpeningDate() != null) { + this.openingDate = command.getOpeningDate().toDate(); + } + } + public void update(Office newParent) { this.parent = newParent; + generateHierarchy(); } public boolean identifiedBy(String identifier) { diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java index dbc7ccf63..75ce13e3c 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeCommandValidator.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; import org.mifosng.data.ApiParameterError; import org.mifosng.data.command.OfficeCommand; import org.mifosng.platform.exceptions.PlatformApiDataValidationException; @@ -15,8 +16,8 @@ public class OfficeCommandValidator { public OfficeCommandValidator(OfficeCommand command) { this.command = command; } - - public void validate() { + + public void validateForCreate() { List dataValidationErrors = new ArrayList(); @@ -46,4 +47,64 @@ public class OfficeCommandValidator { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); } } + + public void validateForUpdate() { + List dataValidationErrors = new ArrayList(); + + if (command.getId() == null) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.office.id.cannot.be.blank", "A valid id must be provided.", "id"); + dataValidationErrors.add(error); + } + + boolean ignoreNulls = true; + + // NOTE: remember for updates that values that are null are ignored from validation and update. + boolean nameHasData = validateParameterNotEmpty(this.command.getName(), "office", "name", ignoreNulls, dataValidationErrors); + boolean openingDateHasData = validateParameterNotEmpty(this.command.getOpeningDateFormatted(), "office", "openingDateFormatted", ignoreNulls, dataValidationErrors); + boolean externalIdHasData = validateParameterNotGreaterThan(100, this.command.getExternalId(), "office", "externalId", ignoreNulls, dataValidationErrors); + boolean parentidHasData = validateParameterNotNull(this.command.getParentId(), "office", "parentid", ignoreNulls, dataValidationErrors); + + if (!anyOfTrue(nameHasData, openingDateHasData, externalIdHasData, parentidHasData)) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg.office.no.parameters.for.update", "No parameters passed for update.", "id"); + dataValidationErrors.add(error); + } + + if (!dataValidationErrors.isEmpty()) { + throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); + } + } + + private boolean anyOfTrue(boolean nameHasData, boolean openingDateHasData, boolean externalIdHasData, boolean parentidHasData) { + return nameHasData || openingDateHasData || externalIdHasData || parentidHasData; + } + + private boolean validateParameterNotNull(Long value, String resourceName, String parameterName, boolean ignoreNulls, List dataValidationErrors) { + if (value == null && ignoreNulls) return false; + return true; + } + + private boolean validateParameterNotGreaterThan(Integer maxLength, String value, String resourceName, String parameterName, boolean ignoreNulls, List dataValidationErrors) { + if (value == null && ignoreNulls) return false; + + if (this.command.getExternalId().trim().length() > maxLength) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg." + resourceName + "." + parameterName + ".exceeds.max.length", "The parameter " + parameterName + " exceeds max length of " + maxLength + ".", parameterName, maxLength); + dataValidationErrors.add(error); + return true; + } + + return true; + } + + private boolean validateParameterNotEmpty(String value, String resourceName, String parameterName, boolean ignoreNulls, List dataValidationErrors) { + + if (value == null && ignoreNulls) return false; + + if (StringUtils.isBlank(value)) { + ApiParameterError error = ApiParameterError.parameterError("validation.msg." + resourceName + "." + parameterName + ".cannot.be.blank", "The parameter " + parameterName + " cannot be blank.", parameterName); + dataValidationErrors.add(error); + return true; + } + + return true; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java index 5af27656a..bec2b2555 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/organisation/service/OfficeWritePlatformServiceJpaRepositoryImpl.java @@ -39,7 +39,7 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP AppUser currentUser = context.authenticatedUser(); OfficeCommandValidator validator = new OfficeCommandValidator(command); - validator.validate(); + validator.validateForCreate(); Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); @@ -67,13 +67,13 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP AppUser currentUser = context.authenticatedUser(); OfficeCommandValidator validator = new OfficeCommandValidator(command); - validator.validate(); + validator.validateForUpdate(); Office office = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getId()); - office.update(command.getName(), command.getExternalId(), command.getOpeningDate()); + office.update(command); - if (!command.isRootOffice()) { + if (!command.isRootOffice() && command.getParentId() != null) { Office parent = validateUserPriviledgeOnOfficeAndRetrieve(currentUser, command.getParentId()); office.update(parent); }