refactor client accounts to be returned as list of accounts broken up into loans and savings rather than in collections by status.

This commit is contained in:
Keith Woodlock
2013-07-18 19:49:47 +01:00
parent a3dc8ff378
commit 26bed02096
11 changed files with 226 additions and 412 deletions
+89 -95
View File
@@ -2329,19 +2329,16 @@ Request Body:
<a id="clients_loansummary" name="clients_loansummary" class="old-syle-anchor">&nbsp;</a>
<div class="method-section">
<div class="method-description">
<h4>Retrieve a Client's Loan Account Summary</h4>
<h4>Retrieve client accounts overview</h4>
<p>
An example of how a loan portfolio summary can be provided. This
one contains quite a bit of redundant data (like the counts) and
is requested in a specific use case of the Individual Lending User
Interface.<br> However, it is quite reasonable to add
resources like this to simplify User Interface development.
is requested in a specific use case of the reference application.<br> It is quite reasonable to add resources like this to simplify User Interface development.
</p>
<p>Example Requests:</p>
<div class=apiClick>clients/1/loans</div>
<div class=apiClick>clients/1/accounts</div>
<br>
<br>
<div class=apiClick>clients/1/loans?fields=openLoans,closedLoans,activeLoanCount</div>
<div class=apiClick>clients/1/accounts?fields=loanAccounts,savingsAccounts</div>
</div>
<div class="method-example">
<code class="method-declaration">
@@ -2349,112 +2346,109 @@ GET https://DomainName/api/v1/clients/{clientId}/loans
</code>
<code class="method-response">
{
"anyLoanCount": 9,
"pendingApprovalLoanCount": 4,
"pendingApprovalLoans": [
"loanAccounts": [
{
"id": 48,
"accountNo": "48",
"id": 1,
"accountNo": "000000001",
"externalId": "456",
"productId": 1,
"productName": "PORetailLoan",
"status": {
"id": 100,
"code": "loanStatusType.submitted.and.pending.approval",
"value": "Submitted and pending approval"
}
},
{
"id": 50,
"accountNo": "50",
"productId": 1,
"productName": "PORetailLoan",
"status": {
"id": 100,
"code": "loanStatusType.submitted.and.pending.approval",
"value": "Submitted and pending approval"
}
},
{
"id": 51,
"accountNo": "51",
"productId": 1,
"productName": "PORetailLoan",
"status": {
"id": 100,
"code": "loanStatusType.submitted.and.pending.approval",
"value": "Submitted and pending approval"
}
},
{
"id": 62,
"accountNo": "62",
"productId": 3,
"productName": "Further Loan Product",
"status": {
"id": 100,
"code": "loanStatusType.submitted.and.pending.approval",
"value": "Submitted and pending approval"
}
}
],
"activeLoanCount": 2,
"openLoans": [
{
"id": 46,
"accountNo": "46",
"productId": 1,
"productName": "PORetailLoan",
"productName": "TestOne",
"status": {
"id": 300,
"code": "loanStatusType.active",
"value": "Active"
}
},
{
"id": 60,
"accountNo": "60",
"productId": 1,
"productName": "PORetailLoan",
"status": {
"id": 300,
"code": "loanStatusType.active",
"value": "Active"
}
"value": "Active",
"pendingApproval": false,
"waitingForDisbursal": false,
"active": true,
"closedObligationsMet": false,
"closedWrittenOff": false,
"closedRescheduled": false,
"closed": false,
"overpaid": false
},
"loanType": {
"id": 1,
"code": "loanType.individual",
"value": "Individual"
},
"loanCycle": 1
}
],
"closedLoanCount": 3,
"closedLoans": [
"savingsAccounts": [
{
"id": 22,
"accountNo": "22",
"productId": 1,
"productName": "PORetailLoan",
"id": 7,
"accountNo": "000000007",
"productId": 2,
"productName": "Other product",
"status": {
"id": 700,
"code": "loanStatusType.overpaid",
"value": "Overpaid"
"id": 100,
"code": "savingsAccountStatusType.submitted.and.pending.approval",
"value": "Submitted and pending approval",
"submittedAndPendingApproval": true,
"approved": false,
"rejected": false,
"withdrawnByApplicant": false,
"active": false,
"closed": false
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
}
},
{
"id": 33,
"accountNo": "33",
"id": 6,
"accountNo": "000000006",
"productId": 1,
"productName": "PORetailLoan",
"productName": "Passbook Savings",
"status": {
"id": 601,
"code": "loanStatusType.closed.written.off",
"value": "Closed (written off)"
}
"id": 300,
"code": "savingsAccountStatusType.active",
"value": "Active",
"submittedAndPendingApproval": false,
"approved": false,
"rejected": false,
"withdrawnByApplicant": false,
"active": true,
"closed": false
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
},
"accountBalance": 1828.03
},
{
"id": 44,
"accountNo": "44",
"id": 5,
"accountNo": "000000005",
"productId": 1,
"productName": "PORetailLoan",
"productName": "Passbook Savings",
"status": {
"id": 600,
"code": "loanStatusType.closed.obligations.met",
"value": "Closed (obligations met)"
"id": 400,
"code": "savingsAccountStatusType.withdrawn.by.applicant",
"value": "Withdrawn by applicant",
"submittedAndPendingApproval": false,
"approved": false,
"rejected": false,
"withdrawnByApplicant": true,
"active": false,
"closed": true
},
"currency": {
"code": "USD",
"name": "US Dollar",
"decimalPlaces": 2,
"displaySymbol": "$",
"nameCode": "currency.USD",
"displayLabel": "US Dollar ($)"
}
}
]
@@ -8,7 +8,7 @@ package org.mifosplatform.organisation.staff.data;
import java.util.Collection;
import java.util.List;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientLoanAccountSummaryData;
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData;
/**
@@ -31,7 +31,7 @@ public class StaffAccountSummaryCollectionData {
private final Long id;
private final String displayName;
private Collection<ClientAccountSummaryData> loans;
private Collection<ClientLoanAccountSummaryData> loans;
public ClientSummary(Long id, String displayName) {
this.id = id;
@@ -46,11 +46,11 @@ public class StaffAccountSummaryCollectionData {
return displayName;
}
public Collection<ClientAccountSummaryData> getLoans() {
public Collection<ClientLoanAccountSummaryData> getLoans() {
return loans;
}
public void setLoans(Collection<ClientAccountSummaryData> loans) {
public void setLoans(Collection<ClientLoanAccountSummaryData> loans) {
this.loans = loans;
}
}
@@ -115,7 +115,7 @@ public class ClientsApiResource {
@Path("{clientId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo,
public String retrieveOne(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly) {
context.authenticatedUser().validateHasReadPermission(ClientApiConstants.CLIENT_RESOURCE_NAME);
@@ -124,7 +124,8 @@ public class ClientsApiResource {
ClientData clientData = this.clientReadPlatformService.retrieveOne(clientId);
if (settings.isTemplate()) {
final ClientData templateData = this.clientReadPlatformService.retrieveTemplate(clientData.officeId(), staffInSelectedOfficeOnly);
final ClientData templateData = this.clientReadPlatformService.retrieveTemplate(clientData.officeId(),
staffInSelectedOfficeOnly);
clientData = ClientData.templateOnTop(clientData, templateData);
}
@@ -215,7 +216,7 @@ public class ClientsApiResource {
}
@GET
@Path("{clientId}/loans")
@Path("{clientId}/accounts")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveAssociatedAccounts(@PathParam("clientId") final Long clientId, @Context final UriInfo uriInfo) {
@@ -224,12 +225,7 @@ public class ClientsApiResource {
final ClientAccountSummaryCollectionData clientAccount = this.clientReadPlatformService.retrieveClientAccountDetails(clientId);
final Set<String> CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("pendingApprovalLoans",
"awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount",
"awaitingDisbursalLoanCount", "activeLoanCount", "closedLoanCount", "pendingApprovalSavingAccountsCount",
"pendingApprovalSavingAccounts", "approvedSavingAccountsCount", "approvedSavingAccounts",
"withdrawnByClientSavingAccountsCount", "withdrawnByClientSavingAccounts", "rejectedSavingAccountsCount",
"rejectedSavingAccounts", "closedSavingAccountsCount", "closedSavingAccounts"));
final Set<String> CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("loanAccounts", "savingsAccounts"));
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.clientAccountSummaryToApiJsonSerializer.serialize(settings, clientAccount, CLIENT_ACCOUNTS_DATA_PARAMETERS);
@@ -13,129 +13,18 @@ import java.util.Collection;
public class ClientAccountSummaryCollectionData {
@SuppressWarnings("unused")
private final Integer anyLoanCount;
private final Integer pendingApprovalLoanCount;
private final Collection<ClientAccountSummaryData> pendingApprovalLoans;
private final Integer awaitingDisbursalLoanCount;
private final Collection<ClientAccountSummaryData> awaitingDisbursalLoans;
private final Integer activeLoanCount;
private final Collection<ClientAccountSummaryData> openLoans;
private final Integer closedLoanCount;
private final Collection<ClientAccountSummaryData> closedLoans;
private final Collection<ClientLoanAccountSummaryData> loanAccounts;
@SuppressWarnings("unused")
private final Integer pendingApprovalDepositAccountsCount;
private final Collection<ClientAccountSummaryData> pendingApprovalDepositAccounts;
@SuppressWarnings("unused")
private final Integer approvedDepositAccountsCount;
private final Collection<ClientAccountSummaryData> approvedDepositAccounts;
@SuppressWarnings("unused")
private final Integer withdrawnByClientDepositAccountsCount;
private final Collection<ClientAccountSummaryData> withdrawnByClientDepositAccounts;
@SuppressWarnings("unused")
private final Integer closedDepositAccountsCount;
private final Collection<ClientAccountSummaryData> closedDepositAccounts;
@SuppressWarnings("unused")
private final Integer rejectedDepositAccountsCount;
private final Collection<ClientAccountSummaryData> rejectedDepositAccounts;
@SuppressWarnings("unused")
private final Integer preclosedDepositAccountsCount;
private final Collection<ClientAccountSummaryData> preclosedDepositAccounts;
@SuppressWarnings("unused")
private final Integer maturedDepositAccountsCount;
private final Collection<ClientAccountSummaryData> maturedDepositAccounts;
@SuppressWarnings("unused")
private final Integer pendingApprovalSavingAccountsCount;
private final Collection<ClientAccountSummaryData> pendingApprovalSavingAccounts;
@SuppressWarnings("unused")
private final Integer approvedSavingAccountsCount;
private final Collection<ClientAccountSummaryData> approvedSavingAccounts;
@SuppressWarnings("unused")
private final Integer withdrawnByClientSavingAccountsCount;
private final Collection<ClientAccountSummaryData> withdrawnByClientSavingAccounts;
@SuppressWarnings("unused")
private final Integer rejectedSavingAccountsCount;
private final Collection<ClientAccountSummaryData> rejectedSavingAccounts;
@SuppressWarnings("unused")
private final Integer closedSavingAccountsCount;
private final Collection<ClientAccountSummaryData> closedSavingAccounts;
private final Collection<ClientSavingsAccountSummaryData> savingsAccounts;
public ClientAccountSummaryCollectionData(final Collection<ClientAccountSummaryData> pendingApprovalLoans,
final Collection<ClientAccountSummaryData> awaitingDisbursalLoans, final Collection<ClientAccountSummaryData> openLoans,
final Collection<ClientAccountSummaryData> closedLoans,
final Collection<ClientAccountSummaryData> pendingApprovalDepositAccounts,
final Collection<ClientAccountSummaryData> approvedDepositAccounts,
final Collection<ClientAccountSummaryData> withdrawnByClientDepositAccounts,
final Collection<ClientAccountSummaryData> rejectedDepositAccounts,
final Collection<ClientAccountSummaryData> closedDepositAccounts,
final Collection<ClientAccountSummaryData> preclosedDepositAccounts,
final Collection<ClientAccountSummaryData> maturedDepositAccounts,
final Collection<ClientAccountSummaryData> pendingApprovalSavingAccounts,
final Collection<ClientAccountSummaryData> approvedSavingAccounts,
final Collection<ClientAccountSummaryData> withdrawnByClientSavingAccounts,
final Collection<ClientAccountSummaryData> rejectedSavingAccounts,
final Collection<ClientAccountSummaryData> closedSavingAccounts) {
this.pendingApprovalLoans = defaultIfEmpty(pendingApprovalLoans);
this.awaitingDisbursalLoans = defaultIfEmpty(awaitingDisbursalLoans);
this.openLoans = defaultIfEmpty(openLoans);
this.closedLoans = defaultIfEmpty(closedLoans);
this.pendingApprovalDepositAccounts = defaultIfEmpty(pendingApprovalDepositAccounts);
this.approvedDepositAccounts = defaultIfEmpty(approvedDepositAccounts);
this.withdrawnByClientDepositAccounts = defaultIfEmpty(withdrawnByClientDepositAccounts);
this.closedDepositAccounts = defaultIfEmpty(closedDepositAccounts);
this.rejectedDepositAccounts = defaultIfEmpty(rejectedDepositAccounts);
this.preclosedDepositAccounts = defaultIfEmpty(preclosedDepositAccounts);
this.maturedDepositAccounts = defaultIfEmpty(maturedDepositAccounts);
this.pendingApprovalSavingAccounts = defaultIfEmpty(pendingApprovalSavingAccounts);
this.approvedSavingAccounts = defaultIfEmpty(approvedSavingAccounts);
this.withdrawnByClientSavingAccounts = defaultIfEmpty(withdrawnByClientSavingAccounts);
this.rejectedSavingAccounts = defaultIfEmpty(rejectedSavingAccounts);
this.closedSavingAccounts = defaultIfEmpty(closedSavingAccounts);
this.pendingApprovalLoanCount = defaultToNullIfEmpty(this.pendingApprovalLoans);
this.awaitingDisbursalLoanCount = defaultToNullIfEmpty(this.awaitingDisbursalLoans);
this.activeLoanCount = defaultToNullIfEmpty(this.openLoans);
this.closedLoanCount = defaultToNullIfEmpty(this.closedLoans);
this.pendingApprovalDepositAccountsCount = defaultToNullIfEmpty(this.pendingApprovalDepositAccounts);
this.approvedDepositAccountsCount = defaultToNullIfEmpty(this.approvedDepositAccounts);
this.withdrawnByClientDepositAccountsCount = defaultToNullIfEmpty(this.withdrawnByClientDepositAccounts);
this.closedDepositAccountsCount = defaultToNullIfEmpty(this.closedDepositAccounts);
this.rejectedDepositAccountsCount = defaultToNullIfEmpty(this.rejectedDepositAccounts);
this.preclosedDepositAccountsCount = defaultToNullIfEmpty(this.preclosedDepositAccounts);
this.maturedDepositAccountsCount = defaultToNullIfEmpty(this.maturedDepositAccounts);
this.pendingApprovalSavingAccountsCount = defaultToNullIfEmpty(this.pendingApprovalSavingAccounts);
this.approvedSavingAccountsCount = defaultToNullIfEmpty(this.approvedSavingAccounts);
this.withdrawnByClientSavingAccountsCount = defaultToNullIfEmpty(this.withdrawnByClientSavingAccounts);
this.rejectedSavingAccountsCount = defaultToNullIfEmpty(this.rejectedSavingAccounts);
this.closedSavingAccountsCount = defaultToNullIfEmpty(this.closedSavingAccounts);
this.anyLoanCount = countOf(this.pendingApprovalLoanCount, this.awaitingDisbursalLoanCount, this.activeLoanCount,
this.closedLoanCount);
public ClientAccountSummaryCollectionData(final Collection<ClientLoanAccountSummaryData> loanAccounts,
final Collection<ClientSavingsAccountSummaryData> savingsAccounts) {
this.loanAccounts = defaultIfEmpty(loanAccounts);
this.savingsAccounts = savingsAccounts;
}
private Integer countOf(final Integer... objects) {
Integer count = Integer.valueOf(0);
for (Integer value : objects) {
if (value != null) {
count = count + value;
}
}
return count;
}
private Integer defaultToNullIfEmpty(final Collection<ClientAccountSummaryData> collection) {
Integer count = null;
if (defaultIfEmpty(collection) != null) {
count = collection.size();
}
return count;
}
private Collection<ClientAccountSummaryData> defaultIfEmpty(final Collection<ClientAccountSummaryData> collection) {
Collection<ClientAccountSummaryData> returnCollection = null;
private Collection<ClientLoanAccountSummaryData> defaultIfEmpty(final Collection<ClientLoanAccountSummaryData> collection) {
Collection<ClientLoanAccountSummaryData> returnCollection = null;
if (collection != null && !collection.isEmpty()) {
returnCollection = collection;
}
@@ -1,87 +0,0 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.client.data;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
/**
* Immutable data object for client loan accounts.
*/
public class ClientAccountSummaryData {
@SuppressWarnings("unused")
private final Long id;
@SuppressWarnings("unused")
private final String accountNo;
@SuppressWarnings("unused")
private final String externalId;
@SuppressWarnings("unused")
private final Long productId;
@SuppressWarnings("unused")
private final String productName;
private final Integer accountStatusId;
private final LoanStatusEnumData status;
@SuppressWarnings("unused")
private final EnumOptionData loanType;
private final SavingsAccountStatusEnumData savingAccountStatus;
@SuppressWarnings("unused")
private final Integer loanCycle;
public ClientAccountSummaryData(final Long id, final String externalId, final Long productId, final String loanProductName,
final Integer loanStatusId) {
this.id = id;
this.accountNo = null;
this.externalId = externalId;
this.productId = productId;
this.productName = loanProductName;
this.accountStatusId = loanStatusId;
this.status = null;
this.loanType = null;
this.savingAccountStatus = null;
this.loanCycle = null;
}
public ClientAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
final String loanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType, final Integer loanCycle) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = loanProductName;
this.accountStatusId = null;
this.status = loanStatus;
this.loanType = loanType;
this.savingAccountStatus = null;
this.loanCycle = loanCycle;
}
public ClientAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
final String loanProductName, final SavingsAccountStatusEnumData savingAccountStatus) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = loanProductName;
this.accountStatusId = null;
this.status = null;
this.loanType = null;
this.savingAccountStatus = savingAccountStatus;
this.loanCycle = null;
}
public Integer accountStatusId() {
Integer accountStatus = this.accountStatusId;
if (accountStatus == null && this.status != null) {
accountStatus = this.status.id().intValue();
} else if (accountStatus == null && this.savingAccountStatus != null) {
accountStatus = this.savingAccountStatus.id().intValue();
}
return accountStatus;
}
}
@@ -0,0 +1,37 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.client.data;
import org.mifosplatform.infrastructure.core.data.EnumOptionData;
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
/**
* Immutable data object for client loan accounts.
*/
@SuppressWarnings("unused")
public class ClientLoanAccountSummaryData {
private final Long id;
private final String accountNo;
private final String externalId;
private final Long productId;
private final String productName;
private final LoanStatusEnumData status;
private final EnumOptionData loanType;
private final Integer loanCycle;
public ClientLoanAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
final String loanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType, final Integer loanCycle) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = loanProductName;
this.status = loanStatus;
this.loanType = loanType;
this.loanCycle = loanCycle;
}
}
@@ -0,0 +1,40 @@
/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.portfolio.client.data;
import java.math.BigDecimal;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
/**
* Immutable data object for client savings accounts.
*/
@SuppressWarnings("unused")
public class ClientSavingsAccountSummaryData {
private final Long id;
private final String accountNo;
private final String externalId;
private final Long productId;
private final String productName;
private final SavingsAccountStatusEnumData status;
private final CurrencyData currency;
private final BigDecimal accountBalance;
public ClientSavingsAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId,
final String productName, final SavingsAccountStatusEnumData status, final CurrencyData currency,
final BigDecimal accountBalance) {
this.id = id;
this.accountNo = accountNo;
this.externalId = externalId;
this.productId = productId;
this.productName = productName;
this.status = status;
this.currency = currency;
this.accountBalance = accountBalance;
}
}
@@ -9,7 +9,7 @@ import java.util.Collection;
import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientLoanAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.group.service.SearchParameters;
@@ -27,7 +27,7 @@ public interface ClientReadPlatformService {
ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId);
Collection<ClientAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId);
Collection<ClientLoanAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId);
ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey);
@@ -5,6 +5,7 @@
*/
package org.mifosplatform.portfolio.client.service;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
@@ -22,13 +23,15 @@ import org.mifosplatform.infrastructure.core.service.Page;
import org.mifosplatform.infrastructure.core.service.PaginationHelper;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.organisation.staff.service.StaffReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientLoanAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.data.ClientSavingsAccountSummaryData;
import org.mifosplatform.portfolio.client.domain.ClientEnumerations;
import org.mifosplatform.portfolio.client.domain.ClientStatus;
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
@@ -37,7 +40,6 @@ import org.mifosplatform.portfolio.group.service.SearchParameters;
import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData;
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData;
import org.mifosplatform.portfolio.savings.service.SavingStatusMapper;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
@@ -61,6 +63,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
private final ClientLookupMapper lookupMapper = new ClientLookupMapper();
private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper();
private final ParentGroupsMapper clientGroupsMapper = new ParentGroupsMapper();
private final ClientSavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new ClientSavingsAccountSummaryDataMapper();
@Autowired
public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
@@ -224,7 +227,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final String sql = "select " + this.lookupMapper.schema() + " where c.office_id = ? and c.status_enum != ?";
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { officeId, ClientStatus.CLOSED.getValue()});
return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { officeId, ClientStatus.CLOSED.getValue() });
}
@Override
@@ -394,81 +397,29 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public ClientAccountSummaryCollectionData retrieveClientAccountDetails(final Long clientId) {
try {
this.context.authenticatedUser();
// Check if client exists
retrieveOne(clientId);
List<ClientAccountSummaryData> pendingApprovalLoans = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> awaitingDisbursalLoans = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> openLoans = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> closedLoans = new ArrayList<ClientAccountSummaryData>();
ClientLoanAccountSummaryDataMapper rm = new ClientLoanAccountSummaryDataMapper();
String sql = "select " + rm.loanAccountSummarySchema() + " where l.client_id = ?";
List<ClientAccountSummaryData> results = this.jdbcTemplate.query(sql, rm, new Object[] { clientId });
if (results != null) {
for (ClientAccountSummaryData row : results) {
List<ClientLoanAccountSummaryData> allLoanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { clientId });
LoanStatusMapper statusMapper = new LoanStatusMapper(row.accountStatusId());
final String savingsSql = "select " + this.savingsAccountSummaryDataMapper.schema()
+ " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC";
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<ClientAccountSummaryData> pendingApprovalDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> approvedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> withdrawnByClientDespositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> closedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> rejectedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> preclosedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> maturedDepositAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> pendingApprovalSavingAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> approvedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> withdrawnByClientSavingAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> rejectedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
List<ClientAccountSummaryData> closedSavingAccounts = new ArrayList<ClientAccountSummaryData>();
final ClientSavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new ClientSavingsAccountSummaryDataMapper();
final String savingsSql = "select " + savingsAccountSummaryDataMapper.schema() + " where sa.client_id = ?";
final List<ClientAccountSummaryData> savingsAccounts = this.jdbcTemplate.query(savingsSql, savingsAccountSummaryDataMapper,
new Object[] { clientId });
if (results != null) {
for (ClientAccountSummaryData row : savingsAccounts) {
SavingStatusMapper statusMapper = new SavingStatusMapper(row.accountStatusId());
if (statusMapper.isOpen()) {
approvedSavingAccounts.add(row);
} else {
pendingApprovalSavingAccounts.add(row);
}
}
}
return new ClientAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans,
pendingApprovalDepositAccounts, approvedDepositAccounts, withdrawnByClientDespositAccounts, rejectedDepositAccounts,
closedDepositAccounts, preclosedDepositAccounts, maturedDepositAccounts, pendingApprovalSavingAccounts,
approvedSavingAccounts, withdrawnByClientSavingAccounts, rejectedSavingAccounts, closedSavingAccounts);
final List<ClientSavingsAccountSummaryData> allSavingsAccounts = this.jdbcTemplate.query(savingsSql,
savingsAccountSummaryDataMapper, new Object[] { clientId });
return new ClientAccountSummaryCollectionData(allLoanAccounts, allSavingsAccounts);
} catch (EmptyResultDataAccessException e) {
throw new ClientNotFoundException(clientId);
}
}
@Override
public Collection<ClientAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(final Long clientId, final Long loanOfficerId) {
public Collection<ClientLoanAccountSummaryData> retrieveClientLoanAccountsByLoanOfficerId(final Long clientId, final Long loanOfficerId) {
this.context.authenticatedUser();
@@ -479,21 +430,26 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
String sql = "select " + rm.loanAccountSummarySchema() + " where l.client_id = ? and l.loan_officer_id = ?";
List<ClientAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { clientId, loanOfficerId });
List<ClientLoanAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { clientId, loanOfficerId });
return loanAccounts;
}
private static final class ClientSavingsAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
private static final class ClientSavingsAccountSummaryDataMapper implements RowMapper<ClientSavingsAccountSummaryData> {
final String schemaSql;
public ClientSavingsAccountSummaryDataMapper() {
StringBuilder accountsSummary = new StringBuilder();
accountsSummary.append("sa.id as id, sa.account_no as accountNo, sa.external_id as externalId, sa.status_enum as statusEnum, ");
accountsSummary.append("sa.account_balance_derived as accountBalance, ");
accountsSummary.append("sa.currency_code as currencyCode, sa.currency_digits as currencyDigits, ");
accountsSummary.append("curr.name as currencyName, curr.internationalized_name_code as currencyNameCode, ");
accountsSummary.append("curr.display_symbol as currencyDisplaySymbol, ");
accountsSummary.append("sa.product_id as productId, p.name as productName ");
accountsSummary.append("from m_savings_account sa ");
accountsSummary.append("join m_savings_product as p on p.id = sa.product_id ");
accountsSummary.append("join m_currency curr on curr.code = sa.currency_code ");
this.schemaSql = accountsSummary.toString();
}
@@ -503,35 +459,43 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
}
@Override
public ClientAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
public ClientSavingsAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = JdbcSupport.getLong(rs, "id");
final String accountNo = rs.getString("accountNo");
final String externalId = rs.getString("externalId");
final Long productId = JdbcSupport.getLong(rs, "productId");
final String savingsProductName = rs.getString("productName");
final String productName = rs.getString("productName");
final Integer statusId = JdbcSupport.getInteger(rs, "statusEnum");
final SavingsAccountStatusEnumData savingAccountStatus = SavingsEnumerations.status(statusId);
final BigDecimal accountBalance = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "accountBalance");
final SavingsAccountStatusEnumData status = SavingsEnumerations.status(statusId);
return new ClientAccountSummaryData(id, accountNo, externalId, productId, savingsProductName, savingAccountStatus);
final String currencyCode = rs.getString("currencyCode");
final String currencyName = rs.getString("currencyName");
final String currencyNameCode = rs.getString("currencyNameCode");
final String currencyDisplaySymbol = rs.getString("currencyDisplaySymbol");
final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits");
final CurrencyData currency = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol,
currencyNameCode);
return new ClientSavingsAccountSummaryData(id, accountNo, externalId, productId, productName, status, currency, accountBalance);
}
}
private static final class ClientLoanAccountSummaryDataMapper implements RowMapper<ClientAccountSummaryData> {
private static final class ClientLoanAccountSummaryDataMapper implements RowMapper<ClientLoanAccountSummaryData> {
public String loanAccountSummarySchema() {
StringBuilder accountsSummary = new StringBuilder("l.id as id, l.account_no as accountNo, l.external_id as externalId,");
accountsSummary.append("l.product_id as productId, lp.name as productName,")
.append("l.loan_status_id as statusId, l.loan_type_enum as loanType, ")
.append("l.loan_product_counter as loanCycle ").append(" from m_loan l ")
.append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id");
.append("l.loan_status_id as statusId, l.loan_type_enum as loanType, ").append("l.loan_product_counter as loanCycle ")
.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, @SuppressWarnings("unused") final int rowNum) throws SQLException {
public ClientLoanAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
final Long id = JdbcSupport.getLong(rs, "id");
final String accountNo = rs.getString("accountNo");
@@ -544,7 +508,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
final EnumOptionData loanType = LoanEnumerations.loanType(loanTypeId);
final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle");
return new ClientAccountSummaryData(id, accountNo, externalId, productId, loanProductName, loanStatus, loanType, loanCycle);
return new ClientLoanAccountSummaryData(id, accountNo, externalId, productId, loanProductName, loanStatus, loanType, loanCycle);
}
}
@@ -604,7 +568,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
}
@Override
public ClientData retrieveAllClosureReasons(String clientClosureReason) {
public ClientData retrieveAllClosureReasons(final String clientClosureReason) {
final List<CodeValueData> closureReasons = new ArrayList<CodeValueData>(
codeValueReadPlatformService.retrieveCodeValuesByCode(clientClosureReason));
return ClientData.template(null, null, null, null, closureReasons);
@@ -14,7 +14,7 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.RoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData;
import org.mifosplatform.portfolio.client.data.ClientLoanAccountSummaryData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
@@ -56,7 +56,7 @@ public class BulkLoansReadPlatformServiceImpl implements BulkLoansReadPlatformSe
for (StaffAccountSummaryCollectionData.ClientSummary clientSummary : clientSummaryList) {
final Collection<ClientAccountSummaryData> clientLoanAccounts = this.clientReadPlatformService
final Collection<ClientLoanAccountSummaryData> clientLoanAccounts = this.clientReadPlatformService
.retrieveClientLoanAccountsByLoanOfficerId(clientSummary.getId(), loanOfficerId);
clientSummary.setLoans(clientLoanAccounts);
@@ -1,19 +0,0 @@
package org.mifosplatform.portfolio.savings.service;
public class SavingStatusMapper {
private final Integer statusId;
public SavingStatusMapper(Integer statusId) {
this.statusId = statusId;
}
public boolean isPendingApproval() {
return Integer.valueOf(100).equals(statusId);
}
public boolean isOpen() {
return Integer.valueOf(300).equals(statusId);
}
}