MIFOSX-37: support ability to use different account number generation strategies for client account numbers (programatically for now, from ui,configuration later)

This commit is contained in:
Keith Woodlock
2013-01-10 17:01:53 +00:00
parent 7db9d409eb
commit 4cac334d71
13 changed files with 438 additions and 353 deletions
@@ -0,0 +1,15 @@
ALTER TABLE `m_client`
ADD COLUMN `middlename` VARCHAR(50) DEFAULT NULL AFTER `firstname`;
ALTER TABLE `m_client`
ADD COLUMN `fullname` VARCHAR(100) DEFAULT NULL AFTER `lastname`;
UPDATE `m_client`
SET
`fullname` = `lastname`
WHERE `firstname` is NULL;
UPDATE `m_client`
SET
`lastname` = null
WHERE `fullname` is not NULL;
@@ -67,7 +67,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(json); final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(json);
return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(), return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(),
command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate()); command.getMiddlename(), command.getLastname(), command.getFullname(), command.getJoiningDate());
} }
@Override @Override
@@ -47,7 +47,7 @@ import org.springframework.stereotype.Component;
@Scope("singleton") @Scope("singleton")
public class ClientsApiResource { public class ClientsApiResource {
private final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "officeName", "externalId", private final Set<String> CLIENT_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "accountNo", "officeId", "officeName", "externalId",
"firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "allowedOffices", "imagePresent")); "firstname", "lastname", "joinedDate", "displayName", "clientOrBusinessName", "allowedOffices", "imagePresent"));
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
@@ -1,84 +1,31 @@
package org.mifosplatform.portfolio.client.command; package org.mifosplatform.portfolio.client.command;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
/**
*
*/
public class ClientCommand { public class ClientCommand {
@SuppressWarnings("unused")
private final String accountNo;
private final String externalId; private final String externalId;
private final String firstname; private final String firstname;
private final String middlename;
private final String lastname; private final String lastname;
private final String clientOrBusinessName; private final String fullname;
private final Long officeId; private final Long officeId;
private final LocalDate joinedDate; private final LocalDate joinedDate;
public ClientCommand(final String externalId, final String firstname, final String lastname, final String clientOrBusinessName, public ClientCommand(final String accountNo, final String externalId, final String firstname, final String middlename,
final Long officeId, final LocalDate joinedDate) { final String lastname, final String fullname, final Long officeId, final LocalDate joinedDate) {
this.accountNo = accountNo;
this.externalId = externalId; this.externalId = externalId;
this.firstname = firstname; this.firstname = firstname;
this.middlename = middlename;
this.lastname = lastname; this.lastname = lastname;
this.clientOrBusinessName = clientOrBusinessName; this.fullname = fullname;
this.officeId = officeId; this.officeId = officeId;
this.joinedDate = joinedDate; this.joinedDate = joinedDate;
} }
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (StringUtils.isNotBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
baseDataValidator.reset().parameter("lastname").value(this.lastname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
} else {
baseDataValidator.reset().parameter("firstname").value(this.firstname).notBlank();
baseDataValidator.reset().parameter("lastname").value(this.lastname).notBlank();
}
baseDataValidator.reset().parameter("joinedDate").value(this.joinedDate).notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).notExceedingLengthOf(100);
baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (this.clientOrBusinessName != null && StringUtils.isNotBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
baseDataValidator.reset().parameter("lastname").value(this.lastname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
} else if (StringUtils.isBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank();
}
baseDataValidator.reset().parameter("joinedDate").value(this.joinedDate).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().anyOfNotNull(this.firstname, this.lastname, this.clientOrBusinessName, this.joinedDate, this.externalId,
this.officeId);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public String getExternalId() { public String getExternalId() {
return this.externalId; return this.externalId;
} }
@@ -87,12 +34,16 @@ public class ClientCommand {
return this.firstname; return this.firstname;
} }
public String getMiddlename() {
return this.middlename;
}
public String getLastname() { public String getLastname() {
return this.lastname; return this.lastname;
} }
public String getClientOrBusinessName() { public String getFullname() {
return this.clientOrBusinessName; return this.fullname;
} }
public Long getOfficeId() { public Long getOfficeId() {
@@ -14,13 +14,14 @@ final public class ClientData {
private final Long id; private final Long id;
private final String accountNo; private final String accountNo;
private final String externalId;
private final String firstname; private final String firstname;
private final String middlename;
private final String lastname; private final String lastname;
private final String clientOrBusinessName; private final String fullname;
private final String displayName; private final String displayName;
private final Long officeId; private final Long officeId;
private final String officeName; private final String officeName;
private final String externalId;
private final LocalDate joinedDate; private final LocalDate joinedDate;
private final String imageKey; private final String imageKey;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@@ -31,91 +32,52 @@ final public class ClientData {
private final ClientData currentChange; private final ClientData currentChange;
private final Collection<ClientData> allChanges; private final Collection<ClientData> allChanges;
private static String buildDisplayNameFrom(final String firstname, final String lastname) {
String displayName = null;
StringBuilder displayNameBuilder = new StringBuilder();
if (StringUtils.isNotBlank(firstname)) {
displayNameBuilder.append(firstname).append(' ');
}
if (StringUtils.isNotBlank(lastname)) {
displayNameBuilder.append(lastname);
displayName = displayNameBuilder.toString();
}
return displayName;
}
public static ClientData dataChangeInstance(final Long id, final Long officeId, final String externalId, final String firstname, public static ClientData dataChangeInstance(final Long id, final Long officeId, final String externalId, final String firstname,
final String lastname, final String clientOrBusinessName, final LocalDate joiningDate) { final String middlename, final String lastname, final String fullname, final LocalDate joiningDate) {
String firstnameValue = firstname; String localDisplayName = null;
String lastnameValue = lastname; return new ClientData(null, officeId, null, id, firstname, middlename, lastname, fullname, localDisplayName, externalId,
if (StringUtils.isNotBlank(clientOrBusinessName)) { joiningDate, null, null, null, null);
firstnameValue = null;
lastnameValue = clientOrBusinessName;
}
final String displayName = buildDisplayNameFrom(firstnameValue, lastnameValue);
return new ClientData(null, officeId, null, id, firstnameValue, lastnameValue, displayName, externalId, joiningDate, null, null, null,
null);
} }
public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection<ClientData> allChanges) { public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection<ClientData> allChanges) {
String firstname = clientData.firstname; return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname,
String lastname = clientData.lastname; clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId,
if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges);
firstname = null;
lastname = clientData.clientOrBusinessName;
}
final String displayName = buildDisplayNameFrom(firstname, lastname);
return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName,
clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges);
} }
public static ClientData template(final Long officeId, final LocalDate joinedDate, final List<OfficeLookup> allowedOffices) { public static ClientData template(final Long officeId, final LocalDate joinedDate, final List<OfficeLookup> allowedOffices) {
return new ClientData(null, officeId, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null); return new ClientData(null, officeId, null, null, null, null, null, null, null, null, joinedDate, null, allowedOffices, null, null);
} }
public static ClientData templateOnTop(final ClientData clientData, final List<OfficeLookup> allowedOffices) { public static ClientData templateOnTop(final ClientData clientData, final List<OfficeLookup> allowedOffices) {
String firstname = clientData.firstname; return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname,
String lastname = clientData.lastname; clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId,
if (StringUtils.isNotBlank(clientData.clientOrBusinessName)) { clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange, clientData.allChanges);
firstname = null;
lastname = clientData.clientOrBusinessName;
}
final String displayName = buildDisplayNameFrom(firstname, lastname);
return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, firstname, lastname, displayName,
clientData.externalId, clientData.joinedDate, clientData.imageKey, allowedOffices, clientData.currentChange,
clientData.allChanges);
} }
public static ClientData clientIdentifier(final Long id, final String accountIdentifier, final String firstname, final String lastname, final Long officeId, public static ClientData clientIdentifier(final Long id, final String accountIdentifier, final String firstname,
final String middlename, final String lastname, final String fullname, final String displayName, final Long officeId,
final String officeName) { final String officeName) {
final String displayName = buildDisplayNameFrom(firstname, lastname); return new ClientData(accountIdentifier, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, null,
null, null, null, null, null);
return new ClientData(accountIdentifier, officeId, officeName, id, firstname, lastname, displayName, null, null, null, null, null, null);
} }
public ClientData(final String accountNo, final Long officeId, final String officeName, final Long id, final String firstname, final String lastname, public ClientData(final String accountNo, final Long officeId, final String officeName, final Long id, final String firstname,
final String displayName, final String externalId, final LocalDate joinedDate, final String imageKey, final String middlename, final String lastname, final String fullname, final String displayName, final String externalId,
final List<OfficeLookup> allowedOffices, final ClientData currentChange, final Collection<ClientData> allChanges) { final LocalDate joinedDate, final String imageKey, final List<OfficeLookup> allowedOffices, final ClientData currentChange,
final Collection<ClientData> allChanges) {
this.accountNo = accountNo; this.accountNo = accountNo;
this.officeId = officeId; this.officeId = officeId;
this.officeName = officeName; this.officeName = officeName;
this.id = id; this.id = id;
this.firstname = StringUtils.defaultIfEmpty(firstname, null); this.firstname = StringUtils.defaultIfEmpty(firstname, null);
this.middlename = StringUtils.defaultIfEmpty(middlename, null);
/*** unset last name for business name **/ this.lastname = StringUtils.defaultIfEmpty(lastname, null);
if (StringUtils.isBlank(firstname)) { this.fullname = StringUtils.defaultIfEmpty(fullname, null);
this.lastname = null; this.displayName = StringUtils.defaultIfEmpty(displayName, null);
this.clientOrBusinessName = lastname;
} else {
this.lastname = lastname;
this.clientOrBusinessName = null;
}
this.displayName = displayName;
this.externalId = StringUtils.defaultIfEmpty(externalId, null); this.externalId = StringUtils.defaultIfEmpty(externalId, null);
this.joinedDate = joinedDate; this.joinedDate = joinedDate;
this.imageKey = imageKey; this.imageKey = imageKey;
@@ -1,12 +0,0 @@
package org.mifosplatform.portfolio.client.domain;
/**
* Responsible for generating unique account identifiers based some rules or patterns.
*
* @see ClientAccountIdentifierGenerator
*/
public interface AccountIdentifierGenerator {
String generate();
}
@@ -0,0 +1,12 @@
package org.mifosplatform.portfolio.client.domain;
import org.springframework.stereotype.Component;
@Component
public class AccountIdentifierGeneratorFactory {
public AccountNumberGenerator determineClientAccountNoGenerator(final Long clientId) {
return new ClientAccountNumberGenerator(clientId, 9);
}
}
@@ -0,0 +1,12 @@
package org.mifosplatform.portfolio.client.domain;
/**
* Responsible for generating unique account number based on some rules or patterns.
*
* @see ClientAccountNumberGenerator
*/
public interface AccountNumberGenerator {
String generate();
}
@@ -1,7 +1,9 @@
package org.mifosplatform.portfolio.client.domain; package org.mifosplatform.portfolio.client.domain;
import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
@@ -11,10 +13,14 @@ import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import javax.persistence.Transient;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator; import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -23,8 +29,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_client") @Table(name = "m_client")
public class Client extends AbstractPersistable<Long> { public class Client extends AbstractPersistable<Long> {
@SuppressWarnings("unused") @Column(name = "account_no", length = 40, unique = true, nullable = false)
@Column(name = "account_no", length=40, unique=true, nullable=false)
private String accountNumber; private String accountNumber;
@ManyToOne @ManyToOne
@@ -32,12 +37,19 @@ public class Client extends AbstractPersistable<Long> {
private Office office; private Office office;
@Column(name = "firstname", length = 50) @Column(name = "firstname", length = 50)
private String firstName; private String firstname;
@Column(name = "middlename", length = 50)
private String middlename;
@Column(name = "lastname", length = 50) @Column(name = "lastname", length = 50)
private String lastName; private String lastname;
@Column(name = "display_name", length = 50) @Column(name = "fullname", length = 100)
private String fullname;
@SuppressWarnings("unused")
@Column(name = "display_name", length = 100)
private String displayName; private String displayName;
@Column(name = "joined_date") @Column(name = "joined_date")
@@ -53,36 +65,34 @@ public class Client extends AbstractPersistable<Long> {
@Column(name = "image_key", length = 500) @Column(name = "image_key", length = 500)
private String imageKey; private String imageKey;
@Transient
private boolean accountNumberRequiresAutoGeneration = false;
public static Client fromJson(final Office clientOffice, final JsonCommand command) { public static Client fromJson(final Office clientOffice, final JsonCommand command) {
final String joiningDateParamName = "joinedDate"; final String accountNo = command.stringValueOfParameterNamed("accountNo");
final LocalDate joiningDate = command.localDateValueOfParameterNamed(joiningDateParamName); final String firstname = command.stringValueOfParameterNamed("firstname");
final String middlename = command.stringValueOfParameterNamed("middlename");
final String lastname = command.stringValueOfParameterNamed("lastname");
final String fullname = command.stringValueOfParameterNamed("fullname");
final LocalDate joiningDate = command.localDateValueOfParameterNamed("joinedDate");
final String externalId = command.stringValueOfParameterNamed("externalId");
final String firstnameParamName = "firstname"; return new Client(clientOffice, accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
String firstname = command.stringValueOfParameterNamed(firstnameParamName);
final String lastnameParamName = "lastname";
String lastname = command.stringValueOfParameterNamed(lastnameParamName);
final String clientOrBusinessNameParamName = "clientOrBusinessName";
final String clientOrBusinessName = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
if (StringUtils.isNotBlank(clientOrBusinessName)) {
lastname = clientOrBusinessName;
firstname = null;
}
final String externalIdParamName = "externalId";
final String externalId = command.stringValueOfParameterNamed(externalIdParamName);
return new Client(clientOffice, firstname, lastname, joiningDate, externalId);
} }
protected Client() { protected Client() {
// //
} }
private Client(final Office office, final String firstName, final String lastName, final LocalDate openingDate, final String externalId) { private Client(final Office office, final String accountNo, final String firstname, final String middlename, final String lastname, final String fullname,
this.accountNumber = new RandomPasswordGenerator(19).generate(); final LocalDate openingDate, final String externalId) {
if (StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate();
this.accountNumberRequiresAutoGeneration = true;
} else {
this.accountNumber = accountNo;
}
this.office = office; this.office = office;
if (StringUtils.isNotBlank(externalId)) { if (StringUtils.isNotBlank(externalId)) {
this.externalId = externalId.trim(); this.externalId = externalId.trim();
@@ -90,18 +100,40 @@ public class Client extends AbstractPersistable<Long> {
this.externalId = null; this.externalId = null;
} }
this.joinedDate = openingDate.toDateMidnight().toDate(); this.joinedDate = openingDate.toDateMidnight().toDate();
if (StringUtils.isNotBlank(firstName)) { if (StringUtils.isNotBlank(firstname)) {
this.firstName = firstName.trim(); this.firstname = firstname.trim();
} else { } else {
this.firstName = null; this.firstname = null;
} }
this.lastName = lastName.trim();
// populate display name if (StringUtils.isNotBlank(middlename)) {
if (this.firstName != null) { this.middlename = middlename.trim();
this.displayName = this.firstName + " " + this.lastName;
} else { } else {
this.displayName = this.lastName; this.middlename = null;
} }
if (StringUtils.isNotBlank(lastname)) {
this.lastname = lastname.trim();
} else {
this.lastname = null;
}
if (StringUtils.isNotBlank(fullname)) {
this.fullname = fullname.trim();
} else {
this.fullname = null;
}
deriveDisplayName();
validateNameParts();
}
public boolean isAccountNumberRequiresAutoGeneration() {
return this.accountNumberRequiresAutoGeneration;
}
public void setAccountNumberRequiresAutoGeneration(boolean accountNumberRequiresAutoGeneration) {
this.accountNumberRequiresAutoGeneration = accountNumberRequiresAutoGeneration;
} }
public boolean identifiedBy(final String identifier) { public boolean identifiedBy(final String identifier) {
@@ -122,10 +154,21 @@ public class Client extends AbstractPersistable<Long> {
public Map<String, Object> update(final JsonCommand command) { public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7); final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
final String dateFormatAsInput = command.dateFormat(); final String accountNoParamName = "accountNo";
final String localeAsInput = command.locale(); if (command.isChangeInStringParameterNamed(accountNoParamName, this.accountNumber)) {
final String newValue = command.stringValueOfParameterNamed(accountNoParamName);
actualChanges.put(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);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
final String officeIdParamName = "officeId"; final String officeIdParamName = "officeId";
if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) { if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) {
@@ -133,6 +176,39 @@ public class Client extends AbstractPersistable<Long> {
actualChanges.put(officeIdParamName, newValue); actualChanges.put(officeIdParamName, newValue);
} }
final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstname)) {
final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
actualChanges.put(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);
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);
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);
this.fullname = newValue;
}
validateNameParts();
final String dateFormatAsInput = command.dateFormat();
final String localeAsInput = command.locale();
final String joiningDateParamName = "joinedDate"; final String joiningDateParamName = "joinedDate";
if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) { if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) {
final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName); final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName);
@@ -144,49 +220,58 @@ public class Client extends AbstractPersistable<Long> {
this.joinedDate = newValue.toDate(); this.joinedDate = newValue.toDate();
} }
final String clientOrBusinessNameParamName = "clientOrBusinessName"; deriveDisplayName();
final String lastnameParamName = "lastname";
if (command.isChangeInStringParameterNamed(lastnameParamName, getLastnameIfNotClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
actualChanges.put(lastnameParamName, newValue);
if (StringUtils.isNotBlank(getClientOrBusinessName())) {
actualChanges.put(clientOrBusinessNameParamName, "");
}
this.lastName = newValue;
}
final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) {
final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
actualChanges.put(firstnameParamName, newValue);
this.firstName = newValue;
}
if (command.isChangeInStringParameterNamed(clientOrBusinessNameParamName, getClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
actualChanges.put(clientOrBusinessNameParamName, newValue);
if (StringUtils.isNotBlank(newValue)) {
this.lastName = newValue;
this.firstName = null;
this.displayName = this.lastName;
} else {
deriveDisplayName();
}
}
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
return actualChanges; return actualChanges;
} }
private void validateNameParts() {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (StringUtils.isNotBlank(this.fullname)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname)
.mustBeBlankWhenParameterProvided("fullname", this.fullname);
baseDataValidator.reset().parameter("middlename").value(this.middlename)
.mustBeBlankWhenParameterProvided("fullname", this.fullname);
baseDataValidator.reset().parameter("lastname").value(this.lastname)
.mustBeBlankWhenParameterProvided("fullname", this.fullname);
}
if (StringUtils.isBlank(this.fullname)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname).notBlank().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("middlename").value(this.middlename).ignoreIfNull().notExceedingLengthOf(50);
baseDataValidator.reset().parameter("lastname").value(this.lastname).notBlank().notExceedingLengthOf(50);
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
private void deriveDisplayName() { private void deriveDisplayName() {
this.displayName = this.firstName + " " + this.lastName;
StringBuilder nameBuilder = new StringBuilder();
if (StringUtils.isNotBlank(this.firstname)) {
nameBuilder.append(this.firstname).append(' ');
}
if (StringUtils.isNotBlank(this.middlename)) {
nameBuilder.append(this.middlename).append(' ');
}
if (StringUtils.isNotBlank(this.lastname)) {
nameBuilder.append(this.lastname);
}
if (StringUtils.isNotBlank(this.fullname)) {
nameBuilder = new StringBuilder(this.fullname);
}
this.displayName = nameBuilder.toString();
} }
private LocalDate getJoiningLocalDate() { private LocalDate getJoiningLocalDate() {
@@ -197,26 +282,6 @@ public class Client extends AbstractPersistable<Long> {
return joiningLocalDate; return joiningLocalDate;
} }
/*
*
*/
private String getLastnameIfNotClientOrBusinessName() {
String lastname = null;
if (StringUtils.isNotBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) {
lastname = this.lastName;
}
return lastname;
}
private String getClientOrBusinessName() {
String clientOrBusinessName = null;
if (StringUtils.isBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) {
clientOrBusinessName = this.lastName;
}
return clientOrBusinessName;
}
/** /**
* Delete is a <i>soft delete</i>. Updates flag on client so it wont appear * Delete is a <i>soft delete</i>. Updates flag on client so it wont appear
* in query/report results. * in query/report results.
@@ -240,54 +305,22 @@ public class Client extends AbstractPersistable<Long> {
return office; return office;
} }
public void setOffice(Office office) {
this.office = office;
}
public String getFirstName() { public String getFirstName() {
return firstName; return firstname;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
} }
public String getLastName() { public String getLastName() {
return lastName; return lastname;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
} }
public Date getJoiningDate() { public Date getJoiningDate() {
return joinedDate; return joinedDate;
} }
public void setJoiningDate(Date joiningDate) {
this.joinedDate = joiningDate;
}
public String getExternalId() { public String getExternalId() {
return externalId; return externalId;
} }
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public String getImageKey() { public String getImageKey() {
return imageKey; return imageKey;
} }
@@ -1,16 +1,16 @@
package org.mifosplatform.portfolio.client.domain; package org.mifosplatform.portfolio.client.domain;
/** /**
* Example {@link AccountIdentifierGenerator} for clients that takes clients * Example {@link AccountNumberGenerator} for clients that takes clients
* auto generated database id and zero fills it ensuring the identifier is * auto generated database id and zero fills it ensuring the identifier is
* always of a given <code>maxLength</code>. * always of a given <code>maxLength</code>.
*/ */
public class ClientAccountIdentifierGenerator implements AccountIdentifierGenerator { public class ClientAccountNumberGenerator implements AccountNumberGenerator {
private final Long clientId; private final Long clientId;
private final int maxLength; private final int maxLength;
public ClientAccountIdentifierGenerator(final Long clientId, int maxLength) { public ClientAccountNumberGenerator(final Long clientId, int maxLength) {
this.clientId = clientId; this.clientId = clientId;
this.maxLength = maxLength;} this.maxLength = maxLength;}
@@ -1,14 +1,19 @@
package org.mifosplatform.portfolio.client.serialization; package org.mifosplatform.portfolio.client.serialization;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException; import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -29,8 +34,8 @@ public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJ
/** /**
* The parameters supported for this command. * The parameters supported for this command.
*/ */
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "externalId", "firstname", "lastname", private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "accountNo", "externalId", "firstname",
"clientOrBusinessName", "officeId", "joinedDate", "locale", "dateFormat")); "middlename", "lastname", "fullname", "officeId", "joinedDate", "locale", "dateFormat"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
@@ -48,13 +53,113 @@ public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJ
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters); fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json); final JsonElement element = fromApiJsonHelper.parse(json);
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element); final String accountNo = fromApiJsonHelper.extractStringNamed("accountNo", element);
final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element); final String externalId = fromApiJsonHelper.extractStringNamed("externalId", element);
final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element); final String firstname = fromApiJsonHelper.extractStringNamed("firstname", element);
final String middlename = fromApiJsonHelper.extractStringNamed("middlename", element);
final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element); final String lastname = fromApiJsonHelper.extractStringNamed("lastname", element);
final String clientOrBusinessName = fromApiJsonHelper.extractStringNamed("clientOrBusinessName", element); final String fullname = fromApiJsonHelper.extractStringNamed("fullname", element);
final Long officeId = fromApiJsonHelper.extractLongNamed("officeId", element);
final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joinedDate", element); final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joinedDate", element);
return new ClientCommand(externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate); return new ClientCommand(accountNo, externalId, firstname, middlename, lastname, fullname, officeId, joiningDate);
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
boolean atLeastOneParameterPassedForUpdate = false;
final String accountNoParameterName = "accountNo";
if (fromApiJsonHelper.parameterExists(accountNoParameterName, element)) {
atLeastOneParameterPassedForUpdate = true;
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParameterName, element);
baseDataValidator.reset().parameter(accountNoParameterName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
final String externalIdParameterName = "externalId";
if (fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
atLeastOneParameterPassedForUpdate = true;
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
}
final String officeIdParameterName = "officeId";
if (fromApiJsonHelper.parameterExists(officeIdParameterName, element)) {
atLeastOneParameterPassedForUpdate = true;
final Long officeId = fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
}
final String joinedDateParameterName = "joinedDate";
if (fromApiJsonHelper.parameterExists(joinedDateParameterName, element)) {
atLeastOneParameterPassedForUpdate = true;
final String joinedDateStr = fromApiJsonHelper.extractStringNamed(joinedDateParameterName, element);
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDateStr).notBlank();
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(joinedDateParameterName, element);
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDate).notNull();
}
if (!atLeastOneParameterPassedForUpdate) {
final Object forceError = null;
baseDataValidator.reset().anyOfNotNull(forceError);
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParameters);
final JsonElement element = fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
final String accountNoParameterName = "accountNo";
if (fromApiJsonHelper.parameterExists(accountNoParameterName, element)) {
final String accountNo = fromApiJsonHelper.extractStringNamed(accountNoParameterName, element);
baseDataValidator.reset().parameter(accountNoParameterName).value(accountNo).notBlank().notExceedingLengthOf(20);
}
final String externalIdParameterName = "externalId";
if (fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
final String externalId = fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
}
final String officeIdParameterName = "officeId";
if (fromApiJsonHelper.parameterExists(officeIdParameterName, element)) {
final Long officeId = fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
}
final String joinedDateParameterName = "joinedDate";
if (fromApiJsonHelper.parameterExists(joinedDateParameterName, element)) {
final String joinedDateStr = fromApiJsonHelper.extractStringNamed(joinedDateParameterName, element);
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDateStr).notBlank();
final LocalDate joinedDate = fromApiJsonHelper.extractLocalDateNamed(joinedDateParameterName, element);
baseDataValidator.reset().parameter(joinedDateParameterName).value(joinedDate).notNull();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
} }
} }
@@ -130,7 +130,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private static final class ClientMapper implements RowMapper<ClientData> { private static final class ClientMapper implements RowMapper<ClientData> {
public String clientSchema() { public String clientSchema() {
return "c.account_no as accountNo, c.office_id as officeId, o.name as officeName, c.id as id, c.firstname as firstname, c.lastname as lastname, c.display_name as displayName, " return "c.account_no as accountNo, c.office_id as officeId, o.name as officeName, c.id as id, "
+ "c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "
+ "c.fullname as fullname, c.display_name as displayName, "
+ "c.external_id as externalId, c.joined_date as joinedDate, c.image_key as imagekey from m_client c join m_office o on o.id = c.office_id " + "c.external_id as externalId, c.joined_date as joinedDate, c.image_key as imagekey from m_client c join m_office o on o.id = c.office_id "
+ " where o.hierarchy like ? and c.is_deleted=0 "; + " where o.hierarchy like ? and c.is_deleted=0 ";
} }
@@ -141,19 +143,18 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String accountNo = rs.getString("accountNo"); final String accountNo = rs.getString("accountNo");
final Long officeId = JdbcSupport.getLong(rs, "officeId"); final Long officeId = JdbcSupport.getLong(rs, "officeId");
final Long id = JdbcSupport.getLong(rs, "id"); final Long id = JdbcSupport.getLong(rs, "id");
String firstname = rs.getString("firstname"); final String firstname = rs.getString("firstname");
if (StringUtils.isBlank(firstname)) { final String middlename = rs.getString("middlename");
firstname = "";
}
final String lastname = rs.getString("lastname"); final String lastname = rs.getString("lastname");
final String fullname = rs.getString("fullname");
final String displayName = rs.getString("displayName"); final String displayName = rs.getString("displayName");
final String externalId = rs.getString("externalId"); final String externalId = rs.getString("externalId");
final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate"); final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate");
final String imageKey = rs.getString("imageKey"); final String imageKey = rs.getString("imageKey");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
return new ClientData(accountNo, officeId, officeName, id, firstname, lastname, displayName, externalId, joinedDate, imageKey, null, null, return new ClientData(accountNo, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, externalId,
null); joinedDate, imageKey, null, null, null);
} }
} }
@@ -258,28 +259,29 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
List<ClientAccountSummaryData> closedSavingAccounts = new ArrayList<ClientAccountSummaryData>(); List<ClientAccountSummaryData> closedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
ClientSavingAccountSummaryDataMapper clientSavingAccountSummaryDataMapper = new ClientSavingAccountSummaryDataMapper(); ClientSavingAccountSummaryDataMapper clientSavingAccountSummaryDataMapper = new ClientSavingAccountSummaryDataMapper();
String savingAccountsSql = "select " + clientSavingAccountSummaryDataMapper.schema() + " where sa.client_id=? and sa.is_deleted=0"; String savingAccountsSql = "select " + clientSavingAccountSummaryDataMapper.schema()
List<ClientAccountSummaryData> savingAccountsResults = this.jdbcTemplate.query(savingAccountsSql, clientSavingAccountSummaryDataMapper, new Object[] {clientId}); + " where sa.client_id=? and sa.is_deleted=0";
List<ClientAccountSummaryData> savingAccountsResults = this.jdbcTemplate.query(savingAccountsSql,
clientSavingAccountSummaryDataMapper, new Object[] { clientId });
if (savingAccountsResults != null) { if (savingAccountsResults != null) {
for (ClientAccountSummaryData account : savingAccountsResults){ for (ClientAccountSummaryData account : savingAccountsResults) {
if (account.accountStatusId() == 100) if (account.accountStatusId() == 100)
pendingApprovalSavingAccounts.add(account); pendingApprovalSavingAccounts.add(account);
else if (account.accountStatusId() ==300) else if (account.accountStatusId() == 300)
approvedSavingAccounts.add(account); approvedSavingAccounts.add(account);
else if (account.accountStatusId() == 400) else if (account.accountStatusId() == 400)
withdrawnByClientSavingAccounts.add(account); withdrawnByClientSavingAccounts.add(account);
else if (account.accountStatusId() == 500) else if (account.accountStatusId() == 500)
rejectedSavingAccounts.add(account); rejectedSavingAccounts.add(account);
else if (account.accountStatusId() == 600) else if (account.accountStatusId() == 600) closedSavingAccounts.add(account);
closedSavingAccounts.add(account); }
} }
}
return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans, return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans,
pendingApprovalDepositAccounts, approvedDepositAccounts, withdrawnByClientDespositAccounts, rejectedDepositAccounts, pendingApprovalDepositAccounts, approvedDepositAccounts, withdrawnByClientDespositAccounts, rejectedDepositAccounts,
closedDepositAccounts, preclosedDepositAccounts, maturedDepositAccounts, closedDepositAccounts, preclosedDepositAccounts, maturedDepositAccounts, pendingApprovalSavingAccounts,
pendingApprovalSavingAccounts,approvedSavingAccounts,withdrawnByClientSavingAccounts,rejectedSavingAccounts,closedSavingAccounts); approvedSavingAccounts, withdrawnByClientSavingAccounts, rejectedSavingAccounts, closedSavingAccounts);
} catch (EmptyResultDataAccessException e) { } catch (EmptyResultDataAccessException e) {
throw new ClientNotFoundException(clientId); throw new ClientNotFoundException(clientId);
} }
@@ -524,8 +526,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private static final class ClientIdentifierMapper implements RowMapper<ClientData> { private static final class ClientIdentifierMapper implements RowMapper<ClientData> {
public String clientLookupByIdentifierSchema() { public String clientLookupByIdentifierSchema() {
return "c.id as id, c.account_no as accountNo, c.firstname as firstname, c.lastname as lastname, " + "c.office_id as officeId, o.name as officeName " return "c.id as id, c.account_no as accountNo, c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "
+ "from m_client c, m_office o, m_client_identifier ci " + "where o.id = c.office_id and c.id=ci.client_id " + "c.fullname as fullname, c.display_name as displayName," + "c.office_id as officeId, o.name as officeName "
+ " from m_client c, m_office o, m_client_identifier ci " + "where o.id = c.office_id and c.id=ci.client_id "
+ "and ci.document_type_id= ? and ci.document_key like ?"; + "and ci.document_type_id= ? and ci.document_key like ?";
} }
@@ -534,21 +537,20 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String accountNo = rs.getString("accountNo"); final String accountNo = rs.getString("accountNo");
String firstname = rs.getString("firstname"); final String firstname = rs.getString("firstname");
if (StringUtils.isBlank(firstname)) { final String middlename = rs.getString("middlename");
firstname = "";
}
final String lastname = rs.getString("lastname"); final String lastname = rs.getString("lastname");
final String fullname = rs.getString("fullname");
final String displayName = rs.getString("displayName");
final Long officeId = rs.getLong("officeId"); final Long officeId = rs.getLong("officeId");
final String officeName = rs.getString("officeName"); final String officeName = rs.getString("officeName");
return ClientData.clientIdentifier(id, accountNo, firstname, lastname, officeId, officeName); return ClientData.clientIdentifier(id, accountNo, firstname, middlename, lastname, fullname, displayName, officeId, officeName);
} }
} }
private static final class ClientSavingAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
private static final class ClientSavingAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
public String schema() { public String schema() {
@@ -20,12 +20,11 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand; import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.mifosplatform.portfolio.client.domain.AccountIdentifierGenerator; import org.mifosplatform.portfolio.client.domain.AccountIdentifierGeneratorFactory;
import org.mifosplatform.portfolio.client.domain.AccountNumberGenerator;
import org.mifosplatform.portfolio.client.domain.Client; import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientAccountIdentifierGenerator;
import org.mifosplatform.portfolio.client.domain.ClientIdentifier; import org.mifosplatform.portfolio.client.domain.ClientIdentifier;
import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository; import org.mifosplatform.portfolio.client.domain.ClientIdentifierRepository;
import org.mifosplatform.portfolio.client.domain.ClientRepository; import org.mifosplatform.portfolio.client.domain.ClientRepository;
@@ -59,6 +58,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer; private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer; private final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer;
private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer; private final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer;
private final AccountIdentifierGeneratorFactory accountIdentifierGeneratorFactory;
@Autowired @Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository, public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository,
@@ -66,7 +66,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final NoteRepository noteRepository, final CodeValueRepository codeValueRepository, final NoteRepository noteRepository, final CodeValueRepository codeValueRepository,
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer, final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer,
final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer) { final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer,
final AccountIdentifierGeneratorFactory accountIdentifierGeneratorFactory) {
this.context = context; this.context = context;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.clientIdentifierRepository = clientIdentifierRepository; this.clientIdentifierRepository = clientIdentifierRepository;
@@ -76,6 +77,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.clientNoteFromApiJsonDeserializer = clientNoteFromApiJsonDeserializer; this.clientNoteFromApiJsonDeserializer = clientNoteFromApiJsonDeserializer;
this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer; this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
} }
@Transactional @Transactional
@@ -119,8 +121,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
try { try {
context.authenticatedUser(); context.authenticatedUser();
final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); this.fromApiJsonDeserializer.validateForCreate(command.json());
clientCommand.validateForCreate();
final String officeIdParamName = "officeId"; final String officeIdParamName = "officeId";
final Long officeId = command.longValueOfParameterNamed(officeIdParamName); final Long officeId = command.longValueOfParameterNamed(officeIdParamName);
@@ -131,14 +132,19 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final Client newClient = Client.fromJson(clientOffice, command); final Client newClient = Client.fromJson(clientOffice, command);
this.clientRepository.save(newClient); this.clientRepository.save(newClient);
// now use client account identifier generator to generate proper if (newClient.isAccountNumberRequiresAutoGeneration()) {
// account number final AccountNumberGenerator accountNoGenerator = this.accountIdentifierGeneratorFactory
AccountIdentifierGenerator generator = new ClientAccountIdentifierGenerator(newClient.getId(), 9); .determineClientAccountNoGenerator(newClient.getId());
newClient.updateAccountIdentifier(generator.generate()); newClient.updateAccountIdentifier(accountNoGenerator.generate());
this.clientRepository.save(newClient); this.clientRepository.save(newClient);
}
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withOfficeId(clientOffice.getId()) return new CommandProcessingResultBuilder() //
.withClientId(newClient.getId()).withEntityId(newClient.getId()).build(); .withCommandId(command.commandId()) //
.withOfficeId(clientOffice.getId()) //
.withClientId(newClient.getId()) //
.withEntityId(newClient.getId()) //
.build();
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
return CommandProcessingResult.empty(); return CommandProcessingResult.empty();
@@ -152,8 +158,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
try { try {
context.authenticatedUser(); context.authenticatedUser();
final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json()); this.fromApiJsonDeserializer.validateForUpdate(command.json());
clientCommand.validateForUpdate();
final Client clientForUpdate = this.clientRepository.findOne(clientId); final Client clientForUpdate = this.clientRepository.findOne(clientId);
if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(clientId); } if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(clientId); }