MIFOSX-213: wip statuses on center and group data and remove is_deleted from client.

This commit is contained in:
Keith Woodlock
2013-04-19 00:43:36 +01:00
parent a6dcba11cf
commit 604f07f13e
35 changed files with 743 additions and 487 deletions
+5 -16
View File
@@ -1706,7 +1706,7 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
<div class="method-description"> <div class="method-description">
<h3>Clients</h3> <h3>Clients</h3>
<p>Clients are people and businesses that have applied (or may apply) to an MFI for loans.</p> <p>Clients are people and businesses that have applied (or may apply) to an MFI for loans.</p>
<p>Clients can be created in <b>Pending</b> state (as opposed to <b>Active</b> state) if global configuration for <i>allow-pending-client-status</i> is enabled.</p> <p>Clients can be created in <b>Pending</b> or straight into <b>Active</b> state.</p>
<table class=matrixHeading> <table class=matrixHeading>
<tr class="matrixHeadingBG"> <tr class="matrixHeadingBG">
<td><div class="mifosXHeading2">Field Descriptions</div></td> <td><div class="mifosXHeading2">Field Descriptions</div></td>
@@ -1733,7 +1733,7 @@ function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFuncti
<td>active</td> <td>active</td>
</tr> </tr>
<tr> <tr>
<td class=fielddesc>Indicates whether this client is to be created as <b>active</b> client. If active=true, then <b>activationDate</b> must be provided. If active=false, then the client is created as <b>pending</b> but this must be allowed through configuration. <td class=fielddesc>Indicates whether this client is to be created as <b>active</b> client. If active=true, then <b>activationDate</b> must be provided. If active=false, then the client is created as <b>pending</b>.
</td> </td>
</tr> </tr>
<tr class=alt> <tr class=alt>
@@ -1804,7 +1804,6 @@ GET https://DomainName/api/v1/clients/template
17 17
], ],
"officeId": 1, "officeId": 1,
"clientPendingApprovalAllowed": false,
"officeOptions": [ "officeOptions": [
{ {
"id": 1, "id": 1,
@@ -2946,7 +2945,7 @@ Request Body:
</code> </code>
<code class="method-response"> <code class="method-response">
{ {
"officeId": 8, "officeId": 1,
"groupId": 8, "groupId": 8,
"resourceId": 8, "resourceId": 8,
"changes": { "changes": {
@@ -7267,8 +7266,6 @@ Request Body:
<p>Global configuration related to set of supported enable/disable configurations:</p> <p>Global configuration related to set of supported enable/disable configurations:</p>
<ol> <ol>
<li><b>maker-checker</b> - defaults to false - if true turns on maker-checker functionality</li> <li><b>maker-checker</b> - defaults to false - if true turns on maker-checker functionality</li>
<li><b>allow-pending-client-status</b> - defaults to false - if true allows clients to be created in 'Pending' state</li>
<li><b>allow-pending-group-status</b> - defaults to false - if true allows groups to be created in 'Pending' state</li>
</ol> </ol>
</div> </div>
</div> </div>
@@ -7291,14 +7288,6 @@ GET https://DomainName/api/v1/configurations
{ {
"name": "maker-checker", "name": "maker-checker",
"enabled": false "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
</div> </div>
<div class="method-example"> <div class="method-example">
<code class="method-declaration"> <code class="method-declaration">
PUT https://DomainName/api/v1/configurations?allow-pending-client-status=false PUT https://DomainName/api/v1/configurations?maker-checker=false
</code> </code>
<code class="method-request"> <code class="method-request">
PUT configurations PUT configurations
@@ -7325,7 +7314,7 @@ Request Body: { }
{ {
"changes": { "changes": {
"globalConfiguration": { "globalConfiguration": {
"allow-pending-client-status": false "maker-checker": false
} }
} }
} }
@@ -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`;
@@ -265,6 +265,14 @@ public class CommandWrapper {
return this.actionName.equalsIgnoreCase("ACTIVATE") && this.entityName.equalsIgnoreCase("CLIENT"); 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() { public boolean isClientIdentifierResource() {
return this.entityName.equals("CLIENTIDENTIFIER"); return this.entityName.equals("CLIENTIDENTIFIER");
} }
@@ -483,7 +491,7 @@ public class CommandWrapper {
public boolean isCenterResource() { public boolean isCenterResource() {
return this.entityName.equalsIgnoreCase("CENTER"); return this.entityName.equalsIgnoreCase("CENTER");
} }
public boolean isReportResource() { public boolean isReportResource() {
return this.entityName.equalsIgnoreCase("REPORT"); return this.entityName.equalsIgnoreCase("REPORT");
} }
@@ -834,6 +834,25 @@ public class CommandWrapperBuilder {
this.actionName = "UPDATE"; this.actionName = "UPDATE";
this.entityName = "GROUP"; this.entityName = "GROUP";
this.entityId = groupId; 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; this.href = "/groups/" + groupId;
return this; return this;
} }
@@ -842,14 +861,7 @@ public class CommandWrapperBuilder {
this.actionName = "UNASSIGNSTAFF"; this.actionName = "UNASSIGNSTAFF";
this.entityName = "GROUP"; this.entityName = "GROUP";
this.entityId = groupId; this.entityId = groupId;
this.href = "/groups/" + groupId; this.groupId = groupId;
return this;
}
public CommandWrapperBuilder deleteGroup(final Long groupId) {
this.actionName = "DELETE";
this.entityName = "GROUP";
this.entityId = groupId;
this.href = "/groups/" + groupId; this.href = "/groups/" + groupId;
return this; return this;
} }
@@ -911,4 +923,13 @@ public class CommandWrapperBuilder {
this.href = "/centers/" + centerId; this.href = "/centers/" + centerId;
return this; 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;
}
} }
@@ -398,6 +398,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = applicationContext.getBean("unassignStaffCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("unassignStaffCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) { } else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteGroupCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("deleteGroupCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isGroupActivation()) {
handler = applicationContext.getBean("activateGroupCommandHandler", NewCommandSourceHandler.class);
} else { } else {
throw new UnsupportedCommandException(wrapper.commandName()); throw new UnsupportedCommandException(wrapper.commandName());
} }
@@ -408,6 +410,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
handler = applicationContext.getBean("updateCenterCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("updateCenterCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) { } else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteCenterCommandHandler", NewCommandSourceHandler.class); handler = applicationContext.getBean("deleteCenterCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isCenterActivation()) {
handler = applicationContext.getBean("activateCenterCommandHandler", NewCommandSourceHandler.class);
} else { } else {
throw new UnsupportedCommandException(wrapper.commandName()); throw new UnsupportedCommandException(wrapper.commandName());
} }
@@ -8,6 +8,4 @@ package org.mifosplatform.infrastructure.configuration.domain;
public interface ConfigurationDomainService { public interface ConfigurationDomainService {
boolean isMakerCheckerEnabledForTask(String taskPermissionCode); boolean isMakerCheckerEnabledForTask(String taskPermissionCode);
boolean isClientPendingApprovalAllowedEnabled();
} }
@@ -39,13 +39,4 @@ public class ConfigurationDomainServiceJpa implements ConfigurationDomainService
return thisTask.hasMakerCheckerEnabled() && property.isEnabled(); 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();
}
} }
@@ -6,13 +6,12 @@
package org.mifosplatform.organisation.staff.domain; package org.mifosplatform.organisation.staff.domain;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.domain.ClientRepository;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
/** /**
* <p> * <p>
* Wrapper for {@link ClientRepository} that adds NULL checking and Error * Wrapper for {@link StaffRepository} that adds NULL checking and Error
* handling capabilities * handling capabilities
* </p> * </p>
*/ */
@@ -32,4 +31,9 @@ public class StaffRepositoryWrapper {
return staff; 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;
}
} }
@@ -27,6 +27,8 @@ final public class ClientData implements Comparable<ClientData> {
private final String externalId; private final String externalId;
private final EnumOptionData status; private final EnumOptionData status;
@SuppressWarnings("unused")
private final Boolean active;
private final LocalDate activationDate; private final LocalDate activationDate;
private final String firstname; private final String firstname;
@@ -42,33 +44,27 @@ final public class ClientData implements Comparable<ClientData> {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Boolean imagePresent; private final Boolean imagePresent;
private final Boolean clientPendingApprovalAllowed;
// associations // associations
private final Collection<GroupGeneralData> groups; private final Collection<GroupGeneralData> groups;
// template // template
private final Collection<OfficeData> officeOptions; private final Collection<OfficeData> officeOptions;
public static ClientData template(final Long officeId, final LocalDate joinedDate, final Boolean clientPendingApprovalAllowed, public static ClientData template(final Long officeId, final LocalDate joinedDate, final Collection<OfficeData> officeOptions) {
final Collection<OfficeData> allowedOffices) { return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, officeOptions, null);
return new ClientData(null, null, officeId, null, null, null, null, null, null, null, null, joinedDate, null,
clientPendingApprovalAllowed, allowedOffices, null);
} }
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeData> allowedOffices) { public static ClientData templateOnTop(final ClientData clientData, final List<OfficeData> allowedOffices) {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id, return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed, clientData.externalId, clientData.activationDate, clientData.imageKey, allowedOffices, clientData.groups);
allowedOffices, clientData.groups);
} }
public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) { public static ClientData setParentGroups(final ClientData clientData, final Collection<GroupGeneralData> parentGroups) {
return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id, return new ClientData(clientData.accountNo, clientData.status, clientData.officeId, clientData.officeName, clientData.id,
clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName,
clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.clientPendingApprovalAllowed, clientData.externalId, clientData.activationDate, clientData.imageKey, clientData.officeOptions, parentGroups);
clientData.officeOptions, parentGroups);
} }
public static ClientData clientIdentifier(final Long id, final String accountNo, final EnumOptionData status, final String firstname, 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<ClientData> {
final String officeName) { final String officeName) {
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null, 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) { 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 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 String externalId, final LocalDate activationDate, final String imageKey, final Collection<OfficeData> allowedOffices,
final Collection<OfficeData> allowedOffices, final Collection<GroupGeneralData> groups) { final Collection<GroupGeneralData> groups) {
this.accountNo = accountNo; this.accountNo = accountNo;
this.status = status; this.status = status;
if (status != null) {
active = status.getId().equals(300L);
} else {
active = null;
}
this.officeId = officeId; this.officeId = officeId;
this.officeName = officeName; this.officeName = officeName;
this.id = id; this.id = id;
@@ -106,8 +114,6 @@ final public class ClientData implements Comparable<ClientData> {
this.imagePresent = null; this.imagePresent = null;
} }
this.clientPendingApprovalAllowed = clientPendingApprovalAllowed;
// associations // associations
this.groups = groups; this.groups = groups;
@@ -37,7 +37,7 @@ public final class ClientDataValidator {
this.fromApiJsonHelper = fromApiJsonHelper; 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(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
@@ -74,10 +74,6 @@ public final class ClientDataValidator {
if (active.booleanValue()) { if (active.booleanValue()) {
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element); final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull(); baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull();
} else {
if (!isPendingApprovalEnabled) {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).failWithCode(".pending.status.not.allowed");
}
} }
} else { } else {
baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false); baseDataValidator.reset().parameter(ClientApiConstants.activeParamName).value(active).trueOrFalseRequired(false);
@@ -86,7 +82,7 @@ public final class ClientDataValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
public void validateForUpdate(final String json, final boolean isPendingApprovalEnabled) { public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
@@ -139,13 +135,7 @@ public final class ClientDataValidator {
if (active.booleanValue()) { if (active.booleanValue()) {
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element); final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(ClientApiConstants.activationDateParamName, element);
baseDataValidator.reset().parameter(ClientApiConstants.activationDateParamName).value(joinedDate).notNull(); 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) { if (!atLeastOneParameterPassedForUpdate) {
@@ -179,8 +169,7 @@ public final class ClientDataValidator {
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) { private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
// //
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", throw new PlatformApiDataValidationException(dataValidationErrors);
dataValidationErrors);
} }
} }
} }
@@ -79,9 +79,6 @@ public final class Client extends AbstractPersistable<Long> {
@Column(name = "external_id", length = 100, nullable = true, unique = true) @Column(name = "external_id", length = 100, nullable = true, unique = true)
private String externalId; private String externalId;
@Column(name = "is_deleted", nullable = false)
private boolean deleted = false;
@Column(name = "image_key", length = 500, nullable = true) @Column(name = "image_key", length = 500, nullable = true)
private String imageKey; private String imageKey;
@@ -92,8 +89,7 @@ public final class Client extends AbstractPersistable<Long> {
@Transient @Transient
private boolean accountNumberRequiresAutoGeneration = false; private boolean accountNumberRequiresAutoGeneration = false;
public static Client createNew(final Office clientOffice, final Group clientParentGroup, final JsonCommand command, public static Client createNew(final Office clientOffice, final Group clientParentGroup, final JsonCommand command) {
final boolean isPendingStateAllowed) {
final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName); final String accountNo = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName);
final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName); final String externalId = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName);
@@ -103,17 +99,16 @@ public final class Client extends AbstractPersistable<Long> {
final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName); final String lastname = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName); final String fullname = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
ClientStatus status = ClientStatus.ACTIVE; ClientStatus status = ClientStatus.PENDING;
boolean active = true; boolean active = false;
if (isPendingStateAllowed && command.hasParameter("active")) { if (command.hasParameter("active")) {
active = command.booleanPrimitiveValueOfParameterNamed(ClientApiConstants.activeParamName); active = command.booleanPrimitiveValueOfParameterNamed(ClientApiConstants.activeParamName);
} }
LocalDate activationDate = null; LocalDate activationDate = null;
if (active) { if (active) {
status = ClientStatus.ACTIVE;
activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName); activationDate = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
} else {
status = ClientStatus.PENDING;
} }
return new Client(status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate, return new Client(status, clientOffice, clientParentGroup, accountNo, firstname, middlename, lastname, fullname, activationDate,
@@ -193,7 +188,26 @@ public final class Client extends AbstractPersistable<Long> {
} }
public void changeOffice(final Office newOffice) { 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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
dataValidationErrors.add(error);
throw new PlatformApiDataValidationException(dataValidationErrors);
} }
public void updateAccountNo(final String accountIdentifier) { public void updateAccountNo(final String accountIdentifier) {
@@ -253,58 +267,50 @@ public final class Client extends AbstractPersistable<Long> {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9); final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
final String statusEnumParamName = "status"; if (command.isChangeInIntegerParameterNamed(ClientApiConstants.statusParamName, this.status)) {
if (command.isChangeInIntegerParameterNamed(statusEnumParamName, this.status)) { final Integer newValue = command.integerValueOfParameterNamed(ClientApiConstants.statusParamName);
final Integer newValue = command.integerValueOfParameterNamed(statusEnumParamName); actualChanges.put(ClientApiConstants.statusParamName, ClientEnumerations.status(newValue));
actualChanges.put(statusEnumParamName, ClientEnumerations.status(newValue));
this.status = ClientStatus.fromInt(newValue).getValue(); this.status = ClientStatus.fromInt(newValue).getValue();
} }
final String accountNoParamName = "accountNo"; if (command.isChangeInStringParameterNamed(ClientApiConstants.accountNoParamName, this.accountNumber)) {
if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.accountNoParamName);
final String newValue = command.stringValueOfParameterNamed(accountNoParamName); actualChanges.put(ClientApiConstants.accountNoParamName, newValue);
actualChanges.put(accountNoParamName, newValue);
this.accountNumber = StringUtils.defaultIfEmpty(newValue, null); this.accountNumber = StringUtils.defaultIfEmpty(newValue, null);
} }
final String externalIdParamName = "externalId"; if (command.isChangeInStringParameterNamed(ClientApiConstants.externalIdParamName, this.externalId)) {
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.externalIdParamName);
final String newValue = command.stringValueOfParameterNamed(externalIdParamName); actualChanges.put(ClientApiConstants.externalIdParamName, newValue);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null); this.externalId = StringUtils.defaultIfEmpty(newValue, null);
} }
final String officeIdParamName = "officeId"; if (command.isChangeInLongParameterNamed(ClientApiConstants.officeIdParamName, this.office.getId())) {
if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) { final Long newValue = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName);
final Long newValue = command.longValueOfParameterNamed(officeIdParamName); actualChanges.put(ClientApiConstants.officeIdParamName, newValue);
actualChanges.put(officeIdParamName, newValue);
} }
final String firstnameParamName = "firstname"; if (command.isChangeInStringParameterNamed(ClientApiConstants.firstnameParamName, this.firstname)) {
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstname)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.firstnameParamName);
final String newValue = command.stringValueOfParameterNamed(firstnameParamName); actualChanges.put(ClientApiConstants.firstnameParamName, newValue);
actualChanges.put(firstnameParamName, newValue);
this.firstname = StringUtils.defaultIfEmpty(newValue, null); this.firstname = StringUtils.defaultIfEmpty(newValue, null);
} }
final String middlenameParamName = "middlename"; if (command.isChangeInStringParameterNamed(ClientApiConstants.middlenameParamName, this.middlename)) {
if (command.isChangeInStringParameterNamed(middlenameParamName, this.middlename)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.middlenameParamName);
final String newValue = command.stringValueOfParameterNamed(middlenameParamName); actualChanges.put(ClientApiConstants.middlenameParamName, newValue);
actualChanges.put(middlenameParamName, newValue);
this.middlename = StringUtils.defaultIfEmpty(newValue, null); this.middlename = StringUtils.defaultIfEmpty(newValue, null);
} }
final String lastnameParamName = "lastname"; if (command.isChangeInStringParameterNamed(ClientApiConstants.lastnameParamName, this.lastname)) {
if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastname)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.lastnameParamName);
final String newValue = command.stringValueOfParameterNamed(lastnameParamName); actualChanges.put(ClientApiConstants.lastnameParamName, newValue);
actualChanges.put(lastnameParamName, newValue);
this.lastname = StringUtils.defaultIfEmpty(newValue, null); this.lastname = StringUtils.defaultIfEmpty(newValue, null);
} }
final String fullnameParamName = "fullname"; if (command.isChangeInStringParameterNamed(ClientApiConstants.fullnameParamName, this.fullname)) {
if (command.isChangeInStringParameterNamed(fullnameParamName, this.fullname)) { final String newValue = command.stringValueOfParameterNamed(ClientApiConstants.fullnameParamName);
final String newValue = command.stringValueOfParameterNamed(fullnameParamName); actualChanges.put(ClientApiConstants.fullnameParamName, newValue);
actualChanges.put(fullnameParamName, newValue);
this.fullname = newValue; this.fullname = newValue;
} }
@@ -313,14 +319,13 @@ public final class Client extends AbstractPersistable<Long> {
final String dateFormatAsInput = command.dateFormat(); final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale(); final String localeAsInput = command.locale();
final String joiningDateParamName = "joinedDate"; if (command.isChangeInLocalDateParameterNamed(ClientApiConstants.activationDateParamName, getActivationLocalDate())) {
if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) { final String valueAsInput = command.stringValueOfParameterNamed(ClientApiConstants.activationDateParamName);
final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName); actualChanges.put(ClientApiConstants.activationDateParamName, valueAsInput);
actualChanges.put(joiningDateParamName, valueAsInput); actualChanges.put(ClientApiConstants.dateFormatParamName, dateFormatAsInput);
actualChanges.put("dateFormat", dateFormatAsInput); actualChanges.put(ClientApiConstants.localeParamName, localeAsInput);
actualChanges.put("locale", localeAsInput);
final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName); final LocalDate newValue = command.localDateValueOfParameterNamed(ClientApiConstants.activationDateParamName);
this.activationDate = newValue.toDate(); this.activationDate = newValue.toDate();
} }
@@ -378,27 +383,12 @@ public final class Client extends AbstractPersistable<Long> {
this.displayName = nameBuilder.toString(); this.displayName = nameBuilder.toString();
} }
private LocalDate getJoiningLocalDate() { private LocalDate getActivationLocalDate() {
LocalDate joiningLocalDate = null; LocalDate activationLocalDate = null;
if (this.activationDate != null) { if (this.activationDate != null) {
joiningLocalDate = LocalDate.fromDateFields(this.activationDate); activationLocalDate = LocalDate.fromDateFields(this.activationDate);
} }
return joiningLocalDate; return activationLocalDate;
}
/**
* Delete is a <i>soft delete</i>. 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;
} }
public boolean isOfficeIdentifiedBy(final Long officeId) { public boolean isOfficeIdentifiedBy(final Long officeId) {
@@ -27,7 +27,7 @@ public class ClientRepositoryWrapper {
public Client findOneWithNotFoundDetection(final Long id) { public Client findOneWithNotFoundDetection(final Long id) {
final Client client = this.repository.findOne(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; return client;
} }
@@ -19,9 +19,8 @@ import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifier;
import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; 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.ClientIdentifierNotFoundException;
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -37,14 +36,14 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
private final static Logger logger = LoggerFactory.getLogger(ClientIdentifierWritePlatformServiceJpaRepositoryImpl.class); private final static Logger logger = LoggerFactory.getLogger(ClientIdentifierWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final ClientIdentifierRepository clientIdentifierRepository; private final ClientIdentifierRepository clientIdentifierRepository;
private final CodeValueRepositoryWrapper codeValueRepository; private final CodeValueRepositoryWrapper codeValueRepository;
private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer;
@Autowired @Autowired
public ClientIdentifierWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public ClientIdentifierWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ClientRepository clientRepository, final ClientIdentifierRepository clientIdentifierRepository, final ClientRepositoryWrapper clientRepository, final ClientIdentifierRepository clientIdentifierRepository,
final CodeValueRepositoryWrapper codeValueRepository, final CodeValueRepositoryWrapper codeValueRepository,
final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer) { final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer) {
this.context = context; this.context = context;
@@ -67,8 +66,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
String documentTypeLabel = null; String documentTypeLabel = null;
Long documentTypeId = null; Long documentTypeId = null;
try { try {
final Client client = this.clientRepository.findOne(clientId); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand final CodeValue documentType = this.codeValueRepository.findOneWithNotFoundDetection(clientIdentifierCommand
.getDocumentTypeId()); .getDocumentTypeId());
@@ -106,6 +104,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
try { try {
CodeValue documentType = null; CodeValue documentType = null;
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(identifierId); final ClientIdentifier clientIdentifierForUpdate = this.clientIdentifierRepository.findOne(identifierId);
if (clientIdentifierForUpdate == null) { throw new ClientIdentifierNotFoundException(identifierId); } if (clientIdentifierForUpdate == null) { throw new ClientIdentifierNotFoundException(identifierId); }
@@ -135,10 +134,9 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
this.clientIdentifierRepository.saveAndFlush(clientIdentifierForUpdate); this.clientIdentifierRepository.saveAndFlush(clientIdentifierForUpdate);
} }
final Client client = this.clientRepository.findOne(clientId);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withOfficeId(client.getOffice().getId()) // .withOfficeId(client.officeId()) //
.withClientId(clientId) // .withClientId(clientId) //
.withEntityId(identifierId) // .withEntityId(identifierId) //
.with(changes) // .with(changes) //
@@ -152,13 +150,19 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
@Transactional @Transactional
@Override @Override
public CommandProcessingResult deleteClientIdentifier(final Long clientId, final Long identifierId, final Long commandId) { 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); final ClientIdentifier clientIdentifier = this.clientIdentifierRepository.findOne(identifierId);
if (clientIdentifier == null) { throw new ClientIdentifierNotFoundException(identifierId); } if (clientIdentifier == null) { throw new ClientIdentifierNotFoundException(identifierId); }
this.clientIdentifierRepository.delete(clientIdentifier); this.clientIdentifierRepository.delete(clientIdentifier);
final Client client = this.clientRepository.findOne(clientId); return new CommandProcessingResultBuilder() //
return new CommandProcessingResultBuilder().withCommandId(commandId).withOfficeId(client.getOffice().getId()) .withCommandId(commandId) //
.withClientId(clientId).withEntityId(identifierId).build(); .withOfficeId(client.officeId()) //
.withClientId(clientId) //
.withEntityId(identifierId) //
.build();
} }
private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId, private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId,
@@ -177,5 +181,4 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
logger.error(dve.getMessage(), dve); logger.error(dve.getMessage(), dve);
} }
} }
@@ -13,7 +13,6 @@ import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
@@ -42,7 +41,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ConfigurationDomainService configurationDomainService;
private final OfficeReadPlatformService officeReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService;
// data mappers // data mappers
@@ -53,9 +51,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
@Autowired @Autowired
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final ConfigurationDomainService configurationDomainService, final OfficeReadPlatformService officeReadPlatformService) { final OfficeReadPlatformService officeReadPlatformService) {
this.context = context; this.context = context;
this.configurationDomainService = configurationDomainService;
this.officeReadPlatformService = officeReadPlatformService; this.officeReadPlatformService = officeReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
} }
@@ -67,11 +64,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final Collection<OfficeData> offices = officeReadPlatformService.retrieveAllOfficesForDropdown(); final Collection<OfficeData> offices = officeReadPlatformService.retrieveAllOfficesForDropdown();
final boolean clientPendingApprovalAllowed = this.configurationDomainService.isClientPendingApprovalAllowedEnabled();
final Long officeId = currentUser.getOffice().getId(); final Long officeId = currentUser.getOffice().getId();
return ClientData.template(officeId, new LocalDate(), clientPendingApprovalAllowed, offices); return ClientData.template(officeId, new LocalDate(), offices);
} }
@Override @Override
@@ -81,19 +76,19 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String hierarchy = currentUser.getOffice().getHierarchy(); final String hierarchy = currentUser.getOffice().getHierarchy();
final String hierarchySearchString = hierarchy + "%"; 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); final String extraCriteria = buildSqlStringFromClientCriteria(searchParameters);
if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")"; if (StringUtils.isNotBlank(extraCriteria)) sql += " and (" + extraCriteria + ")";
sql += " order by c.display_name ASC, c.account_no ASC"; sql += " order by c.display_name ASC, c.account_no ASC";
return this.jdbcTemplate.query(sql, clientMapper, new Object[] { hierarchySearchString }); return this.jdbcTemplate.query(sql, clientMapper, new Object[] { hierarchySearchString });
} }
private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) { private String buildSqlStringFromClientCriteria(final SearchParameters searchParameters) {
final String sqlSearch = searchParameters.getSqlSearch(); final String sqlSearch = searchParameters.getSqlSearch();
final Long officeId = searchParameters.getOfficeId(); final Long officeId = searchParameters.getOfficeId();
final String externalId = searchParameters.getExternalId(); final String externalId = searchParameters.getExternalId();
@@ -147,13 +142,14 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
String hierarchy = currentUser.getOffice().getHierarchy(); String hierarchy = currentUser.getOffice().getHierarchy();
String hierarchySearchString = hierarchy + "%"; 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, ClientData clientData = this.jdbcTemplate.queryForObject(sql, this.clientMapper,
new Object[] { hierarchySearchString, clientId }); new Object[] { hierarchySearchString, clientId });
String clientGroupsSql = "select " + this.clientGroupsMapper.parentGroupsSchema(); String clientGroupsSql = "select " + this.clientGroupsMapper.parentGroupsSchema();
Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper, new Object[] { clientId }); Collection<GroupGeneralData> parentGroups = this.jdbcTemplate.query(clientGroupsSql, this.clientGroupsMapper,
new Object[] { clientId });
return ClientData.setParentGroups(clientData, parentGroups); return ClientData.setParentGroups(clientData, parentGroups);
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
throw new ClientNotFoundException(clientId); throw new ClientNotFoundException(clientId);
@@ -188,7 +184,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String hierarchySearchString = hierarchy + "%"; final String hierarchySearchString = hierarchy + "%";
final String sql = "select " + this.membersOfGroupMapper.schema() 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 }); 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 imageKey = rs.getString("imageKey");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
externalId, activationDate, imageKey, null, null, null); externalId, activationDate, imageKey);
} }
} }
@@ -283,8 +279,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String imageKey = rs.getString("imageKey"); final String imageKey = rs.getString("imageKey");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
return new ClientData(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, return ClientData.instance(accountNo, status, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName,
externalId, activationDate, imageKey, null, null, null); 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("c.office_id as officeId, o.name as officeName ");
builder.append("from m_client c "); builder.append("from m_client c ");
builder.append("join m_office o on o.id = c.office_id "); builder.append("join m_office o on o.id = c.office_id ");
builder.append("where c.is_deleted=0");
this.schema = builder.toString(); this.schema = builder.toString();
} }
@@ -16,7 +16,6 @@ import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; 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.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -60,14 +59,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final ClientDataValidator fromApiJsonDeserializer; private final ClientDataValidator fromApiJsonDeserializer;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
private final ConfigurationDomainService configurationDomainService;
@Autowired @Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository, final ClientRepositoryWrapper clientRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
final ClientDataValidator fromApiJsonDeserializer, final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final GroupRepository groupRepository, final GroupRepository groupRepository) {
final ConfigurationDomainService configurationDomainService) {
this.context = context; this.context = context;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
@@ -75,7 +72,6 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
this.configurationDomainService = configurationDomainService;
} }
@Transactional @Transactional
@@ -128,8 +124,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
try { try {
context.authenticatedUser(); context.authenticatedUser();
final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled(); this.fromApiJsonDeserializer.validateForCreate(command.json());
this.fromApiJsonDeserializer.validateForCreate(command.json(), isPendingApprovalEnabled);
final Long officeId = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName); final Long officeId = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName);
@@ -144,7 +139,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
if (clientParentGroup == null) { throw new GroupNotFoundException(groupId); } 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); this.clientRepository.save(newClient);
@@ -175,15 +170,14 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
try { try {
context.authenticatedUser(); context.authenticatedUser();
final boolean isPendingApprovalEnabled = this.configurationDomainService.isClientPendingApprovalAllowedEnabled(); this.fromApiJsonDeserializer.validateForUpdate(command.json());
this.fromApiJsonDeserializer.validateForUpdate(command.json(), isPendingApprovalEnabled);
final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId); final Client clientForUpdate = this.clientRepository.findOneWithNotFoundDetection(clientId);
final Map<String, Object> changes = clientForUpdate.update(command); final Map<String, Object> changes = clientForUpdate.update(command);
if (changes.containsKey("officeId")) { if (changes.containsKey(ClientApiConstants.officeIdParamName)) {
final Long officeId = (Long) changes.get("officeId"); final Long officeId = (Long) changes.get(ClientApiConstants.officeIdParamName);
final Office newOffice = this.officeRepository.findOne(officeId); final Office newOffice = this.officeRepository.findOne(officeId);
if (newOffice == null) { throw new OfficeNotFoundException(officeId); } if (newOffice == null) { throw new OfficeNotFoundException(officeId); }
@@ -203,7 +197,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.build(); .build();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
return new CommandProcessingResult(Long.valueOf(-1)); return CommandProcessingResult.empty();
} }
} }
@@ -231,7 +225,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.build(); .build();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, 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) { 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); final String imageUploadLocation = FileUtils.generateClientImageParentDirectory(clientId);
// delete previous image from the file system // delete previous image from the file system
@@ -23,12 +23,14 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; 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.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
@@ -170,6 +172,33 @@ public class CentersApiResource {
return this.toApiJsonSerializer.serialize(result); 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 @GET
@Path("{centerId}/loans") @Path("{centerId}/loans")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@@ -31,6 +31,7 @@ public class GroupingTypesApiConstants {
public static final String clientMembersParamName = "clientMembers"; public static final String clientMembersParamName = "clientMembers";
// response parameters // response parameters
public static final String statusParamName = "status";
public static final String hierarchyParamName = "hierarchy"; public static final String hierarchyParamName = "hierarchy";
public static final String officeNameParamName = "officeName"; public static final String officeNameParamName = "officeName";
public static final String staffNameParamName = "staffName"; public static final String staffNameParamName = "staffName";
@@ -57,9 +58,12 @@ public class GroupingTypesApiConstants {
public static final Set<String> CENTER_GROUP_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, nameParamName, public static final Set<String> CENTER_GROUP_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, nameParamName,
externalIdParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName, externalIdParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName,
officeOptionsParamName, staffOptionsParamName,clientOptionsParamName)); officeOptionsParamName, staffOptionsParamName, clientOptionsParamName));
public static final Set<String> GROUP_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, nameParamName, public static final Set<String> GROUP_RESPONSE_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(idParamName, nameParamName,
externalIdParamName, officeIdParamName, officeNameParamName, "parentId", "parentName", staffIdParamName, staffNameParamName, externalIdParamName, officeIdParamName, officeNameParamName, "parentId", "parentName", staffIdParamName, staffNameParamName,
hierarchyParamName, officeOptionsParamName, staffOptionsParamName,clientOptionsParamName)); hierarchyParamName, officeOptionsParamName, staffOptionsParamName, clientOptionsParamName));
public static final Set<String> ACTIVATION_REQUEST_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
dateFormatParamName, activationDateParamName));
} }
@@ -23,12 +23,14 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; 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.ApiRequestJsonSerializationSettings;
import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
@@ -206,6 +208,33 @@ public class GroupsApiResource {
return this.toApiJsonSerializer.serialize(result); 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 @GET
@Path("{groupId}/loans") @Path("{groupId}/loans")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@@ -7,6 +7,8 @@ package org.mifosplatform.portfolio.group.data;
import java.util.Collection; 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.office.data.OfficeData;
import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientData;
@@ -20,6 +22,12 @@ public class GroupGeneralData {
private final Long id; private final Long id;
private final String name; private final String name;
private final String externalId; private final String externalId;
private final EnumOptionData status;
@SuppressWarnings("unused")
private final Boolean active;
private final LocalDate activationDate;
private final Long officeId; private final Long officeId;
private final String officeName; private final String officeName;
private final Long centerId; private final Long centerId;
@@ -40,8 +48,8 @@ public class GroupGeneralData {
public static GroupGeneralData lookup(final Long groupId, final String groupName) { public static GroupGeneralData lookup(final Long groupId, final String groupName) {
final Collection<ClientData> clientMembers = null; final Collection<ClientData> clientMembers = null;
return new GroupGeneralData(groupId, groupName, null, null, null, null, null, null, null, null, clientMembers, null, null, null, return new GroupGeneralData(groupId, groupName, null, null, null, null, null, null, null, null, null, null, clientMembers, null,
null); null, null, null);
} }
public static GroupGeneralData template(final Long officeId, final Long centerId, final String centerName, final Long staffId, 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<ClientData> clientMembers = null; final Collection<ClientData> clientMembers = null;
return new GroupGeneralData(null, null, null, officeId, null, centerId, centerName, staffId, staffName, null, clientMembers, return new GroupGeneralData(null, null, null, null, null, officeId, null, centerId, centerName, staffId, staffName, null,
centerOptions, officeOptions, staffOptions, clientOptions); clientMembers, centerOptions, officeOptions, staffOptions, clientOptions);
} }
public static GroupGeneralData withTemplate(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping) { public static GroupGeneralData withTemplate(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping) {
return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate,
grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, grouping.clientMembers, grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName,
templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, grouping.hierarchy, grouping.clientMembers, templatedGrouping.centerOptions, templatedGrouping.officeOptions,
templatedGrouping.clientOptions); templatedGrouping.staffOptions, templatedGrouping.clientOptions);
} }
public static GroupGeneralData withTemplateAndAssociations(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping, public static GroupGeneralData withTemplateAndAssociations(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping,
final Collection<ClientData> membersOfGroup) { final Collection<ClientData> membersOfGroup) {
return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate,
grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName,
templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, grouping.hierarchy, membersOfGroup, templatedGrouping.centerOptions, templatedGrouping.officeOptions,
templatedGrouping.clientOptions); templatedGrouping.staffOptions, templatedGrouping.clientOptions);
} }
public static GroupGeneralData withAssocations(final GroupGeneralData grouping, final Collection<ClientData> membersOfGroup) { public static GroupGeneralData withAssocations(final GroupGeneralData grouping, final Collection<ClientData> membersOfGroup) {
return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.status, grouping.activationDate,
grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, grouping.officeId, grouping.officeName, grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName,
grouping.centerOptions, grouping.officeOptions, grouping.staffOptions, grouping.clientOptions); 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, public static GroupGeneralData instance(final Long id, final String name, final String externalId, final EnumOptionData status,
final String officeName, final Long centerId, final String centerName, final Long staffId, final String staffName, final LocalDate activationDate, final Long officeId, final String officeName, final Long centerId, final String centerName,
final String hierarchy) { final Long staffId, final String staffName, final String hierarchy) {
final Collection<ClientData> clientMembers = null; final Collection<ClientData> clientMembers = null;
final Collection<CenterData> centerOptions = null; final Collection<CenterData> centerOptions = null;
@@ -85,17 +94,26 @@ public class GroupGeneralData {
final Collection<StaffData> staffOptions = null; final Collection<StaffData> staffOptions = null;
final Collection<ClientData> clientOptions = null; final Collection<ClientData> clientOptions = null;
return new GroupGeneralData(id, name, externalId, officeId, officeName, centerId, centerName, staffId, staffName, hierarchy, return new GroupGeneralData(id, name, externalId, status, activationDate, officeId, officeName, centerId, centerName, staffId,
clientMembers, centerOptions, officeOptions, staffOptions, clientOptions); staffName, hierarchy, clientMembers, centerOptions, officeOptions, staffOptions, clientOptions);
} }
private GroupGeneralData(final Long id, final String name, final String externalId, final Long officeId, final String officeName, private GroupGeneralData(final Long id, final String name, final String externalId, final EnumOptionData status,
final Long centerId, final String centerName, final Long staffId, final String staffName, final String hierarchy, final LocalDate activationDate, final Long officeId, final String officeName, final Long centerId, final String centerName,
final Collection<ClientData> clientMembers, final Collection<CenterData> centerOptions, final Long staffId, final String staffName, final String hierarchy, final Collection<ClientData> clientMembers,
final Collection<OfficeData> officeOptions, final Collection<StaffData> staffOptions, final Collection<ClientData> clientOptions) { final Collection<CenterData> centerOptions, final Collection<OfficeData> officeOptions,
final Collection<StaffData> staffOptions, final Collection<ClientData> clientOptions) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.externalId = externalId; 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.officeId = officeId;
this.officeName = officeName; this.officeName = officeName;
this.centerId = centerId; this.centerId = centerId;
@@ -5,10 +5,15 @@
*/ */
package org.mifosplatform.portfolio.group.domain; package org.mifosplatform.portfolio.group.domain;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.persistence.Column; import javax.persistence.Column;
@@ -25,11 +30,19 @@ import javax.persistence.TemporalType;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; 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.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
import com.google.common.collect.Sets;
@Entity @Entity
@Table(name = "m_group") @Table(name = "m_group")
public final class Group extends AbstractPersistable<Long> { public final class Group extends AbstractPersistable<Long> {
@@ -134,6 +147,46 @@ public final class Group extends AbstractPersistable<Long> {
} }
} }
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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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() { public boolean isNotPending() {
return !isPending(); return !isPending();
} }
@@ -142,72 +195,59 @@ public final class Group extends AbstractPersistable<Long> {
return GroupingTypeStatus.fromInt(this.status).isPending(); return GroupingTypeStatus.fromInt(this.status).isPending();
} }
private void addChild(final Group group) { public Map<String, Object> update(final JsonCommand command) {
this.groupMembers.add(group); final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(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() { private LocalDate getActivationLocalDate() {
return this.office.getId(); LocalDate activationLocalDate = null;
} if (this.activationDate != null) {
activationLocalDate = new LocalDate(this.activationDate);
public Staff getStaff() { }
return this.staff; return activationLocalDate;
}
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<Client> getClientMembers() {
return this.clientMembers;
}
public Group getParent() {
return this.parent;
}
public void setParent(final Group parent) {
this.parent = parent;
}
public void setClientMembers(final Set<Client> 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;
} }
public void addClientMember(final Client member) { public void addClientMember(final Client member) {
@@ -219,7 +259,6 @@ public final class Group extends AbstractPersistable<Long> {
} }
public void generateHierarchy() { public void generateHierarchy() {
if (this.parent != null) { if (this.parent != null) {
this.hierarchy = this.parent.hierarchyOf(getId()); this.hierarchy = this.parent.hierarchyOf(getId());
} else { } else {
@@ -238,4 +277,68 @@ public final class Group extends AbstractPersistable<Long> {
public Long officeId() { public Long officeId() {
return this.office.getId(); 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<String> updateClientMembersIfDifferent(final Set<Client> clientMembersSet) {
List<String> differences = new ArrayList<String>();
if (!clientMembersSet.equals(this.clientMembers)) {
Set<Client> 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<Client> clients) {
String[] clientIds = new String[clients.size()];
Iterator<Client> 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;
}
} }
@@ -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;
/**
* <p>
* Wrapper for {@link GroupRepository} that adds NULL checking and Error
* handling capabilities
* </p>
*/
@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);
}
}
@@ -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);
}
}
@@ -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);
}
}
@@ -20,10 +20,8 @@ import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder; import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException; import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.api.ClientApiConstants; import org.mifosplatform.portfolio.client.api.ClientApiConstants;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants; import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -31,10 +29,6 @@ import org.springframework.stereotype.Component;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
/**
* Implementation of {@link FromApiJsonDeserializer} for {@link ClientCommand}
* 's.
*/
@Component @Component
public final class GroupingTypesDataValidator { public final class GroupingTypesDataValidator {
@@ -48,8 +42,7 @@ public final class GroupingTypesDataValidator {
private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) { private void throwExceptionIfValidationWarningsExist(final List<ApiParameterError> dataValidationErrors) {
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
// //
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", throw new PlatformApiDataValidationException(dataValidationErrors);
dataValidationErrors);
} }
} }
@@ -311,46 +304,24 @@ public final class GroupingTypesDataValidator {
throwExceptionIfValidationWarningsExist(dataValidationErrors); throwExceptionIfValidationWarningsExist(dataValidationErrors);
} }
@Deprecated public void validateForActivation(final JsonCommand command, final String resourceName) {
public void validateForUpdate(final String json) { final String json = command.json();
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); } if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, GroupingTypesApiConstants.ACTIVATION_REQUEST_DATA_PARAMETERS);
/*
* Office updated is not supported
*/
final Set<String> supportedParametersForupdate = new HashSet<String>(Arrays.asList("id", "externalId", "name", "staffId",
"parentId", "clientMembers", "childGroups"));
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParametersForupdate);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
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"; final LocalDate activationDate = fromApiJsonHelper
if (this.fromApiJsonHelper.parameterExists(externalIdParameterName, element)) { .extractLocalDateNamed(GroupingTypesApiConstants.activationDateParamName, element);
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParameterName, element); baseDataValidator.reset().parameter(GroupingTypesApiConstants.activationDateParamName).value(activationDate).notNull();
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
}
final String parentIdParameterName = "parentId"; throwExceptionIfValidationWarningsExist(dataValidationErrors);
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); }
} }
public void validateForUnassignStaff(final String json) { public void validateForUnassignStaff(final String json) {
@@ -371,7 +342,6 @@ public final class GroupingTypesDataValidator {
final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element); final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element);
baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero(); baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
"Validation errors exist.", dataValidationErrors); }
} }
} }
@@ -3,7 +3,10 @@ package org.mifosplatform.portfolio.group.service;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; 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.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.data.GroupGeneralData;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
@@ -20,6 +23,7 @@ public final class AllGroupTypesDataMapper implements RowMapper<GroupGeneralData
sqlBuilder.append("g.office_id as officeId, o.name as officeName, "); sqlBuilder.append("g.office_id as officeId, o.name as officeName, ");
sqlBuilder.append("g.parent_id as centerId, pg.display_name as centerName, "); sqlBuilder.append("g.parent_id as centerId, pg.display_name as centerName, ");
sqlBuilder.append("g.staff_id as staffId, s.display_name as staffName, "); sqlBuilder.append("g.staff_id as staffId, s.display_name as staffName, ");
sqlBuilder.append("g.status_enum as statusEnum, g.activation_date as activationDate, ");
sqlBuilder.append("g.hierarchy as hierarchy "); sqlBuilder.append("g.hierarchy as hierarchy ");
sqlBuilder.append("from m_group g "); sqlBuilder.append("from m_group g ");
sqlBuilder.append("join m_office o on o.id = g.office_id "); sqlBuilder.append("join m_office o on o.id = g.office_id ");
@@ -39,6 +43,11 @@ public final class AllGroupTypesDataMapper implements RowMapper<GroupGeneralData
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String name = rs.getString("displayName"); final String name = rs.getString("displayName");
final String externalId = rs.getString("externalId"); 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 = JdbcSupport.getLong(rs, "officeId"); final Long officeId = JdbcSupport.getLong(rs, "officeId");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
final Long centerId = JdbcSupport.getLong(rs, "centerId"); final Long centerId = JdbcSupport.getLong(rs, "centerId");
@@ -47,6 +56,7 @@ public final class AllGroupTypesDataMapper implements RowMapper<GroupGeneralData
final String staffName = rs.getString("staffName"); final String staffName = rs.getString("staffName");
final String hierarchy = rs.getString("hierarchy"); final String hierarchy = rs.getString("hierarchy");
return GroupGeneralData.instance(id, name, externalId, officeId, officeName, centerId, centerName, staffId, staffName, hierarchy); return GroupGeneralData.instance(id, name, externalId, status, activationDate, officeId, officeName, centerId, centerName, staffId,
staffName, hierarchy);
} }
} }
@@ -12,7 +12,6 @@ import java.util.Collection;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.configuration.domain.ConfigurationDomainService;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.data.EnumOptionData; import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
@@ -23,6 +22,7 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientData; 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.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.group.data.CenterData; import org.mifosplatform.portfolio.group.data.CenterData;
import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.data.GroupGeneralData;
@@ -45,7 +45,6 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService;
private final StaffReadPlatformService staffReadPlatformService; private final StaffReadPlatformService staffReadPlatformService;
private final ConfigurationDomainService configurationDomainService;
// data mappers // data mappers
private final AllGroupTypesDataMapper allGroupTypesDataMapper = new AllGroupTypesDataMapper(); private final AllGroupTypesDataMapper allGroupTypesDataMapper = new AllGroupTypesDataMapper();
@@ -56,10 +55,9 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
@Autowired @Autowired
public CenterReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public CenterReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
final ConfigurationDomainService configurationDomainService, final ClientReadPlatformService clientReadPlatformService, final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
final OfficeReadPlatformService officeReadPlatformService, final StaffReadPlatformService staffReadPlatformService) { final StaffReadPlatformService staffReadPlatformService) {
this.context = context; this.context = context;
this.configurationDomainService = configurationDomainService;
this.clientReadPlatformService = clientReadPlatformService; this.clientReadPlatformService = clientReadPlatformService;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.officeReadPlatformService = officeReadPlatformService; this.officeReadPlatformService = officeReadPlatformService;
@@ -113,8 +111,7 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
+ "g.status_enum as statusEnum, g.activation_date as activationDate, " // + "g.status_enum as statusEnum, g.activation_date as activationDate, " //
+ "g.hierarchy as hierarchy " // + "g.hierarchy as hierarchy " //
+ "from m_group g " // + "from m_group g " //
+ "join m_office o on o.id = g.office_id " + "join m_office o on o.id = g.office_id " + "left join m_staff s on s.id = g.staff_id ";
+ "left join m_staff s on s.id = g.staff_id ";
private static final class CenterDataMapper implements RowMapper<CenterData> { private static final class CenterDataMapper implements RowMapper<CenterData> {
@@ -167,13 +164,19 @@ public class CenterReadPlatformServiceImpl implements CenterReadPlatformService
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String name = rs.getString("name"); final String name = rs.getString("name");
final String externalId = rs.getString("externalId"); 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 Long officeId = rs.getLong("officeId");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
final Long staffId = JdbcSupport.getLong(rs, "staffId"); final Long staffId = JdbcSupport.getLong(rs, "staffId");
final String staffName = rs.getString("staffName"); final String staffName = rs.getString("staffName");
final String hierarchy = rs.getString("hierarchy"); 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);
} }
} }
@@ -16,6 +16,8 @@ public interface GroupingTypesWritePlatformService {
CommandProcessingResult createGroup(Long centerId, JsonCommand command); CommandProcessingResult createGroup(Long centerId, JsonCommand command);
CommandProcessingResult activateGroupOrCenter(Long entityId, JsonCommand command);
CommandProcessingResult updateGroup(Long groupId, JsonCommand command); CommandProcessingResult updateGroup(Long groupId, JsonCommand command);
CommandProcessingResult deleteGroup(Long groupId); CommandProcessingResult deleteGroup(Long groupId);
@@ -6,14 +6,15 @@
package org.mifosplatform.portfolio.group.service; package org.mifosplatform.portfolio.group.service;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; 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.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -24,20 +25,17 @@ import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.InvalidOfficeException; import org.mifosplatform.organisation.office.exception.InvalidOfficeException;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.staff.domain.StaffRepository; import org.mifosplatform.organisation.staff.domain.StaffRepositoryWrapper;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.domain.Client; 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.api.GroupingTypesApiConstants; import org.mifosplatform.portfolio.group.api.GroupingTypesApiConstants;
import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupLevel; import org.mifosplatform.portfolio.group.domain.GroupLevel;
import org.mifosplatform.portfolio.group.domain.GroupLevelRepository; 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.domain.GroupTypes;
import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException; import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException;
import org.mifosplatform.portfolio.group.exception.GroupMustBePendingToBeDeletedException; 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.exception.InvalidGroupLevelException;
import org.mifosplatform.portfolio.group.serialization.GroupingTypesDataValidator; import org.mifosplatform.portfolio.group.serialization.GroupingTypesDataValidator;
import org.mifosplatform.portfolio.note.domain.Note; 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.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import com.google.common.collect.Sets;
@Service @Service
public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements GroupingTypesWritePlatformService { public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements GroupingTypesWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(GroupingTypesWritePlatformServiceJpaRepositoryImpl.class); private final static Logger logger = LoggerFactory.getLogger(GroupingTypesWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final GroupRepository groupRepository; private final GroupRepositoryWrapper groupRepository;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final OfficeRepository officeRepository; private final OfficeRepository officeRepository;
private final StaffRepository staffRepository; private final StaffRepositoryWrapper staffRepository;
private final NoteRepository noteRepository; private final NoteRepository noteRepository;
private final GroupLevelRepository groupLevelRepository; private final GroupLevelRepository groupLevelRepository;
private final GroupingTypesDataValidator fromApiJsonDeserializer; private final GroupingTypesDataValidator fromApiJsonDeserializer;
@Autowired @Autowired
public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepository groupRepository, public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository, final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepository,
final NoteRepository noteRepository, final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository,
final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer) { final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer) {
this.context = context; this.context = context;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
@@ -92,9 +88,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
if (centerId == null) { if (centerId == null) {
officeId = command.longValueOfParameterNamed(GroupingTypesApiConstants.officeIdParamName); officeId = command.longValueOfParameterNamed(GroupingTypesApiConstants.officeIdParamName);
} else { } else {
parentGroup = this.groupRepository.findOne(centerId); parentGroup = this.groupRepository.findOneWithNotFoundDetection(centerId);
if (parentGroup == null) { throw new GroupNotFoundException(centerId); } officeId = parentGroup.officeId();
officeId = parentGroup.getOfficeId();
} }
final Office groupOffice = this.officeRepository.findOne(officeId); final Office groupOffice = this.officeRepository.findOne(officeId);
@@ -103,8 +98,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
Staff staff = null; Staff staff = null;
final Long staffId = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); final Long staffId = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName);
if (staffId != null) { if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, officeId); staff = this.staffRepository.findByOfficeWithNotFoundDetection(staffId, officeId);
if (staff == null) { throw new StaffNotFoundException(staffId); }
} }
final Set<Client> clientMembers = assembleSetOfClients(officeId, command); final Set<Client> clientMembers = assembleSetOfClients(officeId, command);
@@ -160,6 +154,35 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
return createGroupingType(command, GroupTypes.GROUP, centerId); 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 @Transactional
@Override @Override
public CommandProcessingResult updateCenter(final Long centerId, final JsonCommand command) { 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) { private CommandProcessingResult updateGroupingType(final Long groupId, final JsonCommand command, final GroupTypes groupingType) {
try { try {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9); final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(groupId);
final Long officeId = groupForUpdate.officeId();
final Group groupForUpdate = this.groupRepository.findOne(groupId); final Map<String, Object> actualChanges = groupForUpdate.update(command);
if (groupForUpdate == null) { throw new GroupNotFoundException(groupId); }
final Long officeId = groupForUpdate.getOfficeId(); if (actualChanges.containsKey(GroupingTypesApiConstants.staffIdParamName)) {
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)) {
final Long newValue = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName); final Long newValue = command.longValueOfParameterNamed(GroupingTypesApiConstants.staffIdParamName);
actualChanges.put(GroupingTypesApiConstants.staffIdParamName, newValue);
Staff newStaff = null; Staff newStaff = null;
if (newValue != null) { if (newValue != null) {
newStaff = this.staffRepository.findByOffice(newValue, officeId); newStaff = this.staffRepository.findByOfficeWithNotFoundDetection(newValue, officeId);
if (newStaff == null) { throw new StaffNotFoundException(newValue); }
} }
groupForUpdate.setStaff(newStaff); groupForUpdate.updateStaff(newStaff);
} }
GroupLevel groupLevel = this.groupLevelRepository.findOne(groupForUpdate.getGroupLevel().getId()); GroupLevel groupLevel = this.groupLevelRepository.findOne(groupForUpdate.getGroupLevel().getId());
@@ -240,8 +241,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
actualChanges.put(GroupingTypesApiConstants.centerIdParamName, newValue); actualChanges.put(GroupingTypesApiConstants.centerIdParamName, newValue);
Group newParentGroup = null; Group newParentGroup = null;
if (newValue != null) { if (newValue != null) {
newParentGroup = this.groupRepository.findOne(newValue); newParentGroup = this.groupRepository.findOneWithNotFoundDetection(newValue);
if (newParentGroup == null) { throw new StaffNotFoundException(newValue); }
if (!newParentGroup.isOfficeIdentifiedBy(officeId)) { if (!newParentGroup.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and parent group must have the same office"; final String errorMessage = "Group and parent group must have the same office";
@@ -270,19 +270,16 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
} }
final Set<Client> clientMembers = assembleSetOfClients(officeId, command); final Set<Client> clientMembers = assembleSetOfClients(officeId, command);
List<String> changes = groupForUpdate.updateClientMembersIfDifferent(clientMembers);
if (!clientMembers.equals(groupForUpdate.getClientMembers())) { if (!changes.isEmpty()) {
Set<Client> diffClients = Sets.symmetricDifference(clientMembers, groupForUpdate.getClientMembers()); actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, changes);
final String[] diffClientsIds = getClientIds(diffClients);
actualChanges.put(GroupingTypesApiConstants.clientMembersParamName, diffClientsIds);
groupForUpdate.setClientMembers(clientMembers);
} }
this.groupRepository.saveAndFlush(groupForUpdate); this.groupRepository.saveAndFlush(groupForUpdate);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withOfficeId(groupForUpdate.getId()) // .withOfficeId(groupForUpdate.officeId()) //
.withGroupId(groupForUpdate.getId()) // .withGroupId(groupForUpdate.getId()) //
.withEntityId(groupForUpdate.getId()) // .withEntityId(groupForUpdate.getId()) //
.with(actualChanges) // .with(actualChanges) //
@@ -304,8 +301,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
this.fromApiJsonDeserializer.validateForUnassignStaff(command.json()); this.fromApiJsonDeserializer.validateForUnassignStaff(command.json());
final Group groupForUpdate = this.groupRepository.findOne(grouptId); final Group groupForUpdate = this.groupRepository.findOneWithNotFoundDetection(grouptId);
if (groupForUpdate == null) { throw new GroupNotFoundException(grouptId); }
final Staff presentStaff = groupForUpdate.getStaff(); final Staff presentStaff = groupForUpdate.getStaff();
Long presentStaffId = null; Long presentStaffId = null;
@@ -313,7 +309,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
presentStaffId = presentStaff.getId(); presentStaffId = presentStaff.getId();
final String staffIdParamName = "staffId"; final String staffIdParamName = "staffId";
if (!command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) { if (!command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) {
groupForUpdate.unassigStaff(); groupForUpdate.unassignStaff();
} }
this.groupRepository.saveAndFlush(groupForUpdate); this.groupRepository.saveAndFlush(groupForUpdate);
@@ -322,7 +318,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withOfficeId(groupForUpdate.getId()) // .withOfficeId(groupForUpdate.getId()) //
.withGroupId(groupForUpdate.getOfficeId()) // .withGroupId(groupForUpdate.officeId()) //
.withEntityId(groupForUpdate.getId()) // .withEntityId(groupForUpdate.getId()) //
.with(actualChanges) // .with(actualChanges) //
.build(); .build();
@@ -333,19 +329,18 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
@Override @Override
public CommandProcessingResult deleteGroup(final Long groupId) { public CommandProcessingResult deleteGroup(final Long groupId) {
final Group groupForDelete = this.groupRepository.findOne(groupId); final Group groupForDelete = this.groupRepository.findOneWithNotFoundDetection(groupId);
if (groupForDelete == null) { throw new GroupNotFoundException(groupId); }
if (groupForDelete.isNotPending()) { throw new GroupMustBePendingToBeDeletedException(groupId); } if (groupForDelete.isNotPending()) { throw new GroupMustBePendingToBeDeletedException(groupId); }
final List<Note> relatedNotes = this.noteRepository.findByGroupId(groupId); final List<Note> relatedNotes = this.noteRepository.findByGroupId(groupId);
this.noteRepository.deleteInBatch(relatedNotes); this.noteRepository.deleteInBatch(relatedNotes);
this.groupRepository.delete(groupId); this.groupRepository.delete(groupForDelete);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withOfficeId(groupForDelete.getId()) // .withOfficeId(groupForDelete.getId()) //
.withGroupId(groupForDelete.getOfficeId()) // .withGroupId(groupForDelete.officeId()) //
.withEntityId(groupForDelete.getId()) // .withEntityId(groupForDelete.getId()) //
.build(); .build();
} }
@@ -358,8 +353,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
if (!ObjectUtils.isEmpty(clientMembersArray)) { if (!ObjectUtils.isEmpty(clientMembersArray)) {
for (final String clientId : clientMembersArray) { for (final String clientId : clientMembersArray) {
final Long id = Long.valueOf(clientId); final Long id = Long.valueOf(clientId);
final Client client = this.clientRepository.findOne(id); final Client client = this.clientRepository.findOneWithNotFoundDetection(id);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); }
if (!client.isOfficeIdentifiedBy(officeId)) { if (!client.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and Client must have the same office."; final String errorMessage = "Group and Client must have the same office.";
throw new InvalidOfficeException("client", "attach.to.group", errorMessage); throw new InvalidOfficeException("client", "attach.to.group", errorMessage);
@@ -379,8 +373,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
if (!ObjectUtils.isEmpty(childGroupsArray)) { if (!ObjectUtils.isEmpty(childGroupsArray)) {
for (final String groupId : childGroupsArray) { for (final String groupId : childGroupsArray) {
final Long id = Long.valueOf(groupId); final Long id = Long.valueOf(groupId);
final Group group = this.groupRepository.findOne(id); final Group group = this.groupRepository.findOneWithNotFoundDetection(id);
if (group == null) { throw new GroupNotFoundException(id); }
if (!group.isOfficeIdentifiedBy(officeId)) { if (!group.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and child groups must have the same office."; final String errorMessage = "Group and child groups must have the same office.";
throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage); throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage);
@@ -392,16 +386,6 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
return childGroups; return childGroups;
} }
private String[] getClientIds(final Set<Client> clients) {
String[] clientIds = new String[clients.size()];
Iterator<Client> 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 * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
@@ -32,8 +32,7 @@ import org.mifosplatform.portfolio.calendar.service.CalendarHelper;
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.Client; 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.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral;
import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler;
import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.fund.domain.Fund;
@@ -82,7 +81,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private final NoteRepository noteRepository; private final NoteRepository noteRepository;
private final LoanScheduleCalculationPlatformService calculationPlatformService; private final LoanScheduleCalculationPlatformService calculationPlatformService;
private final LoanAssembler loanAssembler; private final LoanAssembler loanAssembler;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final LoanProductRepository loanProductRepository; private final LoanProductRepository loanProductRepository;
private final LoanChargeAssembler loanChargeAssembler; private final LoanChargeAssembler loanChargeAssembler;
private final CollateralAssembler loanCollateralAssembler; private final CollateralAssembler loanCollateralAssembler;
@@ -99,12 +98,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer, final AprCalculator aprCalculator, final LoanApplicationCommandFromApiJsonHelper fromApiJsonDeserializer, final AprCalculator aprCalculator,
final LoanAssembler loanAssembler, final LoanChargeAssembler loanChargeAssembler, final LoanAssembler loanAssembler, final LoanChargeAssembler loanChargeAssembler,
final CollateralAssembler loanCollateralAssembler, final LoanRepository loanRepository, final NoteRepository noteRepository, 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 LoanProductRepository loanProductRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final LoanSummaryWrapper loanSummaryWrapper, final LoanSummaryWrapper loanSummaryWrapper,
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) { final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository) {
this.context = context; this.context = context;
this.fromJsonHelper = fromJsonHelper; this.fromJsonHelper = fromJsonHelper;
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
@@ -136,19 +135,19 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
AppUser currentUser = context.authenticatedUser(); AppUser currentUser = context.authenticatedUser();
final Long productId = fromJsonHelper.extractLongNamed("productId", command.parsedJson()); final Long productId = fromJsonHelper.extractLongNamed("productId", command.parsedJson());
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
this.fromApiJsonDeserializer.validateForCreate(command.json(), loanProduct); this.fromApiJsonDeserializer.validateForCreate(command.json(), loanProduct);
//validate dates against calendar recurring dates // validate dates against calendar recurring dates
//get calendar // get calendar
final Long calendarId = command.longValueOfParameterNamed("calendarId"); final Long calendarId = command.longValueOfParameterNamed("calendarId");
Calendar calendar = null; Calendar calendar = null;
if(calendarId != null && calendarId != 0){ if (calendarId != null && calendarId != 0) {
calendar = this.calendarRepository.findOne(calendarId); calendar = this.calendarRepository.findOne(calendarId);
if(calendar == null) { throw new CalendarNotFoundException(calendarId); } if (calendar == null) { throw new CalendarNotFoundException(calendarId); }
validateCalendarDates(command, calendar); validateCalendarDates(command, calendar);
} }
@@ -169,9 +168,10 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.noteRepository.save(note); this.noteRepository.save(note);
} }
//Save calendar instance // Save calendar instance
if(calendar != null){ if (calendar != null) {
CalendarInstance calendarInstance = new CalendarInstance(calendar, newLoanApplication.getId(), CalendarEntityType.LOANS.getValue()); CalendarInstance calendarInstance = new CalendarInstance(calendar, newLoanApplication.getId(),
CalendarEntityType.LOANS.getValue());
this.calendarInstanceRepository.save(calendarInstance); this.calendarInstanceRepository.save(calendarInstance);
} }
@@ -196,12 +196,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final Long calendarId = command.longValueOfParameterNamed("calendarId"); final Long calendarId = command.longValueOfParameterNamed("calendarId");
Calendar calendar = null; Calendar calendar = null;
if(calendarId != null && calendarId != 0){ if (calendarId != null && calendarId != 0) {
calendar = this.calendarRepository.findOne(calendarId); calendar = this.calendarRepository.findOne(calendarId);
if(calendar == null) { throw new CalendarNotFoundException(calendarId); } if (calendar == null) { throw new CalendarNotFoundException(calendarId); }
validateCalendarDates(command, calendar); validateCalendarDates(command, calendar);
} }
final Loan existingLoanApplication = retrieveLoanBy(loanId); final Loan existingLoanApplication = retrieveLoanBy(loanId);
if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified( if (!existingLoanApplication.isSubmittedAndPendingApproval()) { throw new LoanApplicationNotInSubmittedAndPendingApprovalStateCannotBeModified(
@@ -217,8 +217,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final String clientIdParamName = "clientId"; final String clientIdParamName = "clientId";
if (changes.containsKey(clientIdParamName)) { if (changes.containsKey(clientIdParamName)) {
final Long clientId = command.longValueOfParameterNamed(clientIdParamName); final Long clientId = command.longValueOfParameterNamed(clientIdParamName);
final Client client = this.clientRepository.findOne(clientId); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
existingLoanApplication.updateClient(client); existingLoanApplication.updateClient(client);
} }
@@ -231,8 +230,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
existingLoanApplication.updateLoanProduct(loanProduct); existingLoanApplication.updateLoanProduct(loanProduct);
} }
//validate min and maximum constraints // validate min and maximum constraints
this.fromApiJsonDeserializer.validateMinMaxConstraintsForModification(command.json(), existingLoanApplication.loanProduct()); this.fromApiJsonDeserializer.validateMinMaxConstraintsForModification(command.json(), existingLoanApplication.loanProduct());
final String fundIdParamName = "fundId"; final String fundIdParamName = "fundId";
@@ -295,19 +294,21 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.noteRepository.save(note); this.noteRepository.save(note);
} }
List<CalendarInstance> ciList = (List<CalendarInstance>) this.calendarInstanceRepository.findByEntityIdAndEntityTypeId(loanId, CalendarEntityType.LOANS.getValue()); List<CalendarInstance> ciList = (List<CalendarInstance>) this.calendarInstanceRepository.findByEntityIdAndEntityTypeId(loanId,
if(calendar != null){ CalendarEntityType.LOANS.getValue());
if (calendar != null) {
//For loans, allow to attach only one calendar instance per loan
if(ciList != null && !ciList.isEmpty()){ // For loans, allow to attach only one calendar instance per
// loan
if (ciList != null && !ciList.isEmpty()) {
CalendarInstance calendarInstance = ciList.get(0); CalendarInstance calendarInstance = ciList.get(0);
if(calendarInstance.getCalendar().getId() != calendar.getId()){ if (calendarInstance.getCalendar().getId() != calendar.getId()) {
calendarInstance.updateCalendar(calendar); calendarInstance.updateCalendar(calendar);
this.calendarInstanceRepository.saveAndFlush(calendarInstance); this.calendarInstanceRepository.saveAndFlush(calendarInstance);
} }
} }
}else if(ciList != null && !ciList.isEmpty()){ } else if (ciList != null && !ciList.isEmpty()) {
CalendarInstance calendarInstance = ciList.get(0); CalendarInstance calendarInstance = ciList.get(0);
this.calendarInstanceRepository.delete(calendarInstance); this.calendarInstanceRepository.delete(calendarInstance);
} }
@@ -512,7 +513,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
loan.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper, this.loanRepaymentScheduleTransactionProcessorFactory); loan.setHelpers(defaultLoanLifecycleStateMachine(), this.loanSummaryWrapper, this.loanRepaymentScheduleTransactionProcessorFactory);
return loan; return loan;
} }
private void validateCalendarDates(final JsonCommand command, final Calendar calendar) { private void validateCalendarDates(final JsonCommand command, final Calendar calendar) {
// Validate disbursement date and first repayment dates matches calendar // Validate disbursement date and first repayment dates matches calendar
@@ -20,8 +20,7 @@ import org.mifosplatform.organisation.staff.domain.StaffRepository;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.organisation.staff.exception.StaffRoleException; import org.mifosplatform.organisation.staff.exception.StaffRoleException;
import org.mifosplatform.portfolio.client.domain.Client; 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.collateral.domain.LoanCollateral; import org.mifosplatform.portfolio.collateral.domain.LoanCollateral;
import org.mifosplatform.portfolio.collateral.service.CollateralAssembler; import org.mifosplatform.portfolio.collateral.service.CollateralAssembler;
import org.mifosplatform.portfolio.fund.domain.Fund; import org.mifosplatform.portfolio.fund.domain.Fund;
@@ -56,7 +55,7 @@ import com.google.gson.JsonElement;
public class LoanAssembler { public class LoanAssembler {
private final LoanProductRepository loanProductRepository; private final LoanProductRepository loanProductRepository;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final FundRepository fundRepository; private final FundRepository fundRepository;
private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository; private final LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository;
@@ -71,7 +70,7 @@ public class LoanAssembler {
@Autowired @Autowired
public LoanAssembler(final FromJsonHelper fromApiJsonHelper, final LoanProductRepository loanProductRepository, 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 LoanTransactionProcessingStrategyRepository loanTransactionProcessingStrategyRepository,
final StaffRepository staffRepository, final CodeValueRepositoryWrapper codeValueRepository, final StaffRepository staffRepository, final CodeValueRepositoryWrapper codeValueRepository,
final LoanScheduleAssembler loanScheduleAssembler, final LoanChargeAssembler loanChargeAssembler, final LoanScheduleAssembler loanScheduleAssembler, final LoanChargeAssembler loanChargeAssembler,
@@ -112,7 +111,7 @@ public class LoanAssembler {
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
final Fund fund = findFundByIdIfProvided(fundId); final Fund fund = findFundByIdIfProvided(fundId);
final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId); final Staff loanOfficer = findLoanOfficerByIdIfProvided(loanOfficerId);
final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(transactionProcessingStrategyId); final LoanTransactionProcessingStrategy loanTransactionProcessingStrategy = findStrategyByIdIfProvided(transactionProcessingStrategyId);
@@ -130,8 +129,7 @@ public class LoanAssembler {
Client client = null; Client client = null;
Group group = null; Group group = null;
if (clientId != null) { if (clientId != null) {
client = this.clientRepository.findOne(clientId); client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanPurpose, loanApplication = Loan.newIndividualLoanApplication(accountNo, client, loanProduct, fund, loanOfficer, loanPurpose,
loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral); loanTransactionProcessingStrategy, loanSchedule, loanCharges, collateral);
@@ -121,9 +121,7 @@ public class LoanChargeReadPlatformServiceImpl implements LoanChargeReadPlatform
final LoanChargeMapper rm = new LoanChargeMapper(); final LoanChargeMapper rm = new LoanChargeMapper();
// TODO - KW - check to see if its important that 'c.is_deleted=0' is final String sql = "select " + rm.schema() + " where lc.loan_id=? "
// required here?
final String sql = "select " + rm.schema() + " where c.is_deleted=0 and lc.loan_id=? "
+ " order by lc.charge_time_enum ASC, lc.due_for_collection_as_of_date ASC, lc.is_penalty ASC"; + " 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 }); return this.jdbcTemplate.query(sql, rm, new Object[] { loanId });
@@ -25,6 +25,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.portfolio.client.data.ClientData; 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.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.data.GroupGeneralData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
@@ -185,12 +186,12 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
context.authenticatedUser(); context.authenticatedUser();
GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId); GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId);
//get group associations // get group associations
Collection<ClientData> membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId); Collection<ClientData> membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId);
if (!CollectionUtils.isEmpty(membersOfGroup)) { if (!CollectionUtils.isEmpty(membersOfGroup)) {
groupAccount = GroupGeneralData.withAssocations(groupAccount, membersOfGroup); groupAccount = GroupGeneralData.withAssocations(groupAccount, membersOfGroup);
} }
final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant(); final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant();
LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate); 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," + " l.loanpurpose_cv_id as loanPurposeId, cv.code_value as loanPurposeName,"
+ " lp.id as loanProductId, lp.name as loanProductName, lp.description as loanProductDescription," + " 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," + " 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.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.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," + " 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; GroupGeneralData groupData = null;
if (groupId != null) { if (groupId != null) {
groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupOfficeId, null, groupParentId, null, final Integer groupStatusEnum = JdbcSupport.getInteger(rs, "statusEnum");
groupStaffId, null, groupHierarchy); 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, return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData,
@@ -11,7 +11,7 @@ import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.portfolio.client.domain.Client; 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.client.exception.ClientNotFoundException;
import org.mifosplatform.portfolio.group.domain.Group; import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.domain.GroupRepository;
@@ -35,7 +35,7 @@ import org.springframework.stereotype.Service;
public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService { public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatformService {
private final NoteRepository noteRepository; private final NoteRepository noteRepository;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
// private final SavingAccountRepository savingAccountRepository; // private final SavingAccountRepository savingAccountRepository;
private final LoanRepository loanRepository; private final LoanRepository loanRepository;
@@ -43,15 +43,12 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired @Autowired
public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepository clientRepository, public NoteWritePlatformServiceJpaRepositoryImpl(final NoteRepository noteRepository, final ClientRepositoryWrapper clientRepository,
final GroupRepository groupRepository, final GroupRepository groupRepository, final LoanRepository loanRepository,
// final SavingAccountRepository savingAccountRepository, final LoanTransactionRepository loanTransactionRepository, final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
final LoanRepository loanRepository, final LoanTransactionRepository loanTransactionRepository,
final NoteCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.noteRepository = noteRepository; this.noteRepository = noteRepository;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
// this.savingAccountRepository = savingAccountRepository;
this.loanRepository = loanRepository; this.loanRepository = loanRepository;
this.loanTransactionRepository = loanTransactionRepository; this.loanTransactionRepository = loanTransactionRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
@@ -61,7 +58,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
final Long resourceId = command.getSupportedEntityId(); 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); } if (client == null) { throw new ClientNotFoundException(resourceId); }
final Note newNote = Note.clientNoteFromJson(client, command); final Note newNote = Note.clientNoteFromJson(client, command);
@@ -87,7 +84,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(newNote.getId()) // .withEntityId(newNote.getId()) //
.withClientId(group.getId()).withOfficeId(group.getOfficeId()).build(); .withClientId(group.getId()) //
.withOfficeId(group.officeId()) //
.build();
} }
private CommandProcessingResult createLoanNote(final JsonCommand command) { private CommandProcessingResult createLoanNote(final JsonCommand command) {
@@ -105,12 +104,10 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(newNote.getId()) // .withEntityId(newNote.getId()) //
.withClientId(loan.getClientId()).withOfficeId(loan.getOfficeId()).withLoanId(loan.getId()).withGroupId(loan.getGroupId())// Loan .withClientId(loan.getClientId()) //
// can .withOfficeId(loan.getOfficeId()) //
// be .withLoanId(loan.getId()) //
// associated .withGroupId(loan.getGroupId()) //
// to
// group
.build(); .build();
} }
@@ -196,8 +193,7 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
final NoteType type = NoteType.fromApiUrl(resourceUrl); final NoteType type = NoteType.fromApiUrl(resourceUrl);
final Client client = this.clientRepository.findOne(resourceId); final Client client = this.clientRepository.findOneWithNotFoundDetection(resourceId);
if (client == null) { throw new ClientNotFoundException(resourceId); }
final Note noteForUpdate = this.noteRepository.findByClientIdAndId(resourceId, noteId); final Note noteForUpdate = this.noteRepository.findByClientIdAndId(resourceId, noteId);
if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); } if (noteForUpdate == null) { throw new NoteNotFoundException(noteId, resourceId, type.name().toLowerCase()); }
@@ -238,7 +234,9 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
.withEntityId(noteForUpdate.getId()) // .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) { private CommandProcessingResult updateLoanNote(final JsonCommand command) {
@@ -393,11 +391,12 @@ public class NoteWritePlatformServiceJpaRepositoryImpl implements NoteWritePlatf
noteForUpdate = this.noteRepository.findByLoanTransactionIdAndId(resourceId, noteId); noteForUpdate = this.noteRepository.findByLoanTransactionIdAndId(resourceId, noteId);
} }
break; break;
// case SAVING_ACCOUNT: { // case SAVING_ACCOUNT: {
// noteForUpdate = // noteForUpdate =
// this.noteRepository.findBySavingAccountIdAndId(resourceId, noteId); // this.noteRepository.findBySavingAccountIdAndId(resourceId,
// } // noteId);
// break; // }
// break;
case SAVING_ACCOUNT: case SAVING_ACCOUNT:
break; break;
} }
@@ -25,8 +25,7 @@ import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.domain.Client; 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.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
@@ -40,14 +39,14 @@ import com.google.gson.JsonElement;
public class SavingsAccountAssembler { public class SavingsAccountAssembler {
private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper; private final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final SavingsProductRepository savingProductRepository; private final SavingsProductRepository savingProductRepository;
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@Autowired @Autowired
public SavingsAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper, public SavingsAccountAssembler(final SavingsAccountTransactionSummaryWrapper savingsAccountTransactionSummaryWrapper,
final ClientRepository clientRepository, final GroupRepository groupRepository, final ClientRepositoryWrapper clientRepository, final GroupRepository groupRepository,
final SavingsProductRepository savingProductRepository, final FromJsonHelper fromApiJsonHelper) { final SavingsProductRepository savingProductRepository, final FromJsonHelper fromApiJsonHelper) {
this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper; this.savingsAccountTransactionSummaryWrapper = savingsAccountTransactionSummaryWrapper;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
@@ -78,8 +77,7 @@ public class SavingsAccountAssembler {
Client client = null; Client client = null;
Group group = null; Group group = null;
if (clientId != null) { if (clientId != null) {
client = this.clientRepository.findOne(clientId); client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
} }
if (groupId != null) { if (groupId != null) {
@@ -22,8 +22,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator; import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory; import org.mifosplatform.portfolio.client.domain.AccountNumberGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.Client; 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.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository; import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
@@ -57,7 +56,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
private final SavingsAccountDataValidator savingsAccountDataValidator; private final SavingsAccountDataValidator savingsAccountDataValidator;
private final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator; private final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
private final ClientRepository clientRepository; private final ClientRepositoryWrapper clientRepository;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final SavingsProductRepository savingsProductRepository; private final SavingsProductRepository savingsProductRepository;
@@ -67,7 +66,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final SavingsAccountTransactionRepository savingsAccountTransactionRepository, final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
final SavingsAccountAssembler savingAccountAssembler, final SavingsAccountDataValidator savingsAccountDataValidator, final SavingsAccountAssembler savingAccountAssembler, final SavingsAccountDataValidator savingsAccountDataValidator,
final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator, final SavingsAccountTransactionDataValidator savingsAccountTransactionDataValidator,
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepository clientRepository, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final ClientRepositoryWrapper clientRepository,
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) { final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository) {
this.context = context; this.context = context;
this.savingAccountRepository = savingAccountRepository; this.savingAccountRepository = savingAccountRepository;
@@ -160,8 +159,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (changes.containsKey(SavingsApiConstants.clientIdParamName)) { if (changes.containsKey(SavingsApiConstants.clientIdParamName)) {
final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName); final Long clientId = command.longValueOfParameterNamed(SavingsApiConstants.clientIdParamName);
if (clientId != null) { if (clientId != null) {
final Client client = this.clientRepository.findOne(clientId); final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
account.update(client); account.update(client);
} else { } else {
final Client client = null; final Client client = null;