From 604f07f13ece01b917c978704d993940d4d2a2e1 Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Fri, 19 Apr 2013 00:43:13 +0100 Subject: [PATCH] MIFOSX-213: wip statuses on center and group data and remove is_deleted from client. --- api-docs/apiLive.htm | 21 +- ...-configuration-for-client-group-status.sql | 4 + .../commands/domain/CommandWrapper.java | 10 +- .../service/CommandWrapperBuilder.java | 37 ++- .../SynchronousCommandProcessingService.java | 4 + .../domain/ConfigurationDomainService.java | 2 - .../domain/ConfigurationDomainServiceJpa.java | 9 - .../staff/domain/StaffRepositoryWrapper.java | 8 +- .../portfolio/client/data/ClientData.java | 40 +-- .../client/data/ClientDataValidator.java | 17 +- .../portfolio/client/domain/Client.java | 128 +++++----- .../domain/ClientRepositoryWrapper.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 27 +- .../ClientReadPlatformServiceImpl.java | 33 ++- ...WritePlatformServiceJpaRepositoryImpl.java | 26 +- .../group/api/CentersApiResource.java | 29 +++ .../group/api/GroupingTypesApiConstants.java | 8 +- .../group/api/GroupsApiResource.java | 29 +++ .../group/data/GroupGeneralData.java | 66 +++-- .../portfolio/group/domain/Group.java | 233 +++++++++++++----- .../group/domain/GroupRepositoryWrapper.java | 45 ++++ .../handler/ActivateCenterCommandHandler.java | 32 +++ .../handler/ActivateGroupCommandHandler.java | 32 +++ .../GroupingTypesDataValidator.java | 52 +--- .../service/AllGroupTypesDataMapper.java | 12 +- .../CenterReadPlatformServiceImpl.java | 19 +- .../GroupingTypesWritePlatformService.java | 2 + ...WritePlatformServiceJpaRepositoryImpl.java | 144 +++++------ ...WritePlatformServiceJpaRepositoryImpl.java | 59 ++--- .../loanaccount/service/LoanAssembler.java | 12 +- .../LoanChargeReadPlatformServiceImpl.java | 4 +- .../service/LoanReadPlatformServiceImpl.java | 17 +- ...WritePlatformServiceJpaRepositoryImpl.java | 47 ++-- .../domain/SavingsAccountAssembler.java | 10 +- ...WritePlatformServiceJpaRepositoryImpl.java | 10 +- 35 files changed, 743 insertions(+), 487 deletions(-) create mode 100644 mifosng-db/migrations/core_db/V23__remove-enable-disable-configuration-for-client-group-status.sql create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupRepositoryWrapper.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateCenterCommandHandler.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateGroupCommandHandler.java diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 86d319a1e..486da1890 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -1706,7 +1706,7 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti

Clients

Clients are people and businesses that have applied (or may apply) to an MFI for loans.

-

Clients can be created in Pending state (as opposed to Active state) if global configuration for allow-pending-client-status is enabled.

+

Clients can be created in Pending or straight into Active state.

@@ -1733,7 +1733,7 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti - @@ -1804,7 +1804,6 @@ GET https://DomainName/api/v1/clients/template 17 ], "officeId": 1, - "clientPendingApprovalAllowed": false, "officeOptions": [ { "id": 1, @@ -2946,7 +2945,7 @@ Request Body: { - "officeId": 8, + "officeId": 1, "groupId": 8, "resourceId": 8, "changes": { @@ -7267,8 +7266,6 @@ Request Body:

Global configuration related to set of supported enable/disable configurations:

  1. maker-checker - defaults to false - if true turns on maker-checker functionality
  2. -
  3. allow-pending-client-status - defaults to false - if true allows clients to be created in 'Pending' state
  4. -
  5. allow-pending-group-status - defaults to false - if true allows groups to be created in 'Pending' state
@@ -7291,14 +7288,6 @@ GET https://DomainName/api/v1/configurations { "name": "maker-checker", "enabled": false - }, - { - "name": "allow-pending-client-status", - "enabled": false - }, - { - "name": "allow-pending-group-status", - "enabled": false } ] } @@ -7314,7 +7303,7 @@ GET https://DomainName/api/v1/configurations
-PUT https://DomainName/api/v1/configurations?allow-pending-client-status=false +PUT https://DomainName/api/v1/configurations?maker-checker=false PUT configurations @@ -7325,7 +7314,7 @@ Request Body: { } { "changes": { "globalConfiguration": { - "allow-pending-client-status": false + "maker-checker": false } } } diff --git a/mifosng-db/migrations/core_db/V23__remove-enable-disable-configuration-for-client-group-status.sql b/mifosng-db/migrations/core_db/V23__remove-enable-disable-configuration-for-client-group-status.sql new file mode 100644 index 000000000..71dbe7691 --- /dev/null +++ b/mifosng-db/migrations/core_db/V23__remove-enable-disable-configuration-for-client-group-status.sql @@ -0,0 +1,4 @@ +DELETE FROM `c_configuration` WHERE `name`='allow-pending-client-status'; +DELETE FROM `c_configuration` WHERE `name`='allow-pending-group-status'; + +ALTER TABLE `m_client` DROP COLUMN `is_deleted`; \ 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 0fb231e2a..435ffe5a3 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 @@ -265,6 +265,14 @@ public class CommandWrapper { return this.actionName.equalsIgnoreCase("ACTIVATE") && this.entityName.equalsIgnoreCase("CLIENT"); } + public boolean isGroupActivation() { + return this.actionName.equalsIgnoreCase("ACTIVATE") && this.entityName.equalsIgnoreCase("GROUP"); + } + + public boolean isCenterActivation() { + return this.actionName.equalsIgnoreCase("ACTIVATE") && this.entityName.equalsIgnoreCase("CENTER"); + } + public boolean isClientIdentifierResource() { return this.entityName.equals("CLIENTIDENTIFIER"); } @@ -483,7 +491,7 @@ public class CommandWrapper { public boolean isCenterResource() { return this.entityName.equalsIgnoreCase("CENTER"); } - + public boolean isReportResource() { return this.entityName.equalsIgnoreCase("REPORT"); } 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 434ba0983..f1437c0ab 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 @@ -834,6 +834,25 @@ public class CommandWrapperBuilder { this.actionName = "UPDATE"; this.entityName = "GROUP"; this.entityId = groupId; + this.groupId = groupId; + this.href = "/groups/" + groupId; + return this; + } + + public CommandWrapperBuilder activateGroup(final Long groupId) { + this.actionName = "ACTIVATE"; + this.entityName = "GROUP"; + this.entityId = groupId; + this.groupId = groupId; + this.href = "/groups/" + groupId + "?command=activate"; + return this; + } + + public CommandWrapperBuilder deleteGroup(final Long groupId) { + this.actionName = "DELETE"; + this.entityName = "GROUP"; + this.entityId = groupId; + this.groupId = groupId; this.href = "/groups/" + groupId; return this; } @@ -842,14 +861,7 @@ public class CommandWrapperBuilder { this.actionName = "UNASSIGNSTAFF"; this.entityName = "GROUP"; this.entityId = groupId; - this.href = "/groups/" + groupId; - return this; - } - - public CommandWrapperBuilder deleteGroup(final Long groupId) { - this.actionName = "DELETE"; - this.entityName = "GROUP"; - this.entityId = groupId; + this.groupId = groupId; this.href = "/groups/" + groupId; return this; } @@ -911,4 +923,13 @@ public class CommandWrapperBuilder { this.href = "/centers/" + centerId; return this; } + + public CommandWrapperBuilder activateCenter(final Long centerId) { + this.actionName = "ACTIVATE"; + this.entityName = "CENTER"; + this.entityId = centerId; + this.groupId = centerId; + this.href = "/centers/" + centerId + "?command=activate"; + 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 2a8003cce..16ecf3af1 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 @@ -398,6 +398,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer handler = applicationContext.getBean("unassignStaffCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isDelete()) { handler = applicationContext.getBean("deleteGroupCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isGroupActivation()) { + handler = applicationContext.getBean("activateGroupCommandHandler", NewCommandSourceHandler.class); } else { throw new UnsupportedCommandException(wrapper.commandName()); } @@ -408,6 +410,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer handler = applicationContext.getBean("updateCenterCommandHandler", NewCommandSourceHandler.class); } else if (wrapper.isDelete()) { handler = applicationContext.getBean("deleteCenterCommandHandler", NewCommandSourceHandler.class); + } else if (wrapper.isCenterActivation()) { + handler = applicationContext.getBean("activateCenterCommandHandler", NewCommandSourceHandler.class); } else { throw new UnsupportedCommandException(wrapper.commandName()); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java index 4f3e775dc..1c63e5f35 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainService.java @@ -8,6 +8,4 @@ package org.mifosplatform.infrastructure.configuration.domain; public interface ConfigurationDomainService { boolean isMakerCheckerEnabledForTask(String taskPermissionCode); - - boolean isClientPendingApprovalAllowedEnabled(); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java index 03c03079a..110c66b42 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/infrastructure/configuration/domain/ConfigurationDomainServiceJpa.java @@ -39,13 +39,4 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService return thisTask.hasMakerCheckerEnabled() && property.isEnabled(); } - - @Override - public boolean isClientPendingApprovalAllowedEnabled() { - final String propertyKey = "allow-pending-client-status"; - final GlobalConfigurationProperty property = this.globalConfigurationRepository.findOneByName(propertyKey); - if (property == null) { throw new GlobalConfigurationPropertyNotFoundException(propertyKey); } - - return property.isEnabled(); - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffRepositoryWrapper.java index 3acb21d56..536bab369 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffRepositoryWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/domain/StaffRepositoryWrapper.java @@ -6,13 +6,12 @@ package org.mifosplatform.organisation.staff.domain; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; -import org.mifosplatform.portfolio.client.domain.ClientRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** *

- * Wrapper for {@link ClientRepository} that adds NULL checking and Error + * Wrapper for {@link StaffRepository} that adds NULL checking and Error * handling capabilities *

*/ @@ -32,4 +31,9 @@ public class StaffRepositoryWrapper { return staff; } + public Staff findByOfficeWithNotFoundDetection(final Long staffId, final Long officeId) { + final Staff staff = this.repository.findByOffice(staffId, officeId); + if (staff == null) { throw new StaffNotFoundException(staffId); } + return staff; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java index 1126638fa..d4ee1e225 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java @@ -27,6 +27,8 @@ final public class ClientData implements Comparable { private final String externalId; private final EnumOptionData status; + @SuppressWarnings("unused") + private final Boolean active; private final LocalDate activationDate; private final String firstname; @@ -42,33 +44,27 @@ final public class ClientData implements Comparable { @SuppressWarnings("unused") private final Boolean imagePresent; - private final Boolean clientPendingApprovalAllowed; - // associations private final Collection groups; // template private final Collection officeOptions; - public static ClientData template(final Long officeId, final LocalDate joinedDate, final Boolean clientPendingApprovalAllowed, - final Collection allowedOffices) { - return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, - clientPendingApprovalAllowed, allowedOffices, null); + public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection officeOptions) { + return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, officeOptions, null); } public static ClientData templateOnTop(final ClientData clientData, final List allowedOffices) { return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, - clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed, - allowedOffices, clientData.groups); + clientData.externalId, clientData.activationDate, clientData.imageKey, allowedOffices, clientData.groups); } public static ClientData setParentGroups(final ClientData clientData, final Collection parentGroups) { return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, - clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed, - clientData.officeOptions, parentGroups); + clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.officeOptions, parentGroups); } public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname, @@ -76,19 +72,31 @@ final public class ClientData implements Comparable { final String officeName) { return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null, - null, null, null, null, null); + null, null, null, null); } public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) { - return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null); + return new ClientData(null, null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null); } - public ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id, + public static ClientData instance(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, + final Long id, final String firstname, final String middlename, final String lastname, final String fullname, + final String displayName, final String externalId, final LocalDate activationDate, final String imageKey) { + return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, + externalId, activationDate, imageKey, null, null); + } + + private ClientData(final String accountNo, final EnumOptionData status, final Long officeId, final String officeName, final Long id, final String firstname, final String middlename, final String lastname, final String fullname, final String displayName, - final String externalId, final LocalDate activationDate, final String imageKey, final Boolean clientPendingApprovalAllowed, - final Collection allowedOffices, final Collection groups) { + final String externalId, final LocalDate activationDate, final String imageKey, final Collection allowedOffices, + final Collection groups) { this.accountNo = accountNo; this.status = status; + if (status != null) { + active = status.getId().equals(300L); + } else { + active = null; + } this.officeId = officeId; this.officeName = officeName; this.id = id; @@ -106,8 +114,6 @@ final public class ClientData implements Comparable { this.imagePresent = null; } - this.clientPendingApprovalAllowed = clientPendingApprovalAllowed; - // associations this.groups = groups; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java index cd87eb052..aff0d51d5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientDataValidator.java @@ -37,7 +37,7 @@ public final class ClientDataValidator { this.fromApiJsonHelper = fromApiJsonHelper; } - public void validateForCreate(final String json, final boolean isPendingApprovalEnabled) { + public void validateForCreate(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -74,10 +74,6 @@ public final class ClientDataValidator { if (active.booleanValue()) { final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element); baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull(); - } else { - if (!isPendingApprovalEnabled) { - baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).failWithCode(".pending.status.not.allowed"); - } } } else { baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false); @@ -86,7 +82,7 @@ public final class ClientDataValidator { throwExceptionIfValidationWarningsExist(dataValidationErrors); } - public void validateForUpdate(final String json, final boolean isPendingApprovalEnabled) { + public void validateForUpdate(final String json) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } @@ -139,13 +135,7 @@ public final class ClientDataValidator { if (active.booleanValue()) { final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element); baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull(); - } else { - if (!isPendingApprovalEnabled) { - baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).failWithCode(".pending.status.not.allowed"); - } } - } else { - baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false); } if (!atLeastOneParameterPassedForUpdate) { @@ -179,8 +169,7 @@ public final class ClientDataValidator { private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { // - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); + throw new PlatformApiDataValidationException(dataValidationErrors); } } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java index bb4cf8f3b..07ca9ef45 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/Client.java @@ -79,9 +79,6 @@ public final class Client extends AbstractPersistable { @Column(name = "external_id", length = 100, nullable = true, unique = true) private String externalId; - @Column(name = "is_deleted", nullable = false) - private boolean deleted = false; - @Column(name = "image_key", length = 500, nullable = true) private String imageKey; @@ -92,8 +89,7 @@ public final class Client extends AbstractPersistable { @Transient private boolean accountNumberRequiresAutoGeneration = false; - public static Client createNew(final Office clientOffice, final Group clientParentGroup, final JsonCommand command, - final boolean isPendingStateAllowed) { + public static Client createNew(final Office clientOffice, final Group clientParentGroup, final JsonCommand command) { final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName); final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName); @@ -103,17 +99,16 @@ public final class Client extends AbstractPersistable { final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName); final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName); - ClientStatus status = ClientStatus.ACTIVE; - boolean active = true; - if (isPendingStateAllowed && command.hasParameter("active")) { + ClientStatus status = ClientStatus.PENDING; + boolean active = false; + if (command.hasParameter("active")) { active = command.booleanPrimitiveValueOfParameterNamed(ClientApiConstants.activeParamName); } LocalDate activationDate = null; if (active) { + status = ClientStatus.ACTIVE; activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName); - } else { - status = ClientStatus.PENDING; } return new Client(status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate, @@ -193,7 +188,26 @@ public final class Client extends AbstractPersistable { } public void changeOffice(final Office newOffice) { - this.office = newOffice; + if (isNotAMemberOfAGroup()) { + this.office = newOffice; + } else { + cannotUpdateOfficeOfClientThatBelongsInGroupException(newOffice); + } + } + + private boolean isNotAMemberOfAGroup() { + return this.groups == null || this.groups.isEmpty(); + } + + private void cannotUpdateOfficeOfClientThatBelongsInGroupException(final Office newOffice) { + final String defaultUserMessage = "Cannot update office of client that is member of a group."; + final ApiParameterError error = ApiParameterError.parameterError("error.msg.client.member.of.group.and.cannot.update.office", + defaultUserMessage, ClientApiConstants.officeIdParamName, newOffice.getId(), newOffice.getName()); + + final List dataValidationErrors = new ArrayList(); + dataValidationErrors.add(error); + + throw new PlatformApiDataValidationException(dataValidationErrors); } public void updateAccountNo(final String accountIdentifier) { @@ -253,58 +267,50 @@ public final class Client extends AbstractPersistable { final Map actualChanges = new LinkedHashMap(9); - final String statusEnumParamName = "status"; - if (command.isChangeInIntegerParameterNamed(statusEnumParamName, this.status)) { - final Integer newValue = command.integerValueOfParameterNamed(statusEnumParamName); - actualChanges.put(statusEnumParamName, ClientEnumerations.status(newValue)); + if (command.isChangeInIntegerParameterNamed(ClientApiConstants.statusParamName, this.status)) { + final Integer newValue = command.integerValueOfParameterNamed(ClientApiConstants.statusParamName); + actualChanges.put(ClientApiConstants.statusParamName, ClientEnumerations.status(newValue)); this.status = ClientStatus.fromInt(newValue).getValue(); } - final String accountNoParamName = "accountNo"; - if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) { - final String newValue = command.stringValueOfParameterNamed(accountNoParamName); - actualChanges.put(accountNoParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.accountNoParamName, this.accountNumber)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName); + actualChanges.put(ClientApiConstants.accountNoParamName, newValue); this.accountNumber = StringUtils.defaultIfEmpty(newValue, null); } - final String externalIdParamName = "externalId"; - if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) { - final String newValue = command.stringValueOfParameterNamed(externalIdParamName); - actualChanges.put(externalIdParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.externalIdParamName, this.externalId)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName); + actualChanges.put(ClientApiConstants.externalIdParamName, newValue); this.externalId = StringUtils.defaultIfEmpty(newValue, null); } - final String officeIdParamName = "officeId"; - if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) { - final Long newValue = command.longValueOfParameterNamed(officeIdParamName); - actualChanges.put(officeIdParamName, newValue); + if (command.isChangeInLongParameterNamed(ClientApiConstants.officeIdParamName, this.office.getId())) { + final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName); + actualChanges.put(ClientApiConstants.officeIdParamName, newValue); } - final String firstnameParamName = "firstname"; - if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstname)) { - final String newValue = command.stringValueOfParameterNamed(firstnameParamName); - actualChanges.put(firstnameParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.firstnameParamName, this.firstname)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.firstnameParamName); + actualChanges.put(ClientApiConstants.firstnameParamName, newValue); this.firstname = StringUtils.defaultIfEmpty(newValue, null); } - final String middlenameParamName = "middlename"; - if (command.isChangeInStringParameterNamed(middlenameParamName, this.middlename)) { - final String newValue = command.stringValueOfParameterNamed(middlenameParamName); - actualChanges.put(middlenameParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.middlenameParamName, this.middlename)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.middlenameParamName); + actualChanges.put(ClientApiConstants.middlenameParamName, newValue); this.middlename = StringUtils.defaultIfEmpty(newValue, null); } - final String lastnameParamName = "lastname"; - if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastname)) { - final String newValue = command.stringValueOfParameterNamed(lastnameParamName); - actualChanges.put(lastnameParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.lastnameParamName, this.lastname)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName); + actualChanges.put(ClientApiConstants.lastnameParamName, newValue); this.lastname = StringUtils.defaultIfEmpty(newValue, null); } - final String fullnameParamName = "fullname"; - if (command.isChangeInStringParameterNamed(fullnameParamName, this.fullname)) { - final String newValue = command.stringValueOfParameterNamed(fullnameParamName); - actualChanges.put(fullnameParamName, newValue); + if (command.isChangeInStringParameterNamed(ClientApiConstants.fullnameParamName, this.fullname)) { + final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName); + actualChanges.put(ClientApiConstants.fullnameParamName, newValue); this.fullname = newValue; } @@ -313,14 +319,13 @@ public final class Client extends AbstractPersistable { final String dateFormatAsInput = command.dateFormat(); final String localeAsInput = command.locale(); - final String joiningDateParamName = "joinedDate"; - if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) { - final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName); - actualChanges.put(joiningDateParamName, valueAsInput); - actualChanges.put("dateFormat", dateFormatAsInput); - actualChanges.put("locale", localeAsInput); + if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.activationDateParamName, getActivationLocalDate())) { + final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.activationDateParamName); + actualChanges.put(ClientApiConstants.activationDateParamName, valueAsInput); + actualChanges.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput); + actualChanges.put(ClientApiConstants.localeParamName, localeAsInput); - final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName); + final LocalDate newValue = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName); this.activationDate = newValue.toDate(); } @@ -378,27 +383,12 @@ public final class Client extends AbstractPersistable { this.displayName = nameBuilder.toString(); } - private LocalDate getJoiningLocalDate() { - LocalDate joiningLocalDate = null; + private LocalDate getActivationLocalDate() { + LocalDate activationLocalDate = null; if (this.activationDate != null) { - joiningLocalDate = LocalDate.fromDateFields(this.activationDate); + activationLocalDate = LocalDate.fromDateFields(this.activationDate); } - return joiningLocalDate; - } - - /** - * Delete is a soft delete. Updates flag on client so it wont appear - * in query/report results. - * - * Any fields with unique constraints and prepended with id of record. - */ - public void delete() { - this.deleted = true; - this.externalId = this.getId() + "_" + this.externalId; - } - - public boolean isDeleted() { - return deleted; + return activationLocalDate; } public boolean isOfficeIdentifiedBy(final Long officeId) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/ClientRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/ClientRepositoryWrapper.java index 6551370e5..5c26af704 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/ClientRepositoryWrapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/domain/ClientRepositoryWrapper.java @@ -27,7 +27,7 @@ public class ClientRepositoryWrapper { public Client findOneWithNotFoundDetection(final Long id) { final Client client = this.repository.findOne(id); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); } + if (client == null) { throw new ClientNotFoundException(id); } return client; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java index c4b69ddd2..b8a0bd3b0 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java @@ -19,9 +19,8 @@ import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; -import org.mifosplatform.portfolio.client.domain.ClientRepository; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundException; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer; import org.slf4j.Logger; @@ -37,14 +36,14 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl private final static Logger logger = LoggerFactory.getLogger(ClientIdentifierWritePlatformServiceJpaRepositoryImpl.class); private final PlatformSecurityContext context; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final ClientIdentifierRepository clientIdentifierRepository; private final CodeValueRepositoryWrapper codeValueRepository; private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; @Autowired public ClientIdentifierWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, - final ClientRepository clientRepository, final ClientIdentifierRepository clientIdentifierRepository, + final ClientRepositoryWrapper clientRepository, final ClientIdentifierRepository clientIdentifierRepository, final CodeValueRepositoryWrapper codeValueRepository, final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer) { this.context = context; @@ -67,8 +66,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl String documentTypeLabel = null; Long documentTypeId = null; try { - final Client client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand .getDocumentTypeId()); @@ -106,6 +104,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl try { CodeValue documentType = null; + final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(identifierId); if (clientIdentifierForUpdate == null) { throw new ClientIdentifierNotFoundException(identifierId); } @@ -135,10 +134,9 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl this.clientIdentifierRepository.saveAndFlush(clientIdentifierForUpdate); } - final Client client = this.clientRepository.findOne(clientId); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // - .withOfficeId(client.getOffice().getId()) // + .withOfficeId(client.officeId()) // .withClientId(clientId) // .withEntityId(identifierId) // .with(changes) // @@ -152,13 +150,19 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl @Transactional @Override public CommandProcessingResult deleteClientIdentifier(final Long clientId, final Long identifierId, final Long commandId) { + + final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); + final ClientIdentifier clientIdentifier = this.clientIdentifierRepository.findOne(identifierId); if (clientIdentifier == null) { throw new ClientIdentifierNotFoundException(identifierId); } this.clientIdentifierRepository.delete(clientIdentifier); - final Client client = this.clientRepository.findOne(clientId); - return new CommandProcessingResultBuilder().withCommandId(commandId).withOfficeId(client.getOffice().getId()) - .withClientId(clientId).withEntityId(identifierId).build(); + return new CommandProcessingResultBuilder() // + .withCommandId(commandId) // + .withOfficeId(client.officeId()) // + .withClientId(clientId) // + .withEntityId(identifierId) // + .build(); } private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId, @@ -177,5 +181,4 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { logger.error(dve.getMessage(), dve); } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index 6c183f5fd..80e0268ea 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -13,7 +13,6 @@ import java.util.List; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; -import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; @@ -42,7 +41,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; - private final ConfigurationDomainService configurationDomainService; private final OfficeReadPlatformService officeReadPlatformService; // data mappers @@ -53,9 +51,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService @Autowired public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, - final ConfigurationDomainService configurationDomainService, final OfficeReadPlatformService officeReadPlatformService) { + final OfficeReadPlatformService officeReadPlatformService) { this.context = context; - this.configurationDomainService = configurationDomainService; this.officeReadPlatformService = officeReadPlatformService; this.jdbcTemplate = new JdbcTemplate(dataSource); } @@ -67,11 +64,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final Collection offices = officeReadPlatformService.retrieveAllOfficesForDropdown(); - final boolean clientPendingApprovalAllowed = this.configurationDomainService.isClientPendingApprovalAllowedEnabled(); - final Long officeId = currentUser.getOffice().getId(); - return ClientData.template(officeId, new LocalDate(), clientPendingApprovalAllowed, offices); + return ClientData.template(officeId, new LocalDate(), offices); } @Override @@ -81,19 +76,19 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String hierarchy = currentUser.getOffice().getHierarchy(); final String hierarchySearchString = hierarchy + "%"; - String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.is_deleted=0"; + String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ?"; final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters); - + if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")"; sql += " order by c.display_name ASC, c.account_no ASC"; return this.jdbcTemplate.query(sql, clientMapper, new Object[] { hierarchySearchString }); } - + private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) { - + final String sqlSearch = searchParameters.getSqlSearch(); final Long officeId = searchParameters.getOfficeId(); final String externalId = searchParameters.getExternalId(); @@ -147,13 +142,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService String hierarchy = currentUser.getOffice().getHierarchy(); String hierarchySearchString = hierarchy + "%"; - String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.is_deleted=0 and c.id = ?"; + String sql = "select " + this.clientMapper.schema() + " where o.hierarchy like ? and c.id = ?"; ClientData clientData = this.jdbcTemplate.queryForObject(sql, this.clientMapper, new Object[] { hierarchySearchString, clientId }); String clientGroupsSql = "select " + this.clientGroupsMapper.parentGroupsSchema(); - Collection parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper, new Object[] { clientId }); + Collection parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper, + new Object[] { clientId }); return ClientData.setParentGroups(clientData, parentGroups); } catch (EmptyResultDataAccessException e) { throw new ClientNotFoundException(clientId); @@ -188,7 +184,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String hierarchySearchString = hierarchy + "%"; final String sql = "select " + this.membersOfGroupMapper.schema() - + " where o.hierarchy like ? and pgc.group_id = ? and c.is_deleted=0"; + + " where o.hierarchy like ? and pgc.group_id = ?"; return this.jdbcTemplate.query(sql, this.membersOfGroupMapper, new Object[] { hierarchySearchString, groupId }); } @@ -235,8 +231,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String imageKey = rs.getString("imageKey"); final String officeName = rs.getString("officeName"); - return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, - externalId, activationDate, imageKey, null, null, null); + return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, + externalId, activationDate, imageKey); } } @@ -283,8 +279,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService final String imageKey = rs.getString("imageKey"); final String officeName = rs.getString("officeName"); - return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, - externalId, activationDate, imageKey, null, null, null); + return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, + externalId, activationDate, imageKey); } } @@ -317,7 +313,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService builder.append("c.office_id as officeId, o.name as officeName "); builder.append("from m_client c "); builder.append("join m_office o on o.id = c.office_id "); - builder.append("where c.is_deleted=0"); this.schema = builder.toString(); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 39f68331d..79f5e83fd 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -16,7 +16,6 @@ import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; @@ -60,14 +59,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP private final GroupRepository groupRepository; private final ClientDataValidator fromApiJsonDeserializer; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; - private final ConfigurationDomainService configurationDomainService; @Autowired public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository, - final ClientDataValidator fromApiJsonDeserializer, - final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository, - final ConfigurationDomainService configurationDomainService) { + final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, + final GroupRepository groupRepository) { this.context = context; this.clientRepository = clientRepository; this.officeRepository = officeRepository; @@ -75,7 +72,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.groupRepository = groupRepository; - this.configurationDomainService = configurationDomainService; } @Transactional @@ -128,8 +124,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP try { context.authenticatedUser(); - final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled(); - this.fromApiJsonDeserializer.validateForCreate(command.json(), isPendingApprovalEnabled); + this.fromApiJsonDeserializer.validateForCreate(command.json()); final Long officeId = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName); @@ -144,7 +139,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP if (clientParentGroup == null) { throw new GroupNotFoundException(groupId); } } - final Client newClient = Client.createNew(clientOffice, clientParentGroup, command, isPendingApprovalEnabled); + final Client newClient = Client.createNew(clientOffice, clientParentGroup, command); this.clientRepository.save(newClient); @@ -175,15 +170,14 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP try { context.authenticatedUser(); - final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled(); - this.fromApiJsonDeserializer.validateForUpdate(command.json(), isPendingApprovalEnabled); + this.fromApiJsonDeserializer.validateForUpdate(command.json()); final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId); final Map changes = clientForUpdate.update(command); - if (changes.containsKey("officeId")) { - final Long officeId = (Long) changes.get("officeId"); + if (changes.containsKey(ClientApiConstants.officeIdParamName)) { + final Long officeId = (Long) changes.get(ClientApiConstants.officeIdParamName); final Office newOffice = this.officeRepository.findOne(officeId); if (newOffice == null) { throw new OfficeNotFoundException(officeId); } @@ -203,7 +197,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); - return new CommandProcessingResult(Long.valueOf(-1)); + return CommandProcessingResult.empty(); } } @@ -231,7 +225,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .build(); } catch (DataIntegrityViolationException dve) { handleDataIntegrityIssues(command, dve); - return new CommandProcessingResult(Long.valueOf(-1)); + return CommandProcessingResult.empty(); } } @@ -280,7 +274,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP } private String setupForClientImageUpdate(final Long clientId, final Client client) { - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + if (client == null) { throw new ClientNotFoundException(clientId); } final String imageUploadLocation = FileUtils.generateClientImageParentDirectory(clientId); // delete previous image from the file system diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java index 0ced66ebe..27913e900 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java @@ -23,12 +23,14 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang.StringUtils; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; @@ -170,6 +172,33 @@ public class CentersApiResource { return this.toApiJsonSerializer.serialize(result); } + @POST + @Path("{centerId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String activate(@PathParam("centerId") final Long centerId, @QueryParam("command") final String commandParam, + final String apiRequestBodyAsJson) { + + final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson); + + CommandProcessingResult result = null; + if (is(commandParam, "activate")) { + final CommandWrapper commandRequest = builder.activateCenter(centerId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } + + if (result == null) { + // + throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate" }); + } + + return this.toApiJsonSerializer.serialize(result); + } + + private boolean is(final String commandParam, final String commandValue) { + return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); + } + @GET @Path("{centerId}/loans") @Consumes({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java index c0d6d73fa..a296a9044 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java @@ -31,6 +31,7 @@ public class GroupingTypesApiConstants { public static final String clientMembersParamName = "clientMembers"; // response parameters + public static final String statusParamName = "status"; public static final String hierarchyParamName = "hierarchy"; public static final String officeNameParamName = "officeName"; public static final String staffNameParamName = "staffName"; @@ -57,9 +58,12 @@ public class GroupingTypesApiConstants { public static final Set CENTER_GROUP_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, nameParamName, externalIdParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName, - officeOptionsParamName, staffOptionsParamName,clientOptionsParamName)); + officeOptionsParamName, staffOptionsParamName, clientOptionsParamName)); public static final Set GROUP_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, nameParamName, externalIdParamName, officeIdParamName, officeNameParamName, "parentId", "parentName", staffIdParamName, staffNameParamName, - hierarchyParamName, officeOptionsParamName, staffOptionsParamName,clientOptionsParamName)); + hierarchyParamName, officeOptionsParamName, staffOptionsParamName, clientOptionsParamName)); + + public static final Set ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, + dateFormatParamName, activationDateParamName)); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java index 17fcf9d69..cee718220 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java @@ -23,12 +23,14 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; +import org.apache.commons.lang.StringUtils; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.infrastructure.core.exception.UnrecognizedQueryParamException; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; @@ -206,6 +208,33 @@ public class GroupsApiResource { return this.toApiJsonSerializer.serialize(result); } + @POST + @Path("{groupId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String activate(@PathParam("groupId") final Long groupId, @QueryParam("command") final String commandParam, + final String apiRequestBodyAsJson) { + + final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson); + + CommandProcessingResult result = null; + if (is(commandParam, "activate")) { + final CommandWrapper commandRequest = builder.activateGroup(groupId).build(); + result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); + } + + if (result == null) { + // + throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate" }); + } + + return this.toApiJsonSerializer.serialize(result); + } + + private boolean is(final String commandParam, final String commandValue) { + return StringUtils.isNotBlank(commandParam) && commandParam.trim().equalsIgnoreCase(commandValue); + } + @GET @Path("{groupId}/loans") @Consumes({ MediaType.APPLICATION_JSON }) diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java index 29318afcf..5d50c7e9c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java @@ -7,6 +7,8 @@ package org.mifosplatform.portfolio.group.data; import java.util.Collection; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.organisation.office.data.OfficeData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.client.data.ClientData; @@ -20,6 +22,12 @@ public class GroupGeneralData { private final Long id; private final String name; private final String externalId; + + private final EnumOptionData status; + @SuppressWarnings("unused") + private final Boolean active; + private final LocalDate activationDate; + private final Long officeId; private final String officeName; private final Long centerId; @@ -40,8 +48,8 @@ public class GroupGeneralData { public static GroupGeneralData lookup(final Long groupId, final String groupName) { final Collection clientMembers = null; - return new GroupGeneralData(groupId, groupName, null, null, null, null, null, null, null, null, clientMembers, null, null, null, - null); + return new GroupGeneralData(groupId, groupName, null, null, null, null, null, null, null, null, null, null, clientMembers, null, + null, null, null); } public static GroupGeneralData template(final Long officeId, final Long centerId, final String centerName, final Long staffId, @@ -50,34 +58,35 @@ public class GroupGeneralData { final Collection clientMembers = null; - return new GroupGeneralData(null, null, null, officeId, null, centerId, centerName, staffId, staffName, null, clientMembers, - centerOptions, officeOptions, staffOptions, clientOptions); + return new GroupGeneralData(null, null, null, null, null, officeId, null, centerId, centerName, staffId, staffName, null, + clientMembers, centerOptions, officeOptions, staffOptions, clientOptions); } public static GroupGeneralData withTemplate(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping) { - return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, - grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, grouping.clientMembers, - templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, - templatedGrouping.clientOptions); + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate, + grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, + grouping.hierarchy, grouping.clientMembers, templatedGrouping.centerOptions, templatedGrouping.officeOptions, + templatedGrouping.staffOptions, templatedGrouping.clientOptions); } public static GroupGeneralData withTemplateAndAssociations(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping, final Collection membersOfGroup) { - return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, - grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, - templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, - templatedGrouping.clientOptions); + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate, + grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, + grouping.hierarchy, membersOfGroup, templatedGrouping.centerOptions, templatedGrouping.officeOptions, + templatedGrouping.staffOptions, templatedGrouping.clientOptions); } public static GroupGeneralData withAssocations(final GroupGeneralData grouping, final Collection membersOfGroup) { - return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, - grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, - grouping.centerOptions, grouping.officeOptions, grouping.staffOptions, grouping.clientOptions); + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate, + grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, + grouping.hierarchy, membersOfGroup, grouping.centerOptions, grouping.officeOptions, grouping.staffOptions, + grouping.clientOptions); } - public static GroupGeneralData instance(final Long id, final String name, final String externalId, final Long officeId, - final String officeName, final Long centerId, final String centerName, final Long staffId, final String staffName, - final String hierarchy) { + public static GroupGeneralData instance(final Long id, final String name, final String externalId, final EnumOptionData status, + final LocalDate activationDate, final Long officeId, final String officeName, final Long centerId, final String centerName, + final Long staffId, final String staffName, final String hierarchy) { final Collection clientMembers = null; final Collection centerOptions = null; @@ -85,17 +94,26 @@ public class GroupGeneralData { final Collection staffOptions = null; final Collection clientOptions = null; - return new GroupGeneralData(id, name, externalId, officeId, officeName, centerId, centerName, staffId, staffName, hierarchy, - clientMembers, centerOptions, officeOptions, staffOptions, clientOptions); + return new GroupGeneralData(id, name, externalId, status, activationDate, officeId, officeName, centerId, centerName, staffId, + staffName, hierarchy, clientMembers, centerOptions, officeOptions, staffOptions, clientOptions); } - private GroupGeneralData(final Long id, final String name, final String externalId, final Long officeId, final String officeName, - final Long centerId, final String centerName, final Long staffId, final String staffName, final String hierarchy, - final Collection clientMembers, final Collection centerOptions, - final Collection officeOptions, final Collection staffOptions, final Collection clientOptions) { + private GroupGeneralData(final Long id, final String name, final String externalId, final EnumOptionData status, + final LocalDate activationDate, final Long officeId, final String officeName, final Long centerId, final String centerName, + final Long staffId, final String staffName, final String hierarchy, final Collection clientMembers, + final Collection centerOptions, final Collection officeOptions, + final Collection staffOptions, final Collection clientOptions) { this.id = id; this.name = name; this.externalId = externalId; + this.status = status; + if (status != null) { + this.active = status.getId().equals(300l); + } else { + this.active = null; + } + this.activationDate = activationDate; + this.officeId = officeId; this.officeName = officeName; this.centerId = centerId; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java index b1c84d982..736a70d0b 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java @@ -5,10 +5,15 @@ */ package org.mifosplatform.portfolio.group.domain; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; import javax.persistence.Column; @@ -25,11 +30,19 @@ import javax.persistence.TemporalType; import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormatter; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.ApiParameterError; +import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; +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.domain.Client; +import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants; import org.springframework.data.jpa.domain.AbstractPersistable; +import com.google.common.collect.Sets; + @Entity @Table(name = "m_group") public final class Group extends AbstractPersistable { @@ -134,6 +147,46 @@ public final class Group extends AbstractPersistable { } } + public void activate(final DateTimeFormatter formatter, final LocalDate activationLocalDate) { + if (isActive()) { + final String defaultUserMessage = "Cannot activate group. Group is already active."; + final ApiParameterError error = ApiParameterError.parameterError("error.msg.group.already.active", defaultUserMessage, + "activationDate", activationLocalDate.toString(formatter)); + + final List dataValidationErrors = new ArrayList(); + dataValidationErrors.add(error); + + 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 dataValidationErrors = new ArrayList(); + dataValidationErrors.add(error); + + throw new PlatformApiDataValidationException(dataValidationErrors); + } + + this.activationDate = activationLocalDate.toDate(); + this.status = GroupingTypeStatus.ACTIVE.getValue(); + } + + public boolean isNotActive() { + return !isActive(); + } + + public boolean isActive() { + return GroupingTypeStatus.fromInt(this.status).isActive(); + } + + private boolean isDateInTheFuture(final LocalDate localDate) { + return localDate.isAfter(DateUtils.getLocalDateOfTenant()); + } + public boolean isNotPending() { return !isPending(); } @@ -142,72 +195,59 @@ public final class Group extends AbstractPersistable { return GroupingTypeStatus.fromInt(this.status).isPending(); } - private void addChild(final Group group) { - this.groupMembers.add(group); + public Map update(final JsonCommand command) { + final Map actualChanges = new LinkedHashMap(9); + + if (command.isChangeInIntegerParameterNamed(GroupingTypesApiConstants.statusParamName, this.status)) { + final Integer newValue = command.integerValueOfParameterNamed(GroupingTypesApiConstants.statusParamName); + actualChanges.put(GroupingTypesApiConstants.statusParamName, GroupingTypeEnumerations.status(newValue)); + this.status = GroupingTypeStatus.fromInt(newValue).getValue(); + } + + if (command.isChangeInStringParameterNamed(GroupingTypesApiConstants.externalIdParamName, this.externalId)) { + final String newValue = command.stringValueOfParameterNamed(GroupingTypesApiConstants.externalIdParamName); + actualChanges.put(GroupingTypesApiConstants.externalIdParamName, newValue); + this.externalId = StringUtils.defaultIfEmpty(newValue, null); + } + + if (command.isChangeInLongParameterNamed(GroupingTypesApiConstants.officeIdParamName, this.office.getId())) { + final Long newValue = command.longValueOfParameterNamed(GroupingTypesApiConstants.officeIdParamName); + actualChanges.put(GroupingTypesApiConstants.officeIdParamName, newValue); + } + + if (command.isChangeInLongParameterNamed(GroupingTypesApiConstants.staffIdParamName, staffId())) { + final Long newValue = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); + actualChanges.put(GroupingTypesApiConstants.staffIdParamName, newValue); + } + + if (command.isChangeInStringParameterNamed(GroupingTypesApiConstants.nameParamName, this.name)) { + final String newValue = command.stringValueOfParameterNamed(GroupingTypesApiConstants.nameParamName); + actualChanges.put(GroupingTypesApiConstants.nameParamName, newValue); + this.name = StringUtils.defaultIfEmpty(newValue, null); + } + + final String dateFormatAsInput = command.dateFormat(); + final String localeAsInput = command.locale(); + + if (command.isChangeInLocalDateParameterNamed(GroupingTypesApiConstants.activationDateParamName, getActivationLocalDate())) { + final String valueAsInput = command.stringValueOfParameterNamed(GroupingTypesApiConstants.activationDateParamName); + actualChanges.put(GroupingTypesApiConstants.activationDateParamName, valueAsInput); + actualChanges.put(GroupingTypesApiConstants.dateFormatParamName, dateFormatAsInput); + actualChanges.put(GroupingTypesApiConstants.localeParamName, localeAsInput); + + final LocalDate newValue = command.localDateValueOfParameterNamed(GroupingTypesApiConstants.activationDateParamName); + this.activationDate = newValue.toDate(); + } + + return actualChanges; } - public Long getOfficeId() { - return this.office.getId(); - } - - public Staff getStaff() { - return this.staff; - } - - public void setStaff(final Staff staff) { - this.staff = staff; - } - - public Long getStaffId() { - return this.staff.getId(); - } - - public GroupLevel getGroupLevel() { - return this.groupLevel; - } - - public String getExternalId() { - return this.externalId; - } - - public String getName() { - return this.name; - } - - public Set getClientMembers() { - return this.clientMembers; - } - - public Group getParent() { - return this.parent; - } - - public void setParent(final Group parent) { - this.parent = parent; - } - - public void setClientMembers(final Set clientMembers) { - this.clientMembers = clientMembers; - } - - public void setName(final String name) { - this.name = name; - } - - public void setExternalId(final String externalId) { - this.externalId = externalId; - } - - public void setLevelId(final GroupLevel groupLevel) { - this.groupLevel = groupLevel; - } - - public void assigStaff(final Staff newStaff) { - this.staff = newStaff; - } - - public void unassigStaff() { - this.staff = null; + private LocalDate getActivationLocalDate() { + LocalDate activationLocalDate = null; + if (this.activationDate != null) { + activationLocalDate = new LocalDate(this.activationDate); + } + return activationLocalDate; } public void addClientMember(final Client member) { @@ -219,7 +259,6 @@ public final class Group extends AbstractPersistable { } public void generateHierarchy() { - if (this.parent != null) { this.hierarchy = this.parent.hierarchyOf(getId()); } else { @@ -238,4 +277,68 @@ public final class Group extends AbstractPersistable { public Long officeId() { return this.office.getId(); } + + private Long staffId() { + Long staffId = null; + if (this.staff != null) { + staffId = this.staff.getId(); + } + return staffId; + } + + private void addChild(final Group group) { + this.groupMembers.add(group); + } + + public void updateStaff(final Staff staff) { + this.staff = staff; + } + + public void unassignStaff() { + this.staff = null; + } + + public List updateClientMembersIfDifferent(final Set clientMembersSet) { + List differences = new ArrayList(); + if (!clientMembersSet.equals(this.clientMembers)) { + Set diffClients = Sets.symmetricDifference(clientMembersSet, this.clientMembers); + String[] diffClientsIds = getClientIds(diffClients); + if (diffClientsIds != null) { + differences = Arrays.asList(diffClientsIds); + } + this.clientMembers = clientMembersSet; + } + + return differences; + } + + private String[] getClientIds(final Set clients) { + String[] clientIds = new String[clients.size()]; + Iterator it = clients.iterator(); + for (int i = 0; it.hasNext(); i++) { + clientIds[i] = it.next().getId().toString(); + } + return clientIds; + } + + // TODO - kw - look into removing usage of these getters/setters + public GroupLevel getGroupLevel() { + return this.groupLevel; + } + + public Staff getStaff() { + return this.staff; + } + + public void setStaff(final Staff staff) { + this.staff = staff; + } + + public Group getParent() { + return this.parent; + } + + public void setParent(final Group parent) { + this.parent = parent; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupRepositoryWrapper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupRepositoryWrapper.java new file mode 100644 index 000000000..e7c48f926 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/GroupRepositoryWrapper.java @@ -0,0 +1,45 @@ +/** + * 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.portfolio.group.domain; + +import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + *

+ * Wrapper for {@link GroupRepository} that adds NULL checking and Error + * handling capabilities + *

+ */ +@Service +public class GroupRepositoryWrapper { + + private final GroupRepository repository; + + @Autowired + public GroupRepositoryWrapper(final GroupRepository repository) { + this.repository = repository; + } + + public Group findOneWithNotFoundDetection(final Long id) { + final Group entity = this.repository.findOne(id); + if (entity == null) { throw new GroupNotFoundException(id); } + return entity; + } + + public void save(final Group entity) { + this.repository.save(entity); + } + + public void saveAndFlush(final Group entity) { + this.repository.saveAndFlush(entity); + } + + public void delete(final Group entity) { + this.repository.delete(entity); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateCenterCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateCenterCommandHandler.java new file mode 100644 index 000000000..d47a48213 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateCenterCommandHandler.java @@ -0,0 +1,32 @@ +/** + * 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.portfolio.group.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.group.service.GroupingTypesWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ActivateCenterCommandHandler implements NewCommandSourceHandler { + + private final GroupingTypesWritePlatformService writePlatformService; + + @Autowired + public ActivateCenterCommandHandler(final GroupingTypesWritePlatformService clientWritePlatformService) { + this.writePlatformService = clientWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.activateGroupOrCenter(command.entityId(), command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateGroupCommandHandler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateGroupCommandHandler.java new file mode 100644 index 000000000..13e5d0579 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/handler/ActivateGroupCommandHandler.java @@ -0,0 +1,32 @@ +/** + * 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.portfolio.group.handler; + +import org.mifosplatform.commands.handler.NewCommandSourceHandler; +import org.mifosplatform.infrastructure.core.api.JsonCommand; +import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; +import org.mifosplatform.portfolio.group.service.GroupingTypesWritePlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ActivateGroupCommandHandler implements NewCommandSourceHandler { + + private final GroupingTypesWritePlatformService writePlatformService; + + @Autowired + public ActivateGroupCommandHandler(final GroupingTypesWritePlatformService clientWritePlatformService) { + this.writePlatformService = clientWritePlatformService; + } + + @Transactional + @Override + public CommandProcessingResult processCommand(final JsonCommand command) { + + return this.writePlatformService.activateGroupOrCenter(command.entityId(), command); + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/serialization/GroupingTypesDataValidator.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/serialization/GroupingTypesDataValidator.java index 3b656e18d..7ecc9b0f3 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/serialization/GroupingTypesDataValidator.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/serialization/GroupingTypesDataValidator.java @@ -20,10 +20,8 @@ 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.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.portfolio.client.api.ClientApiConstants; -import org.mifosplatform.portfolio.client.command.ClientCommand; import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -31,10 +29,6 @@ import org.springframework.stereotype.Component; import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; -/** - * Implementation of {@link FromApiJsonDeserializer} for {@link ClientCommand} - * 's. - */ @Component public final class GroupingTypesDataValidator { @@ -48,8 +42,7 @@ public final class GroupingTypesDataValidator { private void throwExceptionIfValidationWarningsExist(final List dataValidationErrors) { if (!dataValidationErrors.isEmpty()) { // - throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", - dataValidationErrors); + throw new PlatformApiDataValidationException(dataValidationErrors); } } @@ -311,46 +304,24 @@ public final class GroupingTypesDataValidator { throwExceptionIfValidationWarningsExist(dataValidationErrors); } - @Deprecated - public void validateForUpdate(final String json) { + public void validateForActivation(final JsonCommand command, final String resourceName) { + final String json = command.json(); if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } final Type typeOfMap = new TypeToken>() {}.getType(); - - /* - * Office updated is not supported - */ - final Set supportedParametersForupdate = new HashSet(Arrays.asList("id", "externalId", "name", "staffId", - "parentId", "clientMembers", "childGroups")); - - this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParametersForupdate); - final JsonElement element = this.fromApiJsonHelper.parse(json); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, GroupingTypesApiConstants.ACTIVATION_REQUEST_DATA_PARAMETERS); final List dataValidationErrors = new ArrayList(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource(resourceName); - final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group"); + final JsonElement element = command.parsedJson(); - final String externalIdParameterName = "externalId"; - if (this.fromApiJsonHelper.parameterExists(externalIdParameterName, element)) { - final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParameterName, element); - baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100); - } + final LocalDate activationDate = fromApiJsonHelper + .extractLocalDateNamed(GroupingTypesApiConstants.activationDateParamName, element); + baseDataValidator.reset().parameter(GroupingTypesApiConstants.activationDateParamName).value(activationDate).notNull(); - final String parentIdParameterName = "parentId"; - if (this.fromApiJsonHelper.parameterExists(parentIdParameterName, element)) { - final Long parentId = this.fromApiJsonHelper.extractLongNamed(parentIdParameterName, element); - baseDataValidator.reset().parameter(parentIdParameterName).value(parentId).ignoreIfNull().integerGreaterThanZero(); - } - - final String staffIdParameterName = "staffId"; - if (this.fromApiJsonHelper.parameterExists(staffIdParameterName, element)) { - final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element); - baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).ignoreIfNull().integerGreaterThanZero(); - } - - if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); } + throwExceptionIfValidationWarningsExist(dataValidationErrors); } public void validateForUnassignStaff(final String json) { @@ -371,7 +342,6 @@ public final class GroupingTypesDataValidator { final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element); baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero(); - if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", - "Validation errors exist.", dataValidationErrors); } + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/AllGroupTypesDataMapper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/AllGroupTypesDataMapper.java index 039fa243d..2f4ae9da4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/AllGroupTypesDataMapper.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/AllGroupTypesDataMapper.java @@ -3,7 +3,10 @@ package org.mifosplatform.portfolio.group.service; import java.sql.ResultSet; import java.sql.SQLException; +import org.joda.time.LocalDate; +import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; +import org.mifosplatform.portfolio.client.domain.ClientEnumerations; import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.springframework.jdbc.core.RowMapper; @@ -20,6 +23,7 @@ public final class AllGroupTypesDataMapper implements RowMapper { @@ -167,13 +164,19 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService final Long id = rs.getLong("id"); final String name = rs.getString("name"); final String externalId = rs.getString("externalId"); + + final Integer statusEnum = JdbcSupport.getInteger(rs, "statusEnum"); + final EnumOptionData status = ClientEnumerations.status(statusEnum); + final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate"); + final Long officeId = rs.getLong("officeId"); final String officeName = rs.getString("officeName"); final Long staffId = JdbcSupport.getLong(rs, "staffId"); final String staffName = rs.getString("staffName"); final String hierarchy = rs.getString("hierarchy"); - return GroupGeneralData.instance(id, name, externalId, officeId, officeName, null, null, staffId, staffName, hierarchy); + return GroupGeneralData.instance(id, name, externalId, status, activationDate, officeId, officeName, null, null, staffId, + staffName, hierarchy); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformService.java index cddaeb14b..dab557b0d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformService.java @@ -16,6 +16,8 @@ public interface GroupingTypesWritePlatformService { CommandProcessingResult createGroup(Long centerId, JsonCommand command); + CommandProcessingResult activateGroupOrCenter(Long entityId, JsonCommand command); + CommandProcessingResult updateGroup(Long groupId, JsonCommand command); CommandProcessingResult deleteGroup(Long groupId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index a990ca337..6abde8f22 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -6,14 +6,15 @@ package org.mifosplatform.portfolio.group.service; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; -import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; @@ -24,20 +25,17 @@ import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.exception.InvalidOfficeException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.staff.domain.Staff; -import org.mifosplatform.organisation.staff.domain.StaffRepository; -import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; +import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupLevel; import org.mifosplatform.portfolio.group.domain.GroupLevelRepository; -import org.mifosplatform.portfolio.group.domain.GroupRepository; +import org.mifosplatform.portfolio.group.domain.GroupRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.GroupTypes; import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException; import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException; -import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException; import org.mifosplatform.portfolio.group.serialization.GroupingTypesDataValidator; import org.mifosplatform.portfolio.note.domain.Note; @@ -50,26 +48,24 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; -import com.google.common.collect.Sets; - @Service public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements GroupingTypesWritePlatformService { private final static Logger logger = LoggerFactory.getLogger(GroupingTypesWritePlatformServiceJpaRepositoryImpl.class); private final PlatformSecurityContext context; - private final GroupRepository groupRepository; - private final ClientRepository clientRepository; + private final GroupRepositoryWrapper groupRepository; + private final ClientRepositoryWrapper clientRepository; private final OfficeRepository officeRepository; - private final StaffRepository staffRepository; + private final StaffRepositoryWrapper staffRepository; private final NoteRepository noteRepository; private final GroupLevelRepository groupLevelRepository; private final GroupingTypesDataValidator fromApiJsonDeserializer; @Autowired - public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepository groupRepository, - final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository, - final NoteRepository noteRepository, + public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, + final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepository, + final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository, final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer) { this.context = context; this.groupRepository = groupRepository; @@ -92,9 +88,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group if (centerId == null) { officeId = command.longValueOfParameterNamed(GroupingTypesApiConstants.officeIdParamName); } else { - parentGroup = this.groupRepository.findOne(centerId); - if (parentGroup == null) { throw new GroupNotFoundException(centerId); } - officeId = parentGroup.getOfficeId(); + parentGroup = this.groupRepository.findOneWithNotFoundDetection(centerId); + officeId = parentGroup.officeId(); } final Office groupOffice = this.officeRepository.findOne(officeId); @@ -103,8 +98,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group Staff staff = null; final Long staffId = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); if (staffId != null) { - staff = this.staffRepository.findByOffice(staffId, officeId); - if (staff == null) { throw new StaffNotFoundException(staffId); } + staff = this.staffRepository.findByOfficeWithNotFoundDetection(staffId, officeId); } final Set clientMembers = assembleSetOfClients(officeId, command); @@ -160,6 +154,35 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group return createGroupingType(command, GroupTypes.GROUP, centerId); } + @Transactional + @Override + public CommandProcessingResult activateGroupOrCenter(final Long groupId, final JsonCommand command) { + + try { + this.fromApiJsonDeserializer.validateForActivation(command, GroupingTypesApiConstants.GROUP_RESOURCE_NAME); + + final Group group = this.groupRepository.findOneWithNotFoundDetection(groupId); + + final Locale locale = command.extractLocale(); + final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); + final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate"); + + group.activate(fmt, activationDate); + + this.groupRepository.saveAndFlush(group); + + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .withOfficeId(group.officeId()) // + .withGroupId(groupId) // + .withEntityId(groupId) // + .build(); + } catch (DataIntegrityViolationException dve) { + handleGroupDataIntegrityIssues(command, dve, GroupTypes.GROUP); + return CommandProcessingResult.empty(); + } + } + @Transactional @Override public CommandProcessingResult updateCenter(final Long centerId, final JsonCommand command) { @@ -181,41 +204,19 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group private CommandProcessingResult updateGroupingType(final Long groupId, final JsonCommand command, final GroupTypes groupingType) { try { - final Map actualChanges = new LinkedHashMap(9); + final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(groupId); + final Long officeId = groupForUpdate.officeId(); - final Group groupForUpdate = this.groupRepository.findOne(groupId); - if (groupForUpdate == null) { throw new GroupNotFoundException(groupId); } + final Map actualChanges = groupForUpdate.update(command); - final Long officeId = groupForUpdate.getOfficeId(); - - if (command.isChangeInStringParameterNamed(GroupingTypesApiConstants.nameParamName, groupForUpdate.getName())) { - final String newValue = command.stringValueOfParameterNamed(GroupingTypesApiConstants.nameParamName); - actualChanges.put(GroupingTypesApiConstants.nameParamName, newValue); - groupForUpdate.setName(StringUtils.defaultIfEmpty(newValue, null)); - } - - if (command.isChangeInStringParameterNamed(GroupingTypesApiConstants.externalIdParamName, groupForUpdate.getExternalId())) { - final String newValue = command.stringValueOfParameterNamed(GroupingTypesApiConstants.externalIdParamName); - actualChanges.put(GroupingTypesApiConstants.externalIdParamName, newValue); - groupForUpdate.setExternalId(StringUtils.defaultIfEmpty(newValue, null)); - } - - final Staff presentStaff = groupForUpdate.getStaff(); - Long presentStaffId = null; - if (presentStaff != null) { - presentStaffId = presentStaff.getId(); - } - - if (command.isChangeInLongParameterNamed(GroupingTypesApiConstants.staffIdParamName, presentStaffId)) { + if (actualChanges.containsKey(GroupingTypesApiConstants.staffIdParamName)) { final Long newValue = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); - actualChanges.put(GroupingTypesApiConstants.staffIdParamName, newValue); Staff newStaff = null; if (newValue != null) { - newStaff = this.staffRepository.findByOffice(newValue, officeId); - if (newStaff == null) { throw new StaffNotFoundException(newValue); } + newStaff = this.staffRepository.findByOfficeWithNotFoundDetection(newValue, officeId); } - groupForUpdate.setStaff(newStaff); + groupForUpdate.updateStaff(newStaff); } GroupLevel groupLevel = this.groupLevelRepository.findOne(groupForUpdate.getGroupLevel().getId()); @@ -240,8 +241,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group actualChanges.put(GroupingTypesApiConstants.centerIdParamName, newValue); Group newParentGroup = null; if (newValue != null) { - newParentGroup = this.groupRepository.findOne(newValue); - if (newParentGroup == null) { throw new StaffNotFoundException(newValue); } + newParentGroup = this.groupRepository.findOneWithNotFoundDetection(newValue); if (!newParentGroup.isOfficeIdentifiedBy(officeId)) { final String errorMessage = "Group and parent group must have the same office"; @@ -270,19 +270,16 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group } final Set clientMembers = assembleSetOfClients(officeId, command); - - if (!clientMembers.equals(groupForUpdate.getClientMembers())) { - Set diffClients = Sets.symmetricDifference(clientMembers, groupForUpdate.getClientMembers()); - final String[] diffClientsIds = getClientIds(diffClients); - actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, diffClientsIds); - groupForUpdate.setClientMembers(clientMembers); + List changes = groupForUpdate.updateClientMembersIfDifferent(clientMembers); + if (!changes.isEmpty()) { + actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, changes); } this.groupRepository.saveAndFlush(groupForUpdate); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // - .withOfficeId(groupForUpdate.getId()) // + .withOfficeId(groupForUpdate.officeId()) // .withGroupId(groupForUpdate.getId()) // .withEntityId(groupForUpdate.getId()) // .with(actualChanges) // @@ -304,8 +301,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group this.fromApiJsonDeserializer.validateForUnassignStaff(command.json()); - final Group groupForUpdate = this.groupRepository.findOne(grouptId); - if (groupForUpdate == null) { throw new GroupNotFoundException(grouptId); } + final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(grouptId); final Staff presentStaff = groupForUpdate.getStaff(); Long presentStaffId = null; @@ -313,7 +309,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group presentStaffId = presentStaff.getId(); final String staffIdParamName = "staffId"; if (!command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) { - groupForUpdate.unassigStaff(); + groupForUpdate.unassignStaff(); } this.groupRepository.saveAndFlush(groupForUpdate); @@ -322,7 +318,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withOfficeId(groupForUpdate.getId()) // - .withGroupId(groupForUpdate.getOfficeId()) // + .withGroupId(groupForUpdate.officeId()) // .withEntityId(groupForUpdate.getId()) // .with(actualChanges) // .build(); @@ -333,19 +329,18 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group @Override public CommandProcessingResult deleteGroup(final Long groupId) { - final Group groupForDelete = this.groupRepository.findOne(groupId); - if (groupForDelete == null) { throw new GroupNotFoundException(groupId); } + final Group groupForDelete = this.groupRepository.findOneWithNotFoundDetection(groupId); if (groupForDelete.isNotPending()) { throw new GroupMustBePendingToBeDeletedException(groupId); } final List relatedNotes = this.noteRepository.findByGroupId(groupId); this.noteRepository.deleteInBatch(relatedNotes); - this.groupRepository.delete(groupId); + this.groupRepository.delete(groupForDelete); return new CommandProcessingResultBuilder() // .withOfficeId(groupForDelete.getId()) // - .withGroupId(groupForDelete.getOfficeId()) // + .withGroupId(groupForDelete.officeId()) // .withEntityId(groupForDelete.getId()) // .build(); } @@ -358,8 +353,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group if (!ObjectUtils.isEmpty(clientMembersArray)) { for (final String clientId : clientMembersArray) { final Long id = Long.valueOf(clientId); - final Client client = this.clientRepository.findOne(id); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); } + final Client client = this.clientRepository.findOneWithNotFoundDetection(id); if (!client.isOfficeIdentifiedBy(officeId)) { final String errorMessage = "Group and Client must have the same office."; throw new InvalidOfficeException("client", "attach.to.group", errorMessage); @@ -379,8 +373,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group if (!ObjectUtils.isEmpty(childGroupsArray)) { for (final String groupId : childGroupsArray) { final Long id = Long.valueOf(groupId); - final Group group = this.groupRepository.findOne(id); - if (group == null) { throw new GroupNotFoundException(id); } + final Group group = this.groupRepository.findOneWithNotFoundDetection(id); + if (!group.isOfficeIdentifiedBy(officeId)) { final String errorMessage = "Group and child groups must have the same office."; throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage); @@ -392,16 +386,6 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group return childGroups; } - private String[] getClientIds(final Set clients) { - - String[] clientIds = new String[clients.size()]; - Iterator it = clients.iterator(); - for (int i = 0; it.hasNext(); i++) { - clientIds[i] = it.next().getId().toString(); - } - return clientIds; - } - /* * Guaranteed to throw an exception no matter what the data integrity issue * is. diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 81ca31bde..f07c46344 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -32,8 +32,7 @@ import org.mifosplatform.portfolio.calendar.service.CalendarHelper; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.fund.domain.Fund; @@ -82,7 +81,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa private final NoteRepository noteRepository; private final LoanScheduleCalculationPlatformService calculationPlatformService; private final LoanAssembler loanAssembler; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final LoanProductRepository loanProductRepository; private final LoanChargeAssembler loanChargeAssembler; private final CollateralAssembler loanCollateralAssembler; @@ -99,12 +98,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer, final AprCalculator aprCalculator, final LoanAssembler loanAssembler, final LoanChargeAssembler loanChargeAssembler, final CollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, final NoteRepository noteRepository, - final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepository clientRepository, + final LoanScheduleCalculationPlatformService calculationPlatformService, final ClientRepositoryWrapper clientRepository, final LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final LoanSummaryWrapper loanSummaryWrapper, final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) { - this.context = context; + this.context = context; this.fromJsonHelper = fromJsonHelper; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; this.fromApiJsonDeserializer = fromApiJsonDeserializer; @@ -136,19 +135,19 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa AppUser currentUser = context.authenticatedUser(); final Long productId = fromJsonHelper.extractLongNamed("productId", command.parsedJson()); - + final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } this.fromApiJsonDeserializer.validateForCreate(command.json(), loanProduct); - //validate dates against calendar recurring dates - //get calendar + // validate dates against calendar recurring dates + // get calendar final Long calendarId = command.longValueOfParameterNamed("calendarId"); Calendar calendar = null; - if(calendarId != null && calendarId != 0){ + if (calendarId != null && calendarId != 0) { calendar = this.calendarRepository.findOne(calendarId); - if(calendar == null) { throw new CalendarNotFoundException(calendarId); } + if (calendar == null) { throw new CalendarNotFoundException(calendarId); } validateCalendarDates(command, calendar); } @@ -169,9 +168,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.noteRepository.save(note); } - //Save calendar instance - if(calendar != null){ - CalendarInstance calendarInstance = new CalendarInstance(calendar, newLoanApplication.getId(), CalendarEntityType.LOANS.getValue()); + // Save calendar instance + if (calendar != null) { + CalendarInstance calendarInstance = new CalendarInstance(calendar, newLoanApplication.getId(), + CalendarEntityType.LOANS.getValue()); this.calendarInstanceRepository.save(calendarInstance); } @@ -196,12 +196,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final Long calendarId = command.longValueOfParameterNamed("calendarId"); Calendar calendar = null; - if(calendarId != null && calendarId != 0){ + if (calendarId != null && calendarId != 0) { calendar = this.calendarRepository.findOne(calendarId); - if(calendar == null) { throw new CalendarNotFoundException(calendarId); } + if (calendar == null) { throw new CalendarNotFoundException(calendarId); } validateCalendarDates(command, calendar); } - + final Loan existingLoanApplication = retrieveLoanBy(loanId); if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified( @@ -217,8 +217,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa final String clientIdParamName = "clientId"; if (changes.containsKey(clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(clientIdParamName); - final Client client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); existingLoanApplication.updateClient(client); } @@ -231,8 +230,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa existingLoanApplication.updateLoanProduct(loanProduct); } - - //validate min and maximum constraints + + // validate min and maximum constraints this.fromApiJsonDeserializer.validateMinMaxConstraintsForModification(command.json(), existingLoanApplication.loanProduct()); final String fundIdParamName = "fundId"; @@ -295,19 +294,21 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa this.noteRepository.save(note); } - List ciList = (List) this.calendarInstanceRepository.findByEntityIdAndEntityTypeId(loanId, CalendarEntityType.LOANS.getValue()); - if(calendar != null){ - - //For loans, allow to attach only one calendar instance per loan - if(ciList != null && !ciList.isEmpty()){ + List ciList = (List) this.calendarInstanceRepository.findByEntityIdAndEntityTypeId(loanId, + CalendarEntityType.LOANS.getValue()); + if (calendar != null) { + + // For loans, allow to attach only one calendar instance per + // loan + if (ciList != null && !ciList.isEmpty()) { CalendarInstance calendarInstance = ciList.get(0); - if(calendarInstance.getCalendar().getId() != calendar.getId()){ + if (calendarInstance.getCalendar().getId() != calendar.getId()) { calendarInstance.updateCalendar(calendar); this.calendarInstanceRepository.saveAndFlush(calendarInstance); } } - - }else if(ciList != null && !ciList.isEmpty()){ + + } else if (ciList != null && !ciList.isEmpty()) { CalendarInstance calendarInstance = ciList.get(0); this.calendarInstanceRepository.delete(calendarInstance); } @@ -512,7 +513,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa loan.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper, this.loanRepaymentScheduleTransactionProcessorFactory); return loan; } - + private void validateCalendarDates(final JsonCommand command, final Calendar calendar) { // Validate disbursement date and first repayment dates matches calendar diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java index 7a4ce06dd..e4c519dc1 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanAssembler.java @@ -20,8 +20,7 @@ import org.mifosplatform.organisation.staff.domain.StaffRepository; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; import org.mifosplatform.organisation.staff.exception.StaffRoleException; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.fund.domain.Fund; @@ -56,7 +55,7 @@ import com.google.gson.JsonElement; public class LoanAssembler { private final LoanProductRepository loanProductRepository; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final GroupRepository groupRepository; private final FundRepository fundRepository; private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository; @@ -71,7 +70,7 @@ public class LoanAssembler { @Autowired public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanProductRepository loanProductRepository, - final ClientRepository clientRepository, final GroupRepository groupRepository, final FundRepository fundRepository, + final ClientRepositoryWrapper clientRepository, final GroupRepository groupRepository, final FundRepository fundRepository, final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository, final StaffRepository staffRepository, final CodeValueRepositoryWrapper codeValueRepository, final LoanScheduleAssembler loanScheduleAssembler, final LoanChargeAssembler loanChargeAssembler, @@ -112,7 +111,7 @@ public class LoanAssembler { final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } - + final Fund fund = findFundByIdIfProvided(fundId); final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId); final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(transactionProcessingStrategyId); @@ -130,8 +129,7 @@ public class LoanAssembler { Client client = null; Group group = null; if (clientId != null) { - client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + client = this.clientRepository.findOneWithNotFoundDetection(clientId); loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanPurpose, loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java index 4018fe217..437344681 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanChargeReadPlatformServiceImpl.java @@ -121,9 +121,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform final LoanChargeMapper rm = new LoanChargeMapper(); - // TODO - KW - check to see if its important that 'c.is_deleted=0' is - // required here? - final String sql = "select " + rm.schema() + " where c.is_deleted=0 and lc.loan_id=? " + final String sql = "select " + rm.schema() + " where lc.loan_id=? " + " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; return this.jdbcTemplate.query(sql, rm, new Object[] { loanId }); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index b620e0dc5..42db1cf39 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -25,6 +25,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.data.ClientData; +import org.mifosplatform.portfolio.client.domain.ClientEnumerations; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; @@ -185,12 +186,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { context.authenticatedUser(); GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId); - //get group associations + // get group associations Collection membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId); if (!CollectionUtils.isEmpty(membersOfGroup)) { groupAccount = GroupGeneralData.withAssocations(groupAccount, membersOfGroup); } - + final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant(); LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate); @@ -296,7 +297,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName," + " lp.id as loanProductId, lp.name as loanProductName, lp.description as loanProductDescription," + " c.id as clientId, c.display_name as clientName, c.office_id as clientOfficeId," - + " g.id as groupId, g.display_name as groupName, g.office_id as groupOfficeId, g.staff_id As groupStaffId , g.parent_id as groupParentId , g.hierarchy As groupHierarchy , g.external_id As groupExternalId , " + + " g.id as groupId, g.display_name as groupName," + + " g.office_id as groupOfficeId, g.staff_id As groupStaffId , g.parent_id as groupParentId, " + + " g.hierarchy As groupHierarchy , g.external_id As groupExternalId, " + + " g.status_enum as statusEnum, g.activation_date as activationDate, " + " l.submittedon_date as submittedOnDate, sbu.username as submittedByUsername, sbu.firstname as submittedByFirstname, sbu.lastname as submittedByLastname," + " l.rejectedon_date as rejectedOnDate, rbu.username as rejectedByUsername, rbu.firstname as rejectedByFirstname, rbu.lastname as rejectedByLastname," + " l.withdrawnon_date as withdrawnOnDate, wbu.username as withdrawnByUsername, wbu.firstname as withdrawnByFirstname, wbu.lastname as withdrawnByLastname," @@ -533,8 +537,11 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { GroupGeneralData groupData = null; if (groupId != null) { - groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupOfficeId, null, groupParentId, null, - groupStaffId, null, groupHierarchy); + final Integer groupStatusEnum = JdbcSupport.getInteger(rs, "statusEnum"); + final EnumOptionData groupStatus = ClientEnumerations.status(groupStatusEnum); + final LocalDate activationDate = JdbcSupport.getLocalDate(rs, "activationDate"); + groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupStatus, activationDate, groupOfficeId, + null, groupParentId, null, groupStaffId, null, groupHierarchy); } return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java index 448d3a133..dbca4202f 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/note/service/NoteWritePlatformServiceJpaRepositoryImpl.java @@ -11,7 +11,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; @@ -35,7 +35,7 @@ import org.springframework.stereotype.Service; public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService { private final NoteRepository noteRepository; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final GroupRepository groupRepository; // private final SavingAccountRepository savingAccountRepository; private final LoanRepository loanRepository; @@ -43,15 +43,12 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer; @Autowired - public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepository clientRepository, - final GroupRepository groupRepository, - // final SavingAccountRepository savingAccountRepository, - final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository, - final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) { + public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepositoryWrapper clientRepository, + final GroupRepository groupRepository, final LoanRepository loanRepository, + final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) { this.noteRepository = noteRepository; this.clientRepository = clientRepository; this.groupRepository = groupRepository; - // this.savingAccountRepository = savingAccountRepository; this.loanRepository = loanRepository; this.loanTransactionRepository = loanTransactionRepository; this.fromApiJsonDeserializer = fromApiJsonDeserializer; @@ -61,7 +58,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf final Long resourceId = command.getSupportedEntityId(); - final Client client = this.clientRepository.findOne(resourceId); + final Client client = this.clientRepository.findOneWithNotFoundDetection(resourceId); if (client == null) { throw new ClientNotFoundException(resourceId); } final Note newNote = Note.clientNoteFromJson(client, command); @@ -87,7 +84,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(newNote.getId()) // - .withClientId(group.getId()).withOfficeId(group.getOfficeId()).build(); + .withClientId(group.getId()) // + .withOfficeId(group.officeId()) // + .build(); } private CommandProcessingResult createLoanNote(final JsonCommand command) { @@ -105,12 +104,10 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(newNote.getId()) // - .withClientId(loan.getClientId()).withOfficeId(loan.getOfficeId()).withLoanId(loan.getId()).withGroupId(loan.getGroupId())// Loan - // can - // be - // associated - // to - // group + .withClientId(loan.getClientId()) // + .withOfficeId(loan.getOfficeId()) // + .withLoanId(loan.getId()) // + .withGroupId(loan.getGroupId()) // .build(); } @@ -196,8 +193,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf final NoteType type = NoteType.fromApiUrl(resourceUrl); - final Client client = this.clientRepository.findOne(resourceId); - if (client == null) { throw new ClientNotFoundException(resourceId); } + final Client client = this.clientRepository.findOneWithNotFoundDetection(resourceId); final Note noteForUpdate = this.noteRepository.findByClientIdAndId(resourceId, noteId); if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); } @@ -238,7 +234,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .withEntityId(noteForUpdate.getId()) // - .withGroupId(group.getId()).withOfficeId(group.getOfficeId()).with(changes).build(); + .withGroupId(group.getId()) // + .withOfficeId(group.officeId()) // + .with(changes).build(); } private CommandProcessingResult updateLoanNote(final JsonCommand command) { @@ -393,11 +391,12 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf noteForUpdate = this.noteRepository.findByLoanTransactionIdAndId(resourceId, noteId); } break; - // case SAVING_ACCOUNT: { - // noteForUpdate = - // this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId); - // } - // break; + // case SAVING_ACCOUNT: { + // noteForUpdate = + // this.noteRepository.findBySavingAccountIdAndId(resourceId, + // noteId); + // } + // break; case SAVING_ACCOUNT: break; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java index 050f64aa5..35a3bc8b9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountAssembler.java @@ -25,8 +25,7 @@ import org.joda.time.format.DateTimeFormatter; import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; @@ -40,14 +39,14 @@ import com.google.gson.JsonElement; public class SavingsAccountAssembler { private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final GroupRepository groupRepository; private final SavingsProductRepository savingProductRepository; private final FromJsonHelper fromApiJsonHelper; @Autowired public SavingsAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper, - final ClientRepository clientRepository, final GroupRepository groupRepository, + final ClientRepositoryWrapper clientRepository, final GroupRepository groupRepository, final SavingsProductRepository savingProductRepository, final FromJsonHelper fromApiJsonHelper) { this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper; this.clientRepository = clientRepository; @@ -78,8 +77,7 @@ public class SavingsAccountAssembler { Client client = null; Group group = null; if (clientId != null) { - client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + client = this.clientRepository.findOneWithNotFoundDetection(clientId); } if (groupId != null) { diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java index a9088d03e..c6b09b42a 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -22,8 +22,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.Client; -import org.mifosplatform.portfolio.client.domain.ClientRepository; -import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; +import org.mifosplatform.portfolio.client.domain.ClientRepositoryWrapper; import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; @@ -57,7 +56,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi private final SavingsAccountDataValidator savingsAccountDataValidator; private final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; - private final ClientRepository clientRepository; + private final ClientRepositoryWrapper clientRepository; private final GroupRepository groupRepository; private final SavingsProductRepository savingsProductRepository; @@ -67,7 +66,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final SavingsAccountTransactionRepository savingsAccountTransactionRepository, final SavingsAccountAssembler savingAccountAssembler, final SavingsAccountDataValidator savingsAccountDataValidator, final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator, - final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepository clientRepository, + final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepositoryWrapper clientRepository, final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) { this.context = context; this.savingAccountRepository = savingAccountRepository; @@ -160,8 +159,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi if (changes.containsKey(SavingsApiConstants.clientIdParamName)) { final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); if (clientId != null) { - final Client client = this.clientRepository.findOne(clientId); - if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } + final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId); account.update(client); } else { final Client client = null;
Field Descriptions
active
Indicates whether this client is to be created as active client. If active=true, then activationDate must be provided. If active=false, then the client is created as pending but this must be allowed through configuration. + Indicates whether this client is to be created as active client. If active=true, then activationDate must be provided. If active=false, then the client is created as pending.