MIFOSX-765: update validation for timeline fields on client and group.

This commit is contained in:
Keith Woodlock
2013-11-15 12:25:38 +00:00
8 changed files with 151 additions and 65 deletions
+35 -3
View File
@@ -2053,7 +2053,8 @@ Content-Type: application/json Request Body:
"dateFormat": "dd MMMM yyyy",
"locale": "en",
"active": true,
"activationDate": "04 March 2009"
"activationDate": "04 March 2009",
"submittedOnDate":"04 March 2009"
}
</code>
<code class="method-response">
@@ -2378,6 +2379,16 @@ GET https://DomainName/api/v1/clients/{clientId}
"displayName": "Client of group",
"officeId": 1,
"officeName": "Head Office",
"timeline": {
"activatedOnDate": [
2009,
3,
4
],
"activatedByUsername": "mifos",
"activatedByFirstname": "App",
"activatedByLastname": "Administrator"
},
"groups": [
{
"id": 1,
@@ -3908,7 +3919,8 @@ Content-Type: application/json Request Body:
"dateFormat": "dd MMMM yyyy",
"locale": "en",
"active": true,
"activationDate": "04 March 2009"
"activationDate": "04 March 2009",
"submittedOnDate":"04 March 2009"
}
</code>
<code class="method-response">
@@ -4127,7 +4139,17 @@ GET https://DomainName/mifosng-provider/api/v1/groups/1
"externalId": "000-1A",
"officeId": 1,
"officeName": "Head Office",
"hierarchy": ".1."
"hierarchy": ".1.",
"timeline": {
"activatedOnDate": [
2013,
11,
14
],
"activatedByUsername": "mifos",
"activatedByFirstname": "App",
"activatedByLastname": "Administrator"
}
}
</code>
</div>
@@ -4144,6 +4166,16 @@ GET https://DomainName/mifosng-provider/api/v1/groups/1?associations=clientMembe
"officeId": 1,
"officeName": "Head Office",
"hierarchy": ".1.",
"timeline": {
"activatedOnDate": [
2013,
11,
14
],
"activatedByUsername": "mifos",
"activatedByFirstname": "App",
"activatedByLastname": "Administrator"
},
"clientMembers": [
{
"id": 1,
@@ -57,7 +57,7 @@ public class ClientApiConstants {
public static final Set<String> CLIENT_CREATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, groupIdParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName,
middlenameParamName, lastnameParamName, fullnameParamName, officeIdParamName, activeParamName, activationDateParamName,
staffIdParamName));
staffIdParamName,submittedOnDateParamName));
public static final Set<String> CLIENT_UPDATE_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, accountNoParamName, externalIdParamName, mobileNoParamName, firstnameParamName, middlenameParamName,
@@ -132,6 +132,12 @@ public final class ClientDataValidator {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
}
if (this.fromApiJsonHelper.parameterExists(ClientApiConstants.submittedOnDateParamName, element))
{
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.submittedOnDateParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.submittedOnDateParamName).value(submittedOnDate).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -151,11 +151,6 @@ public final class Client extends AbstractPersistable<Long> {
final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
LocalDate submittedOnDate = new LocalDate();
if (command.hasParameter(ClientApiConstants.submittedOnDateParamName)) {
submittedOnDate = command.localDateValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
}
ClientStatus status = ClientStatus.PENDING;
boolean active = false;
if (command.hasParameter("active")) {
@@ -168,18 +163,14 @@ public final class Client extends AbstractPersistable<Long> {
status = ClientStatus.ACTIVE;
activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
officeJoiningDate = activationDate;
if (activationDate.isAfter(DateUtils.getLocalDateOfTenant())) {
final String defaultUserMessage = "Activation date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.activationDate.in.the.future",
defaultUserMessage, ClientApiConstants.activationDateParamName, activationDate);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors);
}
}
LocalDate submittedOnDate = new LocalDate();
if (active && submittedOnDate.isAfter(activationDate)) {
submittedOnDate = activationDate;
}
if (command.hasParameter(ClientApiConstants.submittedOnDateParamName)) {
submittedOnDate = command.localDateValueOfParameterNamed(ClientApiConstants.submittedOnDateParamName);
}
return new Client(currentUser, status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname,
@@ -202,18 +193,6 @@ public final class Client extends AbstractPersistable<Long> {
this.accountNumber = accountNo;
}
if (isDateInTheFuture(submittedOnDate)) {
final String defaultUserMessage = "submitted date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.submittedOnDate.in.the.future",
defaultUserMessage, ClientApiConstants.submittedOnDateParamName, submittedOnDate);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors);
}
this.submittedOnDate = submittedOnDate.toDate();
this.submittedBy = currentUser;
@@ -302,6 +281,7 @@ public final class Client extends AbstractPersistable<Long> {
}
public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) {
if (isActive()) {
final String defaultUserMessage = "Cannot activate client. Client is already active.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.already.active", defaultUserMessage,
@@ -461,6 +441,24 @@ public final class Client extends AbstractPersistable<Long> {
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
final String defaultUserMessage = "submitted date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.submittedOnDate.in.the.future",
defaultUserMessage, ClientApiConstants.submittedOnDateParamName, this.submittedOnDate);
dataValidationErrors.add(error);
}
if (getActivationLocalDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getActivationLocalDate())) {
final String defaultUserMessage = "submitted date cannot be after the activation date";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.clients.submittedOnDate.after.activation.date",
defaultUserMessage, ClientApiConstants.submittedOnDateParamName, this.submittedOnDate);
dataValidationErrors.add(error);
}
if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) {
final String defaultUserMessage = "Activation date cannot be in the future.";
@@ -470,7 +468,7 @@ public final class Client extends AbstractPersistable<Long> {
dataValidationErrors.add(error);
}
if (this.activationDate != null) {
if (getActivationLocalDate() != null) {
if (this.office.isOpeningDateAfter(getActivationLocalDate())) {
final String defaultUserMessage = "Client activation date cannot be a date before the office opening date.";
final ApiParameterError error = ApiParameterError.parameterError(
@@ -65,7 +65,7 @@ public class GroupingTypesApiConstants {
public static final Set<String> CENTER_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, idParamName, nameParamName, externalIdParamName, officeIdParamName, staffIdParamName, activeParamName,
activationDateParamName, groupMembersParamName));
activationDateParamName, groupMembersParamName,submittedOnDateParamName));
public static final Set<String> GROUP_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName, dateFormatParamName,
idParamName, nameParamName, externalIdParamName, centerIdParamName, officeIdParamName, staffIdParamName, activeParamName,
@@ -28,6 +28,7 @@ import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
@@ -38,6 +39,7 @@ import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidation
import org.mifosplatform.infrastructure.core.service.DateUtils;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants;
import org.mifosplatform.portfolio.group.exception.ClientExistInGroupException;
@@ -133,15 +135,14 @@ public final class Group extends AbstractPersistable<Long> {
LocalDate groupActivationDate = null;
if (active) {
status = GroupingTypeStatus.ACTIVE;
groupActivationDate = activationDate;// set activation date only if
// group is made active
groupActivationDate = activationDate;
}
return new Group(office, staff, parent, groupLevel, name, externalId, status, groupActivationDate, clientMembers, groupMembers,
submittedOnDate, currentUser);
}
public Group(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel, final String name,
private Group(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel, final String name,
final String externalId, final GroupingTypeStatus status, final LocalDate activationDate, final Set<Client> clientMembers,
final Set<Group> groupMembers, final LocalDate submittedOnDate, final AppUser currentUser) {
this.office = office;
@@ -176,20 +177,56 @@ public final class Group extends AbstractPersistable<Long> {
this.groupMembers.addAll(groupMembers);
}
if (isDateInTheFuture(submittedOnDate)) {
final String defaultUserMessage = "submitted date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.submittedOnDate.in.the.future",
defaultUserMessage, "SubmittedOnDate");
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors);
}
this.submittedOnDate = submittedOnDate.toDate();
this.submittedBy = currentUser;
validate();
}
private void validate() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
validateActivationDate(dataValidationErrors);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
private void validateActivationDate(final List<ApiParameterError> dataValidationErrors) {
if (getSubmittedOnDate() != null && isDateInTheFuture(getSubmittedOnDate())) {
final String defaultUserMessage = "Submitted on date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.submittedOnDate.in.the.future",
defaultUserMessage, ClientApiConstants.submittedOnDateParamName, this.submittedOnDate);
dataValidationErrors.add(error);
}
if (getActivationLocalDate() != null && getSubmittedOnDate() != null && getSubmittedOnDate().isAfter(getActivationLocalDate())) {
final String defaultUserMessage = "Submitted on date cannot be after the activation date";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.submittedOnDate.after.activation.date",
defaultUserMessage, GroupingTypesApiConstants.submittedOnDateParamName, this.submittedOnDate);
dataValidationErrors.add(error);
}
if (getActivationLocalDate() != null && isDateInTheFuture(getActivationLocalDate())) {
final String defaultUserMessage = "Activation date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.activationDate.in.the.future",
defaultUserMessage, GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate());
dataValidationErrors.add(error);
}
if (getActivationLocalDate() != null) {
if (this.office.isOpeningDateAfter(getActivationLocalDate())) {
final String defaultUserMessage = "Activation date cannot be a date before the office opening date.";
final ApiParameterError error = ApiParameterError.parameterError(
"error.msg.group.activationDate.cannot.be.before.office.activation.date", defaultUserMessage,
GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate());
dataValidationErrors.add(error);
}
}
}
public void activate(final AppUser currentUser, final DateTimeFormatter formatter, final LocalDate activationLocalDate) {
@@ -204,21 +241,11 @@ public final class Group extends AbstractPersistable<Long> {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
if (isDateInTheFuture(activationLocalDate)) {
final String defaultUserMessage = "Activation date cannot be in the future.";
final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.activationDate.in.the.future",
defaultUserMessage, "activationDate", activationLocalDate);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors);
}
this.activationDate = activationLocalDate.toDate();
this.status = GroupingTypeStatus.ACTIVE.getValue();
this.activatedBy = currentUser;
validate();
}
public boolean isActivatedAfter(final LocalDate submittedOn) {
@@ -292,6 +319,10 @@ public final class Group extends AbstractPersistable<Long> {
return actualChanges;
}
public LocalDate getSubmittedOnDate() {
return (LocalDate) ObjectUtils.defaultIfNull(new LocalDate(this.submittedOnDate), null);
}
public LocalDate getActivationLocalDate() {
LocalDate activationLocalDate = null;
if (this.activationDate != null) {
@@ -97,6 +97,12 @@ public final class GroupingTypesDataValidator {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
}
if (this.fromApiJsonHelper.parameterExists(GroupingTypesApiConstants.submittedOnDateParamName, element))
{
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(GroupingTypesApiConstants.submittedOnDateParamName, element);
baseDataValidator.reset().parameter(GroupingTypesApiConstants.submittedOnDateParamName).value(submittedOnDate).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -155,6 +161,12 @@ public final class GroupingTypesDataValidator {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
}
if (this.fromApiJsonHelper.parameterExists(GroupingTypesApiConstants.submittedOnDateParamName, element))
{
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(GroupingTypesApiConstants.submittedOnDateParamName, element);
baseDataValidator.reset().parameter(GroupingTypesApiConstants.submittedOnDateParamName).value(submittedOnDate).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -209,6 +221,12 @@ public final class GroupingTypesDataValidator {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
}
if (this.fromApiJsonHelper.parameterExists(GroupingTypesApiConstants.submittedOnDateParamName, element))
{
final LocalDate submittedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(GroupingTypesApiConstants.submittedOnDateParamName, element);
baseDataValidator.reset().parameter(GroupingTypesApiConstants.submittedOnDateParamName).value(submittedOnDate).notNull();
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}
@@ -132,14 +132,15 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
final Set<Group> groupMembers = assembleSetOfChildGroups(officeId, command);
final boolean active = command.booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.activeParamName);
LocalDate submittedOnDate = new LocalDate();
if (active && submittedOnDate.isAfter(activationDate)) {
submittedOnDate = activationDate;
}
if(command.hasParameter(GroupingTypesApiConstants.submittedOnDateParamName)){
submittedOnDate = command.localDateValueOfParameterNamed(GroupingTypesApiConstants.submittedOnDateParamName);
}
final boolean active = command.booleanPrimitiveValueOfParameterNamed(GroupingTypesApiConstants.activeParamName);
final Group newGroup = Group.newGroup(groupOffice, staff, parentGroup, groupLevel, name, externalId, active, activationDate,
clientMembers, groupMembers,submittedOnDate,currentUser);
@@ -193,7 +194,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
try {
this.fromApiJsonDeserializer.validateForActivation(command, GroupingTypesApiConstants.GROUP_RESOURCE_NAME);
AppUser currentUser = this.context.authenticatedUser();
final AppUser currentUser = this.context.authenticatedUser();
final Group group = this.groupRepository.findOneWithNotFoundDetection(groupId);