diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/MoneyData.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/MoneyData.java new file mode 100644 index 000000000..f1ad66b75 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/monetary/data/MoneyData.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.organisation.monetary.data; + +import java.math.BigDecimal; + +/** + * Immutable data object representing currency. + */ +public class MoneyData { + + private final String code; + private final BigDecimal amount; + private final int decimalPlaces; + + public MoneyData(final String code, final BigDecimal amount, final int decimalPlaces) { + this.code = code; + this.amount = amount; + this.decimalPlaces = decimalPlaces; + } + + public String getCode() { + return this.code; + } + + public BigDecimal getAmount() { + return this.amount; + } + + public int getDecimalPlaces() { + return this.decimalPlaces; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupData.java index 66fed724f..ae0610fe8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupData.java @@ -27,6 +27,8 @@ public class GroupData { private final Long parentId; private final String parentName; @SuppressWarnings("unused") + private final GroupSummaryData groupSummaryData; + @SuppressWarnings("unused") private final GroupLevelData groupLevelData; private final Collection clientMembers; @SuppressWarnings("unused") @@ -52,6 +54,7 @@ public class GroupData { this.parentName = parentName; this.staffId = staffId; this.staffName = staffName; + this.groupSummaryData = null; this.groupLevelData = null; this.clientMembers = null; this.allowedClients = null; @@ -63,7 +66,7 @@ public class GroupData { public GroupData(final GroupData group, final Collection clientMembers, final Collection allowedClients, final Collection allowedOffices, final Collection allowedParentGroups, - final GroupLevelData groupLevelData, final Collection allowedStaffs, final Collection childGroups) { + final GroupLevelData groupLevelData, final Collection allowedStaffs, final Collection childGroups , final GroupSummaryData groupSummaryData) { this.id = group.getId(); this.officeId = group.getOfficeId(); this.officeName = group.getOfficeName(); @@ -75,6 +78,7 @@ public class GroupData { this.staffId = group.getStaffId(); this.staffName = group.getStaffName(); + this.groupSummaryData = groupSummaryData; this.groupLevelData = groupLevelData; this.clientMembers = clientMembers; this.allowedClients = allowedClients; @@ -98,6 +102,7 @@ public class GroupData { this.parentName = null; this.staffId = null; this.staffName = null; + this.groupSummaryData = null; this.groupLevelData = groupLevelData; this.allowedClients = allowedClients; this.allowedOffices = allowedOffices; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLevelData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLevelData.java index a192ee971..d154823ff 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLevelData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLevelData.java @@ -10,23 +10,50 @@ package org.mifosplatform.portfolio.group.data; */ public class GroupLevelData { + private final Long levelId; - private final Long parentLevelId; private final String levelName; + private final Long parentLevelId; + private final String parentLevelName; + private final Long childLevelId; + private final String childLevelName; private final boolean superParent; private final boolean recursable; private final boolean canHaveClients; - public GroupLevelData(Long levelId, Long parentLevelId, String levelName, boolean superParent, boolean recursable, - boolean canHaveClients) { + public GroupLevelData(Long levelId, String levelName, Long parentLevelId, String parentLevelName, Long childLevelId, + String childLevelName, boolean superParent, boolean recursable, boolean canHaveClients) { + super(); this.levelId = levelId; - this.parentLevelId = parentLevelId; this.levelName = levelName; + this.parentLevelId = parentLevelId; + this.parentLevelName = parentLevelName; + this.childLevelId = childLevelId; + this.childLevelName = childLevelName; this.superParent = superParent; this.recursable = recursable; this.canHaveClients = canHaveClients; } + + + public String getParentLevelName() { + return this.parentLevelName; + } + + + + public Long getChildLevelId() { + return this.childLevelId; + } + + + + public String getChildLevelName() { + return this.childLevelName; + } + + public Long getLevelId() { return this.levelId; } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupSummaryData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupSummaryData.java new file mode 100644 index 000000000..4d700a9cc --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupSummaryData.java @@ -0,0 +1,43 @@ +/** + * 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.group.data; + +import java.util.Collection; + +import org.mifosplatform.organisation.monetary.data.MoneyData; + +public class GroupSummaryData { + + private final Long totalActiveClients; + private final Long totalChildGroups; + private final Collection totalLoanPortfolio; + private final Collection totalSavings; + + public GroupSummaryData(final Long totalActiveClients, final Long totalChildGroups, final Collection totalLoanPortfolio, + final Collection totalSavings) { + this.totalActiveClients = totalActiveClients; + this.totalChildGroups = totalChildGroups; + this.totalLoanPortfolio = totalLoanPortfolio; + this.totalSavings = totalSavings; + } + + public Long getTotalActiveClients() { + return this.totalActiveClients; + } + + public Long getTotalChildGroups() { + return this.totalChildGroups; + } + + public Collection getTotalLoanPortfolio() { + return this.totalLoanPortfolio; + } + + public Collection getTotalSavings() { + return this.totalSavings; + } + +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java index ec5487796..de81116e5 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/domain/Group.java @@ -177,7 +177,7 @@ public class Group extends AbstractPersistable { if (parent != null) { this.hierarchy = this.parent.hierarchyOf(this.getId()); } else { - this.hierarchy = "."; + this.hierarchy = "." + this.getId() + "."; } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformService.java index 89f5146bc..e893dbdf9 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformService.java @@ -7,6 +7,7 @@ package org.mifosplatform.portfolio.group.service; import java.util.Collection; +import org.mifosplatform.organisation.monetary.data.MoneyData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.client.data.ClientLookup; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; @@ -38,4 +39,10 @@ public interface GroupReadPlatformService { GroupData retrieveGroupDetails(Long groupId, boolean template); Collection retrieveChildGroupsbyGroupId(Long groupId); + + Long retrieveTotalClients(Long groupId); + + Long retrieveTotalNoOfChildGroups(Long groupId); + + Collection retrieveGroupLoanPortfolio(Long groupId); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformServiceImpl.java index f09c7f88d..f1c1b9a61 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupReadPlatformServiceImpl.java @@ -5,6 +5,7 @@ */ package org.mifosplatform.portfolio.group.service; +import java.math.BigDecimal; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; @@ -15,6 +16,7 @@ import org.apache.commons.lang.StringUtils; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.organisation.monetary.data.MoneyData; import org.mifosplatform.organisation.office.data.OfficeLookup; import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.organisation.staff.data.StaffData; @@ -27,6 +29,7 @@ import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData; import org.mifosplatform.portfolio.group.data.GroupData; import org.mifosplatform.portfolio.group.data.GroupLevelData; import org.mifosplatform.portfolio.group.data.GroupLookupData; +import org.mifosplatform.portfolio.group.data.GroupSummaryData; import org.mifosplatform.portfolio.group.exception.GroupLevelNotFoundException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.springframework.beans.factory.annotation.Autowired; @@ -111,7 +114,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { GroupLookupMapper rm = new GroupLookupMapper(); - String sql = "select " + rm.groupLookupSchema() + " from m_group pg join m_group g where pg.id = g.parent_id and pg.id = ? and g.is_deleted=0"; + String sql = "select " + rm.groupLookupSchema() + + " from m_group pg join m_group g where pg.id = g.parent_id and pg.id = ? and g.is_deleted=0"; return this.jdbcTemplate.query(sql, rm, new Object[] { groupId }); @@ -173,11 +177,19 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { Collection availableClients = null; Collection allowedOffices = null; Collection allowedParentGroups = null; - GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(group.getGroupLevel());; + GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(group.getGroupLevel()); + ; Collection allowedStaffs = null; Collection childGroups = this.retrieveChildGroupsbyGroupId(groupId); - - group = new GroupData(group, clientMembers, availableClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs , childGroups); + + final Long totalActiveClients = this.retrieveTotalClients(groupId); + final Long totalChildGroups = this.retrieveTotalNoOfChildGroups(groupId); + Collection totalLoanPortfolio = this.retrieveGroupLoanPortfolio(groupId); + + GroupSummaryData groupSummaryData = new GroupSummaryData(totalActiveClients, totalChildGroups, totalLoanPortfolio, null); + + group = new GroupData(group, clientMembers, availableClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs, + childGroups, groupSummaryData); if (template) { @@ -187,16 +199,15 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { } allowedOffices = officeReadPlatformService.retrieveAllOfficesForLookup(); if (groupLevelData.getParentLevelId() != null) { - allowedParentGroups = this.retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), - groupLevelData.getParentLevelId()); + allowedParentGroups = this.retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), groupLevelData.getParentLevelId()); } allowedStaffs = this.retrieveStaffsbyOfficeId(group.getOfficeId()); group = new GroupData(group, group.clientMembers(), availableClients, allowedOffices, allowedParentGroups, groupLevelData, - allowedStaffs , childGroups); + allowedStaffs, childGroups, groupSummaryData); } - + return group; } @@ -218,6 +229,61 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { } } + @Override + public Long retrieveTotalClients(final Long groupId) { + + this.context.authenticatedUser(); + + String groupHierarchy = "." + groupId + "%"; + String sqlTotalClients = "SELECT count(gc.client_id) FROM m_group_client gc JOIN m_group g " + + "ON gc.group_id = g.id WHERE g.hierarchy LIKE ? "; + return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupHierarchy }); + + } + + @Override + public Long retrieveTotalNoOfChildGroups(final Long groupId) { + + this.context.authenticatedUser(); + String sqlTotalClients = "SELECT count(gc.id) FROM m_group g JOIN m_group gc WHERE g.id = gc.parent_id and g.id = ?"; + return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupId }); + + } + + @Override + public Collection retrieveGroupLoanPortfolio(final Long groupId) { + + this.context.authenticatedUser(); + + MoneyDataMapper rm = new MoneyDataMapper(); + + String groupHierarchy = "." + groupId + "%"; + String sql = "select " + rm.moneyDataSchema() + " FROM m_group_client gc JOIN m_group g ON gc.group_id = g.id " + + "JOIN m_loan l ON l.client_id = gc.client_id LEFT JOIN m_organisation_currency oc ON oc.code = l.currency_code " + + " WHERE g.hierarchy LIKE ? GROUP BY l.currency_code "; + + return this.jdbcTemplate.query(sql, rm, new Object[] { groupHierarchy }); + + } + + private static final class MoneyDataMapper implements RowMapper { + + public String moneyDataSchema() { + return "l.currency_code as currencyCode, oc.decimal_places as decimalPlaces, sum(l.principal_amount) as amount"; + } + + @Override + public MoneyData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { + + String currencyCode = rs.getString("currencyCode"); + Integer decimalPlaces = rs.getInt("decimalPlaces"); + BigDecimal amount = rs.getBigDecimal("amount"); + + return new MoneyData(currencyCode, amount, decimalPlaces); + } + + } + private static final class GroupDataMapper implements RowMapper { public String groupSchema() { @@ -240,7 +306,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { String parentName = rs.getString("parentName"); Long staffId = rs.getLong("staffId"); String staffName = rs.getString("staffName"); - + return new GroupData(id, officeId, officeName, name, externalId, groupLevel, parentId, parentName, staffId, staffName); } @@ -266,21 +332,27 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { private static final class GroupLevelDataMapper implements RowMapper { public String groupLevelSchema() { - return "gl.id as id, gl.parent_id as parentLevelId , gl.level_name as levelName , gl.super_parent as superParent ," - + " gl.recursable as recursable , gl.can_have_clients as canHaveClients from m_group_level gl"; + return "gl.id as id, gl.level_name as levelName , gl.parent_id as parentLevelId , pgl.level_name as parentName , " + + "cgl.id as childLevelId,cgl.level_name as childLevelName,gl.super_parent as superParent ," + + " gl.recursable as recursable , gl.can_have_clients as canHaveClients from m_group_level gl " + + " left join m_group_level pgl on pgl.id = gl.parent_id left join m_group_level cgl on gl.id = cgl.parent_id"; } @Override public GroupLevelData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException { Long levelId = rs.getLong("id"); - Long parentLevelId = rs.getLong("parentLevelId"); String levelName = rs.getString("levelName"); + Long parentLevelId = rs.getLong("parentLevelId"); + String parentLevelName = rs.getString("parentName"); + Long childLevelId = rs.getLong("childLevelId"); + String childLevelName = rs.getString("childLevelName"); boolean superParent = rs.getBoolean("superParent"); boolean recursable = rs.getBoolean("recursable"); boolean canHaveClients = rs.getBoolean("canHaveClients"); - return new GroupLevelData(levelId, parentLevelId, levelName, superParent, recursable, canHaveClients); + return new GroupLevelData(levelId, levelName, parentLevelId, parentLevelName, childLevelId, childLevelName, superParent, + recursable, canHaveClients); } }