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