Repository: fineract Updated Branches: refs/heads/develop e29e37ebb -> 9398afda4
FINERACT-642 Include Guarantor Accounts in Client Accounts Overview Project: http://git-wip-us.apache.org/repos/asf/fineract/repo Commit: http://git-wip-us.apache.org/repos/asf/fineract/commit/fbf9d1e7 Tree: http://git-wip-us.apache.org/repos/asf/fineract/tree/fbf9d1e7 Diff: http://git-wip-us.apache.org/repos/asf/fineract/diff/fbf9d1e7 Branch: refs/heads/develop Commit: fbf9d1e7d0fe2d3b9519f2e9ffe1785c04009473 Parents: d2b3411 Author: tonic889 <tonic...@github.com> Authored: Sat Apr 28 20:26:56 2018 -0400 Committer: tonic889 <tonic...@github.com> Committed: Mon Aug 6 22:54:31 2018 -0400 ---------------------------------------------------------------------- .../data/AccountSummaryCollectionData.java | 22 +++- .../data/GuarantorAccountSummaryData.java | 70 +++++++++++ ...ilsReadPlatformServiceJpaRepositoryImpl.java | 117 ++++++++++++++++++- 3 files changed, 202 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/fineract/blob/fbf9d1e7/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java index f4faaca..80de9a5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/AccountSummaryCollectionData.java @@ -29,27 +29,34 @@ public class AccountSummaryCollectionData { private final Collection<LoanAccountSummaryData> loanAccounts; private final Collection<SavingsAccountSummaryData> savingsAccounts; private final Collection<ShareAccountSummaryData> shareAccounts ; + private final Collection<GuarantorAccountSummaryData> guarantorAccounts; private final Collection<LoanAccountSummaryData> memberLoanAccounts; private final Collection<SavingsAccountSummaryData> memberSavingsAccounts; - + private final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts; + public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts, - final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<ShareAccountSummaryData> shareAccounts) { + final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<ShareAccountSummaryData> shareAccounts, + final Collection<GuarantorAccountSummaryData> guarantorAccounts) { this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); this.shareAccounts = defaultShareAccountsIfEmpty(shareAccounts) ; + this.guarantorAccounts = guarantorAccounts; this.memberLoanAccounts = null; this.memberSavingsAccounts = null; + this.memberGuarantorAccounts = null; } public AccountSummaryCollectionData(final Collection<LoanAccountSummaryData> loanAccounts, - final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<LoanAccountSummaryData> memberLoanAccounts, - final Collection<SavingsAccountSummaryData> memberSavingsAccounts) { + final Collection<SavingsAccountSummaryData> savingsAccounts, final Collection<GuarantorAccountSummaryData> guarantorAccounts, final Collection<LoanAccountSummaryData> memberLoanAccounts, + final Collection<SavingsAccountSummaryData> memberSavingsAccounts, final Collection<GuarantorAccountSummaryData> memberGuarantorAccounts) { this.loanAccounts = defaultLoanAccountsIfEmpty(loanAccounts); this.savingsAccounts = defaultSavingsAccountsIfEmpty(savingsAccounts); + this.guarantorAccounts = guarantorAccounts; this.shareAccounts = null ; this.memberLoanAccounts = defaultLoanAccountsIfEmpty(memberLoanAccounts); this.memberSavingsAccounts = defaultSavingsAccountsIfEmpty(memberSavingsAccounts); + this.memberGuarantorAccounts = defaultGuarantorAccountsIfEmpty(memberGuarantorAccounts); } private Collection<LoanAccountSummaryData> defaultLoanAccountsIfEmpty(final Collection<LoanAccountSummaryData> collection) { @@ -76,4 +83,11 @@ public class AccountSummaryCollectionData { return returnCollection; } + private Collection<GuarantorAccountSummaryData> defaultGuarantorAccountsIfEmpty(final Collection<GuarantorAccountSummaryData> collection) { + Collection<GuarantorAccountSummaryData> returnCollection = null; + if (collection != null && !collection.isEmpty()) { + returnCollection = collection; + } + return returnCollection; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/fbf9d1e7/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/GuarantorAccountSummaryData.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/GuarantorAccountSummaryData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/GuarantorAccountSummaryData.java new file mode 100644 index 0000000..64f444e --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/data/GuarantorAccountSummaryData.java @@ -0,0 +1,70 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.portfolio.accountdetails.data; + +import java.math.BigDecimal; + +import org.apache.fineract.infrastructure.core.data.EnumOptionData; +import org.apache.fineract.portfolio.loanaccount.data.LoanApplicationTimelineData; +import org.apache.fineract.portfolio.loanaccount.data.LoanStatusEnumData; + +/** + * Immutable data object for loan accounts. + */ +@SuppressWarnings("unused") +public class GuarantorAccountSummaryData { + + private final Long id; + private final String accountNo; + private final String externalId; + private final Long productId; + private final String productName; + private final String shortProductName; + private final LoanStatusEnumData status; + private final EnumOptionData loanType; + private final Integer loanCycle; + private final Boolean inArrears; + private final BigDecimal originalLoan; + private final BigDecimal loanBalance; + private final BigDecimal amountPaid; + private final Boolean isActive; + private final String relationship; + private final BigDecimal onHoldAmount; + public GuarantorAccountSummaryData(final Long id, final String accountNo, final String externalId, final Long productId, + final String loanProductName, final String shortLoanProductName, final LoanStatusEnumData loanStatus, final EnumOptionData loanType, final Integer loanCycle, + final Boolean inArrears,final BigDecimal originalLoan,final BigDecimal loanBalance,final BigDecimal amountPaid, + final Boolean isActive, final String relationship, final BigDecimal onHoldAmount) { + this.id = id; + this.accountNo = accountNo; + this.externalId = externalId; + this.productId = productId; + this.productName = loanProductName; + this.shortProductName = shortLoanProductName; + this.status = loanStatus; + this.loanType = loanType; + this.loanCycle = loanCycle; + this.inArrears = inArrears; + this.loanBalance = loanBalance; + this.originalLoan = originalLoan; + this.amountPaid = amountPaid; + this.isActive = isActive; + this.relationship = relationship; + this.onHoldAmount = onHoldAmount; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/fineract/blob/fbf9d1e7/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java index 0fc9103..b4b1bb7 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/accountdetails/service/AccountDetailsReadPlatformServiceJpaRepositoryImpl.java @@ -30,6 +30,7 @@ import org.apache.fineract.infrastructure.core.service.RoutingDataSource; import org.apache.fineract.infrastructure.security.utils.ColumnValidator; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.portfolio.accountdetails.data.AccountSummaryCollectionData; +import org.apache.fineract.portfolio.accountdetails.data.GuarantorAccountSummaryData; import org.apache.fineract.portfolio.accountdetails.data.LoanAccountSummaryData; import org.apache.fineract.portfolio.accountdetails.data.SavingsAccountSummaryData; import org.apache.fineract.portfolio.accountdetails.data.ShareAccountSummaryData; @@ -75,10 +76,14 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou this.clientReadPlatformService.retrieveOne(clientId); final String loanwhereClause = " where l.client_id = ?"; final String savingswhereClause = " where sa.client_id = ? order by sa.status_enum ASC, sa.account_no ASC"; + final String guarantorWhereClause = " where g.entity_id = ? and g.is_active = 1 order by l.account_no ASC"; + final List<LoanAccountSummaryData> loanAccounts = retrieveLoanAccountDetails(loanwhereClause, new Object[] { clientId }); final List<SavingsAccountSummaryData> savingsAccounts = retrieveAccountDetails(savingswhereClause, new Object[] { clientId }); final List<ShareAccountSummaryData> shareAccounts = retrieveShareAccountDetails(clientId) ; - return new AccountSummaryCollectionData(loanAccounts, savingsAccounts, shareAccounts); + final List<GuarantorAccountSummaryData> guarantorloanAccounts = retrieveGuarantorLoanAccountDetails( + guarantorWhereClause, new Object[] { clientId }); + return new AccountSummaryCollectionData(loanAccounts, savingsAccounts, shareAccounts, guarantorloanAccounts); } @Override @@ -89,14 +94,21 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou final String loanWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null"; final String savingswhereClauseForGroup = " where sa.group_id = ? and sa.client_id is null order by sa.status_enum ASC, sa.account_no ASC"; final String savingswhereClauseForMembers = " where sa.group_id = ? and sa.client_id is not null order by sa.status_enum ASC, sa.account_no ASC"; + final String guarantorWhereClauseForGroup = " where l.group_id = ? and l.client_id is null and g.is_active = 1 order by l.account_no ASC"; + final String guarantorWhereClauseForMembers = " where l.group_id = ? and l.client_id is not null and g.is_active = 1 order by l.account_no ASC"; + final List<LoanAccountSummaryData> groupLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForGroup, new Object[] { groupId }); final List<SavingsAccountSummaryData> groupSavingsAccounts = retrieveAccountDetails(savingswhereClauseForGroup, new Object[] { groupId }); + final List<GuarantorAccountSummaryData> groupGuarantorloanAccounts = retrieveGuarantorLoanAccountDetails( + guarantorWhereClauseForGroup, new Object[] { groupId }); final List<LoanAccountSummaryData> memberLoanAccounts = retrieveLoanAccountDetails(loanWhereClauseForMembers, new Object[] { groupId }); final List<SavingsAccountSummaryData> memberSavingsAccounts = retrieveAccountDetails(savingswhereClauseForMembers, new Object[] { groupId }); - return new AccountSummaryCollectionData(groupLoanAccounts, groupSavingsAccounts, memberLoanAccounts, memberSavingsAccounts); + final List<GuarantorAccountSummaryData> memberGuarantorloanAccounts = retrieveGuarantorLoanAccountDetails( + guarantorWhereClauseForMembers, new Object[] { groupId }); + return new AccountSummaryCollectionData(groupLoanAccounts, groupSavingsAccounts, groupGuarantorloanAccounts, memberLoanAccounts, memberSavingsAccounts, memberGuarantorloanAccounts); } @Override @@ -144,6 +156,14 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou return this.jdbcTemplate.query(query, mapper, new Object [] {clientId}); } + private List<GuarantorAccountSummaryData> retrieveGuarantorLoanAccountDetails( + final String loanwhereClause, final Object[] inputs) { + final GuarantorLoanAccountSummaryDataMapper rm = new GuarantorLoanAccountSummaryDataMapper(); + final String sql = "select " + rm.guarantorLoanAccountSummarySchema() + + loanwhereClause; + return this.jdbcTemplate.query(sql, rm, inputs); + } + private final static class ShareAccountSummaryDataMapper implements RowMapper<ShareAccountSummaryData> { private final String schema ; @@ -493,6 +513,97 @@ public class AccountDetailsReadPlatformServiceJpaRepositoryImpl implements Accou return new LoanAccountSummaryData(id, accountNo, externalId, productId, loanProductName, shortLoanProductName, loanStatus, loanType, loanCycle, timeline, inArrears,originalLoan,loanBalance,amountPaid); } + + } + private static final class GuarantorLoanAccountSummaryDataMapper implements + RowMapper<GuarantorAccountSummaryData> { + + public String guarantorLoanAccountSummarySchema() { + + final 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, lp.short_name as shortProductName,") + .append(" l.loan_status_id as statusId, l.loan_type_enum as loanType,") + + .append("l.principal_disbursed_derived as originalLoan,") + .append("l.total_outstanding_derived as loanBalance,") + .append("l.total_repayment_derived as amountPaid,") + + .append(" l.loan_product_counter as loanCycle,") + + .append(" l.submittedon_date as submittedOnDate,") + + .append(" l.rejectedon_date as rejectedOnDate,") + .append(" l.withdrawnon_date as withdrawnOnDate,") + .append(" l.approvedon_date as approvedOnDate,") + .append(" l.expected_disbursedon_date as expectedDisbursementDate, l.disbursedon_date as actualDisbursementDate,") + .append(" l.closedon_date as closedOnDate,") + .append(" la.overdue_since_date_derived as overdueSinceDate,") + .append(" l.writtenoffon_date as writtenOffOnDate, l.expected_maturedon_date as expectedMaturityDate,") + .append(" g.is_active as isActive,") + .append(" cv.code_value as relationship,") + .append(" sa.on_hold_funds_derived") + .append(" from m_loan l ") + .append(" join m_guarantor as g on g.loan_id = l.id ") + .append(" join m_client as c on c.id = g.entity_id ") + .append(" LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id") + .append(" left join m_loan_arrears_aging la on la.loan_id = l.id") + .append(" left join m_code_value cv ON cv.id = g.client_reln_cv_id") + .append(" left join m_savings_account sa on sa.client_id = c.id") + + ; + + return accountsSummary.toString(); + } + + @Override + public GuarantorAccountSummaryData 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 loanProductName = rs.getString("productName"); + final String shortLoanProductName = rs + .getString("shortProductName"); + final Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId"); + final LoanStatusEnumData loanStatus = LoanEnumerations + .status(loanStatusId); + final Integer loanTypeId = JdbcSupport.getInteger(rs, "loanType"); + final EnumOptionData loanType = AccountEnumerations + .loanType(loanTypeId); + final Integer loanCycle = JdbcSupport.getInteger(rs, "loanCycle"); + + final BigDecimal originalLoan = JdbcSupport + .getBigDecimalDefaultToNullIfZero(rs, "originalLoan"); + final BigDecimal loanBalance = JdbcSupport + .getBigDecimalDefaultToNullIfZero(rs, "loanBalance"); + final BigDecimal amountPaid = JdbcSupport + .getBigDecimalDefaultToNullIfZero(rs, "amountPaid"); + final BigDecimal onHoldAmount = JdbcSupport + .getBigDecimalDefaultToNullIfZero(rs, + "on_hold_funds_derived"); + + final LocalDate overdueSinceDate = JdbcSupport.getLocalDate(rs, + "overdueSinceDate"); + Boolean inArrears = true; + if (overdueSinceDate == null) { + inArrears = false; + } + + final Boolean isActive = rs.getBoolean("isActive"); + + final String relationship = rs.getString("relationship"); + return new GuarantorAccountSummaryData(id, accountNo, externalId, + productId, loanProductName, shortLoanProductName, + loanStatus, loanType, loanCycle, inArrears, originalLoan, + loanBalance, amountPaid, isActive, relationship, + onHoldAmount); + } + } -} +} \ No newline at end of file