From 26bed02096e81e0b1494917856c2f8a9d53d376c Mon Sep 17 00:00:00 2001 From: Keith Woodlock Date: Thu, 18 Jul 2013 19:49:47 +0100 Subject: [PATCH] refactor client accounts to be returned as list of accounts broken up into loans and savings rather than in collections by status. --- api-docs/apiLive.htm | 184 +++++++++--------- .../StaffAccountSummaryCollectionData.java | 8 +- .../client/api/ClientsApiResource.java | 14 +- .../ClientAccountSummaryCollectionData.java | 127 +----------- .../client/data/ClientAccountSummaryData.java | 87 --------- .../data/ClientLoanAccountSummaryData.java | 37 ++++ .../data/ClientSavingsAccountSummaryData.java | 40 ++++ .../service/ClientReadPlatformService.java | 4 +- .../ClientReadPlatformServiceImpl.java | 114 ++++------- .../BulkLoansReadPlatformServiceImpl.java | 4 +- .../savings/service/SavingStatusMapper.java | 19 -- 11 files changed, 226 insertions(+), 412 deletions(-) delete mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryData.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLoanAccountSummaryData.java create mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientSavingsAccountSummaryData.java delete mode 100644 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingStatusMapper.java diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 46bb779c5..3f66255d3 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -2329,19 +2329,16 @@ Request Body:  
-

Retrieve a Client's Loan Account Summary

+

Retrieve client accounts overview

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.
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.
It is quite reasonable to add resources like this to simplify User Interface development.

Example Requests:

-
clients/1/loans
+
clients/1/accounts


-
clients/1/loans?fields=openLoans,closedLoans,activeLoanCount
+
clients/1/accounts?fields=loanAccounts,savingsAccounts
@@ -2349,112 +2346,109 @@ GET https://DomainName/api/v1/clients/{clientId}/loans { - "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 ($)" } } ] diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffAccountSummaryCollectionData.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffAccountSummaryCollectionData.java index 3e3c6bc50..bb4fbb40d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffAccountSummaryCollectionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffAccountSummaryCollectionData.java @@ -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 loans; + private Collection loans; public ClientSummary(Long id, String displayName) { this.id = id; @@ -46,11 +46,11 @@ public class StaffAccountSummaryCollectionData { return displayName; } - public Collection getLoans() { + public Collection getLoans() { return loans; } - public void setLoans(Collection loans) { + public void setLoans(Collection loans) { this.loans = loans; } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java index 7c6d5b13e..9309e030d 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/api/ClientsApiResource.java @@ -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 CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet(Arrays.asList("pendingApprovalLoans", - "awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", - "awaitingDisbursalLoanCount", "activeLoanCount", "closedLoanCount", "pendingApprovalSavingAccountsCount", - "pendingApprovalSavingAccounts", "approvedSavingAccountsCount", "approvedSavingAccounts", - "withdrawnByClientSavingAccountsCount", "withdrawnByClientSavingAccounts", "rejectedSavingAccountsCount", - "rejectedSavingAccounts", "closedSavingAccountsCount", "closedSavingAccounts")); + final Set CLIENT_ACCOUNTS_DATA_PARAMETERS = new HashSet(Arrays.asList("loanAccounts", "savingsAccounts")); final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.clientAccountSummaryToApiJsonSerializer.serialize(settings, clientAccount, CLIENT_ACCOUNTS_DATA_PARAMETERS); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryCollectionData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryCollectionData.java index 424f3662c..239b96947 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryCollectionData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryCollectionData.java @@ -13,129 +13,18 @@ import java.util.Collection; public class ClientAccountSummaryCollectionData { @SuppressWarnings("unused") - private final Integer anyLoanCount; - private final Integer pendingApprovalLoanCount; - private final Collection pendingApprovalLoans; - private final Integer awaitingDisbursalLoanCount; - private final Collection awaitingDisbursalLoans; - private final Integer activeLoanCount; - private final Collection openLoans; - private final Integer closedLoanCount; - private final Collection closedLoans; + private final Collection loanAccounts; @SuppressWarnings("unused") - private final Integer pendingApprovalDepositAccountsCount; - private final Collection pendingApprovalDepositAccounts; - @SuppressWarnings("unused") - private final Integer approvedDepositAccountsCount; - private final Collection approvedDepositAccounts; - @SuppressWarnings("unused") - private final Integer withdrawnByClientDepositAccountsCount; - private final Collection withdrawnByClientDepositAccounts; - @SuppressWarnings("unused") - private final Integer closedDepositAccountsCount; - private final Collection closedDepositAccounts; - @SuppressWarnings("unused") - private final Integer rejectedDepositAccountsCount; - private final Collection rejectedDepositAccounts; - @SuppressWarnings("unused") - private final Integer preclosedDepositAccountsCount; - private final Collection preclosedDepositAccounts; - @SuppressWarnings("unused") - private final Integer maturedDepositAccountsCount; - private final Collection maturedDepositAccounts; - @SuppressWarnings("unused") - private final Integer pendingApprovalSavingAccountsCount; - private final Collection pendingApprovalSavingAccounts; - @SuppressWarnings("unused") - private final Integer approvedSavingAccountsCount; - private final Collection approvedSavingAccounts; - @SuppressWarnings("unused") - private final Integer withdrawnByClientSavingAccountsCount; - private final Collection withdrawnByClientSavingAccounts; - @SuppressWarnings("unused") - private final Integer rejectedSavingAccountsCount; - private final Collection rejectedSavingAccounts; - @SuppressWarnings("unused") - private final Integer closedSavingAccountsCount; - private final Collection closedSavingAccounts; + private final Collection savingsAccounts; - public ClientAccountSummaryCollectionData(final Collection pendingApprovalLoans, - final Collection awaitingDisbursalLoans, final Collection openLoans, - final Collection closedLoans, - final Collection pendingApprovalDepositAccounts, - final Collection approvedDepositAccounts, - final Collection withdrawnByClientDepositAccounts, - final Collection rejectedDepositAccounts, - final Collection closedDepositAccounts, - final Collection preclosedDepositAccounts, - final Collection maturedDepositAccounts, - final Collection pendingApprovalSavingAccounts, - final Collection approvedSavingAccounts, - final Collection withdrawnByClientSavingAccounts, - final Collection rejectedSavingAccounts, - final Collection 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 loanAccounts, + final Collection 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 collection) { - Integer count = null; - if (defaultIfEmpty(collection) != null) { - count = collection.size(); - } - return count; - } - - private Collection defaultIfEmpty(final Collection collection) { - Collection returnCollection = null; + private Collection defaultIfEmpty(final Collection collection) { + Collection returnCollection = null; if (collection != null && !collection.isEmpty()) { returnCollection = collection; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryData.java deleted file mode 100644 index 472c6a269..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientAccountSummaryData.java +++ /dev/null @@ -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; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLoanAccountSummaryData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLoanAccountSummaryData.java new file mode 100644 index 000000000..990de0c62 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLoanAccountSummaryData.java @@ -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; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientSavingsAccountSummaryData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientSavingsAccountSummaryData.java new file mode 100644 index 000000000..711969e04 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientSavingsAccountSummaryData.java @@ -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; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java index 01f243ebb..b6be73f29 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformService.java @@ -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 retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); + Collection retrieveClientLoanAccountsByLoanOfficerId(Long clientId, Long loanOfficerId); ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java index 4cef44bb0..4602271c4 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/service/ClientReadPlatformServiceImpl.java @@ -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 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) { + List 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 pendingApprovalDepositAccounts = new ArrayList(); - List approvedDepositAccounts = new ArrayList(); - List withdrawnByClientDespositAccounts = new ArrayList(); - List closedDepositAccounts = new ArrayList(); - List rejectedDepositAccounts = new ArrayList(); - List preclosedDepositAccounts = new ArrayList(); - List maturedDepositAccounts = new ArrayList(); - - List pendingApprovalSavingAccounts = new ArrayList(); - List approvedSavingAccounts = new ArrayList(); - List withdrawnByClientSavingAccounts = new ArrayList(); - List rejectedSavingAccounts = new ArrayList(); - List closedSavingAccounts = new ArrayList(); - - final ClientSavingsAccountSummaryDataMapper savingsAccountSummaryDataMapper = new ClientSavingsAccountSummaryDataMapper(); - final String savingsSql = "select " + savingsAccountSummaryDataMapper.schema() + " where sa.client_id = ?"; - final List 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 allSavingsAccounts = this.jdbcTemplate.query(savingsSql, + savingsAccountSummaryDataMapper, new Object[] { clientId }); + return new ClientAccountSummaryCollectionData(allLoanAccounts, allSavingsAccounts); } catch (EmptyResultDataAccessException e) { throw new ClientNotFoundException(clientId); } } @Override - public Collection retrieveClientLoanAccountsByLoanOfficerId(final Long clientId, final Long loanOfficerId) { + public Collection 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 loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { clientId, loanOfficerId }); + List loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { clientId, loanOfficerId }); return loanAccounts; } - private static final class ClientSavingsAccountSummaryDataMapper implements RowMapper { + private static final class ClientSavingsAccountSummaryDataMapper implements RowMapper { 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 { + private static final class ClientLoanAccountSummaryDataMapper implements RowMapper { 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 closureReasons = new ArrayList( codeValueReadPlatformService.retrieveCodeValuesByCode(clientClosureReason)); return ClientData.template(null, null, null, null, closureReasons); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformServiceImpl.java index ce9603d02..b0409c981 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformServiceImpl.java @@ -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 clientLoanAccounts = this.clientReadPlatformService + final Collection clientLoanAccounts = this.clientReadPlatformService .retrieveClientLoanAccountsByLoanOfficerId(clientSummary.getId(), loanOfficerId); clientSummary.setLoans(clientLoanAccounts); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingStatusMapper.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingStatusMapper.java deleted file mode 100644 index 507f48357..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingStatusMapper.java +++ /dev/null @@ -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); - } - -}