From a22d5d10aa2ece06b792e86434bb5213447667fd Mon Sep 17 00:00:00 2001 From: Vishwas Babu A J Date: Wed, 5 Sep 2012 01:18:27 +0530 Subject: [PATCH] updating Client crud service & Db schema for MifosX-35 --- .../patches/patch-0003-m_client-patch.sql | 4 + .../mifosng/platform/api/data/ClientData.java | 207 +++-- .../platform/client/domain/Client.java | 295 ++++--- .../ClientReadPlatformServiceImpl.java | 815 +++++++++--------- 4 files changed, 672 insertions(+), 649 deletions(-) create mode 100644 mifosng-db/patches/patch-0003-m_client-patch.sql diff --git a/mifosng-db/patches/patch-0003-m_client-patch.sql b/mifosng-db/patches/patch-0003-m_client-patch.sql new file mode 100644 index 000000000..44c33db81 --- /dev/null +++ b/mifosng-db/patches/patch-0003-m_client-patch.sql @@ -0,0 +1,4 @@ +ALTER TABLE `m_client` + ADD COLUMN `display_name` VARCHAR(100) NOT NULL AFTER `lastname`; + +update m_client set display_name = concat_ws(' ',firstname,lastname); \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java index ec42b13cd..88346b222 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/data/ClientData.java @@ -1,106 +1,103 @@ -package org.mifosng.platform.api.data; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.joda.time.LocalDate; - -public class ClientData { - - private final Long id; - private final String firstname; - private final String lastname; - private final String clientOrBusinessName; - private final String displayName; - private final Long officeId; - private final String officeName; - private final String externalId; - private final LocalDate joinedDate; - - private List allowedOffices = new ArrayList(); - - public ClientData(final Long officeId, final String officeName, - final Long id, final String firstname, final String lastname, - final String externalId, final LocalDate joinedDate) { - this.officeId = officeId; - this.officeName = officeName; - this.id = id; - this.firstname = firstname; - - StringBuilder nameBuilder = new StringBuilder(this.firstname); - if (StringUtils.isNotBlank(nameBuilder.toString())) { - nameBuilder.append(' '); - } - nameBuilder.append(lastname); - - this.displayName = nameBuilder.toString(); - if (StringUtils.isBlank(this.firstname)) { - this.lastname = null; - this.clientOrBusinessName = nameBuilder.toString(); - } else { - this.lastname = lastname; - this.clientOrBusinessName = null; - } - - this.externalId = externalId; - this.joinedDate = joinedDate; - } - - public ClientData(final Long officeId, final LocalDate joinedDate, final List offices) { - this.id = null; - this.officeId = officeId; - this.officeName = null; - this.firstname = null; - this.lastname = null; - this.clientOrBusinessName = null; - this.displayName = null; - this.externalId = null; - this.joinedDate = joinedDate; - this.allowedOffices = offices; - } - - public Long getId() { - return id; - } - - public Long getOfficeId() { - return officeId; - } - - public String getOfficeName() { - return officeName; - } - - public String getFirstname() { - return firstname; - } - - public String getLastname() { - return lastname; - } - - public String getClientOrBusinessName() { - return clientOrBusinessName; - } - - public String getDisplayName() { - return displayName; - } - - public String getExternalId() { - return externalId; - } - - public LocalDate getJoinedDate() { - return joinedDate; - } - - public List getAllowedOffices() { - return allowedOffices; - } - - public void setAllowedOffices(List allowedOffices) { - this.allowedOffices = allowedOffices; - } +package org.mifosng.platform.api.data; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; + +public class ClientData { + + private final Long id; + private final String firstname; + private final String lastname; + private final String clientOrBusinessName; + private final String displayName; + private final Long officeId; + private final String officeName; + private final String externalId; + private final LocalDate joinedDate; + + private List allowedOffices = new ArrayList(); + + public ClientData(final Long officeId, final String officeName, + final Long id, final String firstname, final String lastname, + final String displayName, final String externalId, + final LocalDate joinedDate) { + this.officeId = officeId; + this.officeName = officeName; + this.id = id; + this.firstname = firstname; + this.displayName = displayName; + + /*** unset last name for business name **/ + if (StringUtils.isBlank(this.firstname)) { + this.lastname = null; + this.clientOrBusinessName = lastname; + } else { + this.lastname = lastname; + this.clientOrBusinessName = null; + } + + this.externalId = externalId; + this.joinedDate = joinedDate; + } + + public ClientData(final Long officeId, final LocalDate joinedDate, + final List offices) { + this.id = null; + this.officeId = officeId; + this.officeName = null; + this.firstname = null; + this.lastname = null; + this.clientOrBusinessName = null; + this.displayName = null; + this.externalId = null; + this.joinedDate = joinedDate; + this.allowedOffices = offices; + } + + public Long getId() { + return id; + } + + public Long getOfficeId() { + return officeId; + } + + public String getOfficeName() { + return officeName; + } + + public String getFirstname() { + return firstname; + } + + public String getLastname() { + return lastname; + } + + public String getClientOrBusinessName() { + return clientOrBusinessName; + } + + public String getDisplayName() { + return displayName; + } + + public String getExternalId() { + return externalId; + } + + public LocalDate getJoinedDate() { + return joinedDate; + } + + public List getAllowedOffices() { + return allowedOffices; + } + + public void setAllowedOffices(List allowedOffices) { + this.allowedOffices = allowedOffices; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java index 3af0588c2..9edd95852 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/domain/Client.java @@ -1,138 +1,159 @@ -package org.mifosng.platform.client.domain; - -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.apache.commons.lang.StringUtils; -import org.joda.time.LocalDate; -import org.mifosng.platform.api.commands.ClientCommand; -import org.mifosng.platform.infrastructure.AbstractAuditableCustom; -import org.mifosng.platform.organisation.domain.Office; -import org.mifosng.platform.user.domain.AppUser; - -@Entity -@Table(name = "m_client") -public class Client extends AbstractAuditableCustom { - - @SuppressWarnings("unused") - @ManyToOne - @JoinColumn(name = "office_id", nullable = false) - private Office office; - - @SuppressWarnings("unused") - @Column(name = "firstname", length=50) - private String firstName; - - @SuppressWarnings("unused") - @Column(name = "lastname", length=50) - private String lastName; - - @SuppressWarnings("unused") - @Column(name = "joining_date") - @Temporal(TemporalType.DATE) - private Date joiningDate; - - @Column(name = "external_id", length=100, unique=true) - private String externalId; - - @Column(name = "is_deleted", nullable=false) - private boolean deleted = false; - - public static Client newClient(Office clientOffice, String firstname, String lastname, LocalDate joiningDate, String externalId) { - return new Client(clientOffice, firstname, lastname, joiningDate, externalId); - } - - public Client() { - this.office = null; - this.joiningDate = null; - this.firstName = null; - this.lastName = null; - this.externalId = null; - } - - private Client(final Office office, final String firstName, final String lastName, final LocalDate openingDate, final String externalId) { - this.office = office; - if (StringUtils.isNotBlank(externalId)) { - this.externalId = externalId.trim(); - } else { - this.externalId = null; - } - this.joiningDate = openingDate.toDateMidnight().toDate(); - if (StringUtils.isNotBlank(firstName)) { - this.firstName = firstName.trim(); - } else { - this.firstName = null; - } - this.lastName = lastName.trim(); - } - - public boolean identifiedBy(final String identifier) { - return identifier.equalsIgnoreCase(this.externalId); - } - - public boolean identifiedBy(Long clientId) { - return getId().equals(clientId); - } - - public void update(ClientCommand command) { - this.joiningDate = command.getJoiningDate().toDate(); - this.firstName = command.getFirstname(); - this.lastName = command.getLastname(); - - if (StringUtils.isNotBlank(command.getClientOrBusinessName())) { - this.firstName = null; - this.lastName = command.getClientOrBusinessName().trim(); - } - - if (StringUtils.isNotBlank(command.getExternalId())) { - this.externalId = command.getExternalId().trim(); - } else { - this.externalId = null; - } - } - - public void update(final Office clientOffice, final ClientCommand command) { - if (command.isOfficeChanged()) { - this.office = clientOffice; - } - if (command.isJoiningDateChanged()) { - this.joiningDate = command.getJoiningDate().toDate(); - } - if (command.isFirstnameChanged()) { - this.firstName = command.getFirstname(); - } - if (command.isLastnameChanged()) { - this.lastName = command.getLastname(); - } - - if (command.isClientOrBusinessNameChanged() && StringUtils.isNotBlank(command.getClientOrBusinessName())) { - this.lastName = command.getClientOrBusinessName(); - this.firstName = null; - } - - if (command.isExternalIdChanged()) { - this.externalId = StringUtils.defaultIfEmpty(command.getExternalId().trim(), null); - } - } - - /** - * Delete is a soft delete. Updates flag on client so it wont appear in query/report results. - * - * Any fields with unique constraints and prepended with id of record. - */ - public void delete() { - this.deleted = true; - this.externalId = this.getId() + "_" + this.externalId; - } - - public boolean isDeleted() { - return deleted; - } +package org.mifosng.platform.client.domain; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.LocalDate; +import org.mifosng.platform.api.commands.ClientCommand; +import org.mifosng.platform.infrastructure.AbstractAuditableCustom; +import org.mifosng.platform.organisation.domain.Office; +import org.mifosng.platform.user.domain.AppUser; + +@Entity +@Table(name = "m_client") +public class Client extends AbstractAuditableCustom { + + @SuppressWarnings("unused") + @ManyToOne + @JoinColumn(name = "office_id", nullable = false) + private Office office; + + @SuppressWarnings("unused") + @Column(name = "firstname", length=50) + private String firstName; + + @SuppressWarnings("unused") + @Column(name = "lastname", length=50) + private String lastName; + + @SuppressWarnings("unused") + @Column(name = "display_name", length=50) + private String displayName; + + @SuppressWarnings("unused") + @Column(name = "joining_date") + @Temporal(TemporalType.DATE) + private Date joiningDate; + + @Column(name = "external_id", length=100, unique=true) + private String externalId; + + @Column(name = "is_deleted", nullable=false) + private boolean deleted = false; + + public static Client newClient(Office clientOffice, String firstname, String lastname, LocalDate joiningDate, String externalId) { + return new Client(clientOffice, firstname, lastname, joiningDate, externalId); + } + + public Client() { + this.office = null; + this.joiningDate = null; + this.firstName = null; + this.lastName = null; + this.externalId = null; + } + + private Client(final Office office, final String firstName, final String lastName, final LocalDate openingDate, final String externalId) { + this.office = office; + if (StringUtils.isNotBlank(externalId)) { + this.externalId = externalId.trim(); + } else { + this.externalId = null; + } + this.joiningDate = openingDate.toDateMidnight().toDate(); + if (StringUtils.isNotBlank(firstName)) { + this.firstName = firstName.trim(); + } else { + this.firstName = null; + } + this.lastName = lastName.trim(); + //populate display name + if(this.firstName!=null){ + this.displayName = this.firstName + " " + this.lastName; + }else{ + this.displayName = this.lastName; + } + } + + public boolean identifiedBy(final String identifier) { + return identifier.equalsIgnoreCase(this.externalId); + } + + public boolean identifiedBy(Long clientId) { + return getId().equals(clientId); + } + + public void update(ClientCommand command) { + this.joiningDate = command.getJoiningDate().toDate(); + this.firstName = command.getFirstname(); + this.lastName = command.getLastname(); + + if (StringUtils.isNotBlank(command.getClientOrBusinessName())) { + this.firstName = null; + this.lastName = command.getClientOrBusinessName().trim(); + this.displayName = this.lastName; + }else{ + deriveDisplayName(); + } + + if (StringUtils.isNotBlank(command.getExternalId())) { + this.externalId = command.getExternalId().trim(); + } else { + this.externalId = null; + } + } + + public void update(final Office clientOffice, final ClientCommand command) { + if (command.isOfficeChanged()) { + this.office = clientOffice; + } + if (command.isJoiningDateChanged()) { + this.joiningDate = command.getJoiningDate().toDate(); + } + if (command.isFirstnameChanged()) { + this.firstName = command.getFirstname(); + } + if (command.isLastnameChanged()) { + this.lastName = command.getLastname(); + } + + if (command.isClientOrBusinessNameChanged() && StringUtils.isNotBlank(command.getClientOrBusinessName())) { + this.lastName = command.getClientOrBusinessName(); + this.firstName = null; + this.displayName = this.lastName; + }else if(command.isFirstnameChanged() || command.isLastnameChanged()) { + //do not want to enter this condition for business names + deriveDisplayName(); + } + + if (command.isExternalIdChanged()) { + this.externalId = StringUtils.defaultIfEmpty(command.getExternalId().trim(), null); + } + } + + private void deriveDisplayName() { + this.displayName = this.firstName + " " + this.lastName; + } + + /** + * Delete is a soft delete. Updates flag on client so it wont appear in query/report results. + * + * Any fields with unique constraints and prepended with id of record. + */ + public void delete() { + this.deleted = true; + this.externalId = this.getId() + "_" + this.externalId; + } + + public boolean isDeleted() { + return deleted; + } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java index 82f5c0adb..8e4c7ca19 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/client/service/ClientReadPlatformServiceImpl.java @@ -1,408 +1,409 @@ -package org.mifosng.platform.client.service; - -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.apache.commons.lang.StringUtils; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.mifosng.platform.api.data.*; -import org.mifosng.platform.client.domain.NoteEnumerations; -import org.mifosng.platform.exceptions.ClientNotFoundException; -import org.mifosng.platform.exceptions.NoteNotFoundException; -import org.mifosng.platform.infrastructure.JdbcSupport; -import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; -import org.mifosng.platform.organisation.service.OfficeReadPlatformService; -import org.mifosng.platform.security.PlatformSecurityContext; -import org.mifosng.platform.user.domain.AppUser; -import org.mifosng.platform.user.service.AppUserReadPlatformService; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.dao.EmptyResultDataAccessException; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.core.RowMapper; -import org.springframework.stereotype.Service; - -@Service -public class ClientReadPlatformServiceImpl implements ClientReadPlatformService { - - private final JdbcTemplate jdbcTemplate; - private final PlatformSecurityContext context; - private final OfficeReadPlatformService officeReadPlatformService; - private final AppUserReadPlatformService appUserReadPlatformService; - - @Autowired - public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, - final TenantAwareRoutingDataSource dataSource, - final OfficeReadPlatformService officeReadPlatformService, - final AppUserReadPlatformService appUserReadPlatformService) { - this.context = context; - this.officeReadPlatformService = officeReadPlatformService; - this.appUserReadPlatformService = appUserReadPlatformService; - this.jdbcTemplate = new JdbcTemplate(dataSource); - } - - private String generateOfficeIdInClause(List offices) { - String officeIdsList = ""; - for (int i = 0; i < offices.size(); i++) { - Long id = offices.get(i).getId(); - if (i == 0) { - officeIdsList = id.toString(); - } else { - officeIdsList += "," + id.toString(); - } - } - return officeIdsList; - } - - @Override - public Collection retrieveAllIndividualClients(final String extraCriteria) { - - this.context.authenticatedUser(); - - List offices = new ArrayList(officeReadPlatformService.retrieveAllOffices()); - String officeIdsList = generateOfficeIdInClause(offices); - - ClientMapper rm = new ClientMapper(offices); - - String sql = "select " + rm.clientSchema() + " where c.office_id in (" + officeIdsList + ") and c.is_deleted=0"; - - if (StringUtils.isNotBlank(extraCriteria)) - sql += " and " + extraCriteria; - - sql += " order by c.lastname ASC, c.firstname ASC"; - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - @Override - public ClientData retrieveIndividualClient(final Long clientId) { - - try { - this.context.authenticatedUser(); - // TODO - JW include office name in query rather than get the lot - // for office name - List offices = new ArrayList( - officeReadPlatformService.retrieveAllOffices()); - ClientMapper rm = new ClientMapper(offices); - - String sql = "select " + rm.clientSchema() + " where c.id = ? and c.is_deleted=0"; - - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {clientId}); - } catch (EmptyResultDataAccessException e) { - throw new ClientNotFoundException(clientId); - } - } - - @Override - public Collection retrieveAllIndividualClientsForLookup() { - - this.context.authenticatedUser(); - - ClientLookupMapper rm = new ClientLookupMapper(); - - String sql = "select " + rm.clientLookupSchema() + " where c.is_deleted = 0"; - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); - } - - @Override - public ClientData retrieveNewClientDetails() { - - AppUser currentUser = context.authenticatedUser(); - - List offices = new ArrayList( - officeReadPlatformService.retrieveAllOfficesForLookup()); - - final Long officeId = currentUser.getOffice().getId(); - return new ClientData(officeId, new LocalDate(), offices); - } - - - - private static final class ClientMapper implements RowMapper { - - private final List offices; - - public ClientMapper(final List offices) { - this.offices = offices; - } - - public String clientSchema() { - return "c.office_id as officeId, c.id as id, c.firstname as firstname, c.lastname as lastname, c.external_id as externalId, " + - "c.joining_date as joinedDate from m_client c"; - } - - @Override - public ClientData mapRow(final ResultSet rs, final int rowNum) - throws SQLException { - - Long officeId = JdbcSupport.getLong(rs, "officeId"); - Long id = JdbcSupport.getLong(rs, "id"); - String firstname = rs.getString("firstname"); - if (StringUtils.isBlank(firstname)) { - firstname = ""; - } - String lastname = rs.getString("lastname"); - String externalId = rs.getString("externalId"); - LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate"); - - String officeName = fromOfficeList(this.offices, officeId); - - return new ClientData(officeId, officeName, id, firstname, - lastname, externalId, joinedDate); - } - - private String fromOfficeList(final List officeList, - final Long officeId) { - String match = ""; - for (OfficeData office : officeList) { - if (office.getId().equals(officeId)) { - match = office.getName(); - } - } - - return match; - } - } - - private static final class ClientLookupMapper implements RowMapper{ - - public String clientLookupSchema() { - return "c.id as id, c.firstname as firstname, c.lastname as lastname from m_client c"; - } - - @Override - public ClientLookup mapRow(ResultSet rs, int rowNum) throws SQLException { - Long id = rs.getLong("id"); - String firstname = rs.getString("firstname"); - String lastname = rs.getString("lastname"); - if (StringUtils.isBlank(firstname)) { - firstname = ""; - } - return new ClientLookup(id, firstname, lastname); - } - } - - @Override - public ClientAccountSummaryCollectionData retrieveClientAccountDetails(final Long clientId) { - - try { - this.context.authenticatedUser(); - - // Check if client exists - retrieveIndividualClient(clientId); - - List pendingApprovalLoans = new ArrayList(); - List awaitingDisbursalLoans = new ArrayList(); - List openLoans = new ArrayList(); - List closedLoans = new ArrayList(); - - ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper(); - - String sql = "select " + rm.loanAccountSummarySchema() + " where l.client_id = ?"; - - List results = this.jdbcTemplate.query(sql, rm, new Object[] {clientId}); - if (results != null) { - for (ClientAccountSummaryData row : results) { - - LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId()); - - if (statusMapper.isOpen()) { - openLoans.add(row); - } else if (statusMapper.isAwaitingDisbursal()) { - awaitingDisbursalLoans.add(row); - } else if (statusMapper.isPendingApproval()) { - pendingApprovalLoans.add(row); - } else { - closedLoans.add(row); - } - } - } - - List pendingApprovalDepositAccounts = new ArrayList(); - List approvedDepositAccounts = new ArrayList(); -// List openDepositAccounts = new ArrayList(); -// List closedDepositAccounts = new ArrayList(); - - ClientDespoitAccountSummaryDataMapper depositAccountMapper = new ClientDespoitAccountSummaryDataMapper(); - - String depositAccountsSql = "select " + depositAccountMapper.schema() + " where da.client_id = ? and da.is_deleted=0"; - List depositAccountResults = this.jdbcTemplate.query(depositAccountsSql, depositAccountMapper, new Object[] {clientId}); - if (depositAccountResults != null) { - for (ClientAccountSummaryData row : depositAccountResults) { - - if (row.getAccountStatusId() == 100) { - pendingApprovalDepositAccounts.add(row); - } else if (row.getAccountStatusId() == 200) { - approvedDepositAccounts.add(row); - } - } - } - - return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans, - pendingApprovalDepositAccounts, approvedDepositAccounts); - } catch (EmptyResultDataAccessException e) { - throw new ClientNotFoundException(clientId); - } - } - - private static final class ClientLoanAccountSummaryDataMapper implements - RowMapper { - - public String loanAccountSummarySchema() { - - StringBuilder accountsSummary = new StringBuilder("l.id as id, l.external_id as externalId,"); - accountsSummary - .append("l.product_id as productId, lp.name as productName,") - .append("l.loan_status_id as statusId ") - .append("from m_loan l ") - .append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id "); - - return accountsSummary.toString(); - } - - @Override - public ClientAccountSummaryData mapRow(final ResultSet rs, - final int rowNum) throws SQLException { - - Long id = JdbcSupport.getLong(rs, "id"); - String externalId = rs.getString("externalId"); - Long productId = JdbcSupport.getLong(rs, "productId"); - String loanProductName = rs.getString("productName"); - Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId"); - - return new ClientAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId); - } - } - - private static final class ClientDespoitAccountSummaryDataMapper implements RowMapper { - - public String schema() { - - StringBuilder accountsSummary = new StringBuilder("da.id as id, da.external_id as externalId,"); - accountsSummary.append("da.product_id as productId, dp.name as productName,") - .append("da.status_enum as statusId ") - .append("from m_deposit_account da ") - .append("LEFT JOIN m_product_deposit AS dp ON dp.id = da.product_id "); - - return accountsSummary.toString(); - } - - @Override - public ClientAccountSummaryData mapRow(final ResultSet rs, - final int rowNum) throws SQLException { - - Long id = JdbcSupport.getLong(rs, "id"); - String externalId = rs.getString("externalId"); - Long productId = JdbcSupport.getLong(rs, "productId"); - String productName = rs.getString("productName"); - Integer accountStatusId = JdbcSupport.getInteger(rs, "statusId"); - - return new ClientAccountSummaryData(id, externalId, productId, productName, accountStatusId); - } - } - - - - @Override - public NoteData retrieveClientNote(Long clientId, Long noteId) { - - try { - context.authenticatedUser(); - - // Check if client exists - retrieveIndividualClient(clientId); - - // FIXME - use join on sql query to fetch user information for note - // rather than fetching users? - Collection allUsers = this.appUserReadPlatformService - .retrieveAllUsers(); - - NoteMapper noteMapper = new NoteMapper(allUsers); - - String sql = "select " + noteMapper.schema() - + " where n.client_id = ? and n.id = ?"; - - return this.jdbcTemplate.queryForObject(sql, noteMapper, new Object[] {clientId, noteId}); - } catch (EmptyResultDataAccessException e) { - throw new NoteNotFoundException(clientId); - } - } - - @Override - public Collection retrieveAllClientNotes(Long clientId) { - - context.authenticatedUser(); - - // Check if client exists - retrieveIndividualClient(clientId); - - // FIXME - use join on sql query to fetch user information for note - // rather than fetching users? - Collection allUsers = this.appUserReadPlatformService - .retrieveAllUsers(); - - NoteMapper noteMapper = new NoteMapper(allUsers); - - String sql = "select " - + noteMapper.schema() - + " where n.client_id = ? order by n.created_date DESC"; - - return this.jdbcTemplate.query(sql, noteMapper, new Object[] {clientId}); - } - - private static final class NoteMapper implements RowMapper { - - private final Collection allUsers; - - public NoteMapper(Collection allUsers) { - this.allUsers = allUsers; - } - - public String schema() { - return "n.id as id, n.client_id as clientId, n.loan_id as loanId, n.loan_transaction_id as transactionId, n.note_type_enum as noteTypeEnum, n.note as note, " - + "n.created_date as createdDate, n.createdby_id as createdById, n.lastmodified_date as lastModifiedDate, n.lastmodifiedby_id as lastModifiedById" - + " from m_note n"; - } - - @Override - public NoteData mapRow(final ResultSet rs, final int rowNum) - throws SQLException { - - Long id = JdbcSupport.getLong(rs, "id"); - Long clientId = JdbcSupport.getLong(rs, "clientId"); - Long loanId = JdbcSupport.getLong(rs, "loanId"); - Long transactionId = JdbcSupport.getLong(rs, "transactionId"); - Integer noteTypeId = JdbcSupport.getInteger(rs, "noteTypeEnum"); - EnumOptionData noteType = NoteEnumerations.noteType(noteTypeId); - String note = rs.getString("note"); - - DateTime createdDate = JdbcSupport.getDateTime(rs, "createdDate"); - Long createdById = JdbcSupport.getLong(rs, "createdById"); - String createdByUsername = findUserById(createdById, allUsers); - - DateTime lastModifiedDate = JdbcSupport.getDateTime(rs, - "lastModifiedDate"); - Long lastModifiedById = JdbcSupport.getLong(rs, "lastModifiedById"); - String updatedByUsername = findUserById(createdById, allUsers); - - return new NoteData(id, clientId, loanId, transactionId, noteType, - note, createdDate, createdById, createdByUsername, - lastModifiedDate, lastModifiedById, updatedByUsername); - } - - private String findUserById(Long createdById, Collection allUsers) { - String username = ""; - for (AppUserData appUserData : allUsers) { - if (appUserData.getId().equals(createdById)) { - username = appUserData.getUsername(); - break; - } - } - return username; - } - } +package org.mifosng.platform.client.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.mifosng.platform.api.data.*; +import org.mifosng.platform.client.domain.NoteEnumerations; +import org.mifosng.platform.exceptions.ClientNotFoundException; +import org.mifosng.platform.exceptions.NoteNotFoundException; +import org.mifosng.platform.infrastructure.JdbcSupport; +import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; +import org.mifosng.platform.organisation.service.OfficeReadPlatformService; +import org.mifosng.platform.security.PlatformSecurityContext; +import org.mifosng.platform.user.domain.AppUser; +import org.mifosng.platform.user.service.AppUserReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class ClientReadPlatformServiceImpl implements ClientReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + private final OfficeReadPlatformService officeReadPlatformService; + private final AppUserReadPlatformService appUserReadPlatformService; + + @Autowired + public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, + final TenantAwareRoutingDataSource dataSource, + final OfficeReadPlatformService officeReadPlatformService, + final AppUserReadPlatformService appUserReadPlatformService) { + this.context = context; + this.officeReadPlatformService = officeReadPlatformService; + this.appUserReadPlatformService = appUserReadPlatformService; + this.jdbcTemplate = new JdbcTemplate(dataSource); + } + + private String generateOfficeIdInClause(List offices) { + String officeIdsList = ""; + for (int i = 0; i < offices.size(); i++) { + Long id = offices.get(i).getId(); + if (i == 0) { + officeIdsList = id.toString(); + } else { + officeIdsList += "," + id.toString(); + } + } + return officeIdsList; + } + + @Override + public Collection retrieveAllIndividualClients(final String extraCriteria) { + + this.context.authenticatedUser(); + + List offices = new ArrayList(officeReadPlatformService.retrieveAllOffices()); + String officeIdsList = generateOfficeIdInClause(offices); + + ClientMapper rm = new ClientMapper(offices); + + String sql = "select " + rm.clientSchema() + " where c.office_id in (" + officeIdsList + ") and c.is_deleted=0"; + + if (StringUtils.isNotBlank(extraCriteria)) + sql += " and " + extraCriteria; + + sql += " order by c.lastname ASC, c.firstname ASC"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public ClientData retrieveIndividualClient(final Long clientId) { + + try { + this.context.authenticatedUser(); + // TODO - JW include office name in query rather than get the lot + // for office name + List offices = new ArrayList( + officeReadPlatformService.retrieveAllOffices()); + ClientMapper rm = new ClientMapper(offices); + + String sql = "select " + rm.clientSchema() + " where c.id = ? and c.is_deleted=0"; + + return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {clientId}); + } catch (EmptyResultDataAccessException e) { + throw new ClientNotFoundException(clientId); + } + } + + @Override + public Collection retrieveAllIndividualClientsForLookup() { + + this.context.authenticatedUser(); + + ClientLookupMapper rm = new ClientLookupMapper(); + + String sql = "select " + rm.clientLookupSchema() + " where c.is_deleted = 0"; + + return this.jdbcTemplate.query(sql, rm, new Object[] {}); + } + + @Override + public ClientData retrieveNewClientDetails() { + + AppUser currentUser = context.authenticatedUser(); + + List offices = new ArrayList( + officeReadPlatformService.retrieveAllOfficesForLookup()); + + final Long officeId = currentUser.getOffice().getId(); + return new ClientData(officeId, new LocalDate(), offices); + } + + + + private static final class ClientMapper implements RowMapper { + + private final List offices; + + public ClientMapper(final List offices) { + this.offices = offices; + } + + public String clientSchema() { + return "c.office_id as officeId, c.id as id, c.firstname as firstname, c.lastname as lastname, c.display_name as displayName, " + + "c.external_id as externalId, c.joining_date as joinedDate from m_client c"; + } + + @Override + public ClientData mapRow(final ResultSet rs, final int rowNum) + throws SQLException { + + Long officeId = JdbcSupport.getLong(rs, "officeId"); + Long id = JdbcSupport.getLong(rs, "id"); + String firstname = rs.getString("firstname"); + if (StringUtils.isBlank(firstname)) { + firstname = ""; + } + String lastname = rs.getString("lastname"); + String displayName = rs.getString("displayName"); + String externalId = rs.getString("externalId"); + LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate"); + + String officeName = fromOfficeList(this.offices, officeId); + + return new ClientData(officeId, officeName, id, firstname, + lastname, displayName, externalId, joinedDate); + } + + private String fromOfficeList(final List officeList, + final Long officeId) { + String match = ""; + for (OfficeData office : officeList) { + if (office.getId().equals(officeId)) { + match = office.getName(); + } + } + + return match; + } + } + + private static final class ClientLookupMapper implements RowMapper{ + + public String clientLookupSchema() { + return "c.id as id, c.firstname as firstname, c.lastname as lastname from m_client c"; + } + + @Override + public ClientLookup mapRow(ResultSet rs, int rowNum) throws SQLException { + Long id = rs.getLong("id"); + String firstname = rs.getString("firstname"); + String lastname = rs.getString("lastname"); + if (StringUtils.isBlank(firstname)) { + firstname = ""; + } + return new ClientLookup(id, firstname, lastname); + } + } + + @Override + public ClientAccountSummaryCollectionData retrieveClientAccountDetails(final Long clientId) { + + try { + this.context.authenticatedUser(); + + // Check if client exists + retrieveIndividualClient(clientId); + + List pendingApprovalLoans = new ArrayList(); + List awaitingDisbursalLoans = new ArrayList(); + List openLoans = new ArrayList(); + List closedLoans = new ArrayList(); + + ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper(); + + String sql = "select " + rm.loanAccountSummarySchema() + " where l.client_id = ?"; + + List results = this.jdbcTemplate.query(sql, rm, new Object[] {clientId}); + if (results != null) { + for (ClientAccountSummaryData row : results) { + + LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId()); + + if (statusMapper.isOpen()) { + openLoans.add(row); + } else if (statusMapper.isAwaitingDisbursal()) { + awaitingDisbursalLoans.add(row); + } else if (statusMapper.isPendingApproval()) { + pendingApprovalLoans.add(row); + } else { + closedLoans.add(row); + } + } + } + + List pendingApprovalDepositAccounts = new ArrayList(); + List approvedDepositAccounts = new ArrayList(); +// List openDepositAccounts = new ArrayList(); +// List closedDepositAccounts = new ArrayList(); + + ClientDespoitAccountSummaryDataMapper depositAccountMapper = new ClientDespoitAccountSummaryDataMapper(); + + String depositAccountsSql = "select " + depositAccountMapper.schema() + " where da.client_id = ? and da.is_deleted=0"; + List depositAccountResults = this.jdbcTemplate.query(depositAccountsSql, depositAccountMapper, new Object[] {clientId}); + if (depositAccountResults != null) { + for (ClientAccountSummaryData row : depositAccountResults) { + + if (row.getAccountStatusId() == 100) { + pendingApprovalDepositAccounts.add(row); + } else if (row.getAccountStatusId() == 200) { + approvedDepositAccounts.add(row); + } + } + } + + return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans, + pendingApprovalDepositAccounts, approvedDepositAccounts); + } catch (EmptyResultDataAccessException e) { + throw new ClientNotFoundException(clientId); + } + } + + private static final class ClientLoanAccountSummaryDataMapper implements + RowMapper { + + public String loanAccountSummarySchema() { + + StringBuilder accountsSummary = new StringBuilder("l.id as id, l.external_id as externalId,"); + accountsSummary + .append("l.product_id as productId, lp.name as productName,") + .append("l.loan_status_id as statusId ") + .append("from m_loan l ") + .append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id "); + + return accountsSummary.toString(); + } + + @Override + public ClientAccountSummaryData mapRow(final ResultSet rs, + final int rowNum) throws SQLException { + + Long id = JdbcSupport.getLong(rs, "id"); + String externalId = rs.getString("externalId"); + Long productId = JdbcSupport.getLong(rs, "productId"); + String loanProductName = rs.getString("productName"); + Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId"); + + return new ClientAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId); + } + } + + private static final class ClientDespoitAccountSummaryDataMapper implements RowMapper { + + public String schema() { + + StringBuilder accountsSummary = new StringBuilder("da.id as id, da.external_id as externalId,"); + accountsSummary.append("da.product_id as productId, dp.name as productName,") + .append("da.status_enum as statusId ") + .append("from m_deposit_account da ") + .append("LEFT JOIN m_product_deposit AS dp ON dp.id = da.product_id "); + + return accountsSummary.toString(); + } + + @Override + public ClientAccountSummaryData mapRow(final ResultSet rs, + final int rowNum) throws SQLException { + + Long id = JdbcSupport.getLong(rs, "id"); + String externalId = rs.getString("externalId"); + Long productId = JdbcSupport.getLong(rs, "productId"); + String productName = rs.getString("productName"); + Integer accountStatusId = JdbcSupport.getInteger(rs, "statusId"); + + return new ClientAccountSummaryData(id, externalId, productId, productName, accountStatusId); + } + } + + + + @Override + public NoteData retrieveClientNote(Long clientId, Long noteId) { + + try { + context.authenticatedUser(); + + // Check if client exists + retrieveIndividualClient(clientId); + + // FIXME - use join on sql query to fetch user information for note + // rather than fetching users? + Collection allUsers = this.appUserReadPlatformService + .retrieveAllUsers(); + + NoteMapper noteMapper = new NoteMapper(allUsers); + + String sql = "select " + noteMapper.schema() + + " where n.client_id = ? and n.id = ?"; + + return this.jdbcTemplate.queryForObject(sql, noteMapper, new Object[] {clientId, noteId}); + } catch (EmptyResultDataAccessException e) { + throw new NoteNotFoundException(clientId); + } + } + + @Override + public Collection retrieveAllClientNotes(Long clientId) { + + context.authenticatedUser(); + + // Check if client exists + retrieveIndividualClient(clientId); + + // FIXME - use join on sql query to fetch user information for note + // rather than fetching users? + Collection allUsers = this.appUserReadPlatformService + .retrieveAllUsers(); + + NoteMapper noteMapper = new NoteMapper(allUsers); + + String sql = "select " + + noteMapper.schema() + + " where n.client_id = ? order by n.created_date DESC"; + + return this.jdbcTemplate.query(sql, noteMapper, new Object[] {clientId}); + } + + private static final class NoteMapper implements RowMapper { + + private final Collection allUsers; + + public NoteMapper(Collection allUsers) { + this.allUsers = allUsers; + } + + public String schema() { + return "n.id as id, n.client_id as clientId, n.loan_id as loanId, n.loan_transaction_id as transactionId, n.note_type_enum as noteTypeEnum, n.note as note, " + + "n.created_date as createdDate, n.createdby_id as createdById, n.lastmodified_date as lastModifiedDate, n.lastmodifiedby_id as lastModifiedById" + + " from m_note n"; + } + + @Override + public NoteData mapRow(final ResultSet rs, final int rowNum) + throws SQLException { + + Long id = JdbcSupport.getLong(rs, "id"); + Long clientId = JdbcSupport.getLong(rs, "clientId"); + Long loanId = JdbcSupport.getLong(rs, "loanId"); + Long transactionId = JdbcSupport.getLong(rs, "transactionId"); + Integer noteTypeId = JdbcSupport.getInteger(rs, "noteTypeEnum"); + EnumOptionData noteType = NoteEnumerations.noteType(noteTypeId); + String note = rs.getString("note"); + + DateTime createdDate = JdbcSupport.getDateTime(rs, "createdDate"); + Long createdById = JdbcSupport.getLong(rs, "createdById"); + String createdByUsername = findUserById(createdById, allUsers); + + DateTime lastModifiedDate = JdbcSupport.getDateTime(rs, + "lastModifiedDate"); + Long lastModifiedById = JdbcSupport.getLong(rs, "lastModifiedById"); + String updatedByUsername = findUserById(createdById, allUsers); + + return new NoteData(id, clientId, loanId, transactionId, noteType, + note, createdDate, createdById, createdByUsername, + lastModifiedDate, lastModifiedById, updatedByUsername); + } + + private String findUserById(Long createdById, Collection allUsers) { + String username = ""; + for (AppUserData appUserData : allUsers) { + if (appUserData.getId().equals(createdById)) { + username = appUserData.getUsername(); + break; + } + } + return username; + } + } } \ No newline at end of file