diff --git a/api-docs/apiLive.htm b/api-docs/apiLive.htm index 3da9f7d10..635ce2321 100644 --- a/api-docs/apiLive.htm +++ b/api-docs/apiLive.htm @@ -228,7 +228,7 @@
-

Group

+

Groupings

@@ -274,6 +274,22 @@
+ + Center + centers + Create a Center + List Centers + + Delete a Center + + + + centers/{centerId} + + Retrieve a Center + Update a Center + + Group groups @@ -290,35 +306,12 @@ Update a Group - - - groups/{group}/loans - - Retrieve a Group's - Loan Account Summary - - - - - - groups/{group}/command/assign_loanofficer - Assign a Loan Officer - - - - - - - groups/{group}/command/unassign_loanofficer - Unassign a Loan Officer - - - -
+ +

Loan

@@ -1317,6 +1310,14 @@ + + centers/template + Retrieve Center Template + + + groups/template + Retrieve Group Template + clients/template Retrieve Client Template @@ -2579,54 +2580,460 @@ No Request Body:
+ +   +
+
+

Centers

+

Centers along with Groups are used to provided a distinctive banking distribution channel used in microfinance. Its common in areas such as India to use Centers and Group administrative units in grameen style lending. Typically groups will contain one to five people and centers themselves will be made of anywhere between 2-7 groups. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field Descriptions
name
Name given to the Center.
officeId
The officeId of the office/branch this center is administrated through.
staffId
The staffId of the staff member dealing with this center. The staff member is not specifically the loan officer.
externalId
A place to put an external reference for this center e.g. The ID another system uses. If provided, it must be unique. +
+
+
+ +   +
+
+

Retrieve a Center Template

+

Example Requests:

+
centers/template
+
+
centers/template?officeId=2
+
+
+ +GET https://DomainName/mifosng-provider/api/v1/centers/template + + +{ + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Suboffice", + "nameDecorated": "....Suboffice" + } + ], + "staffOptions": [ + { + "id": 1, + "displayName": "LoanOfficer, HeadOffice" + }, + { + "id": 2, + "displayName": "NonLoanOfficer, HeadOffice" + } + ] +} + +
+
+ +GET https://DomainName/mifosng-provider/api/v1/centers/template?officeId=2 + + +{ + "officeId": 2, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Suboffice", + "nameDecorated": "....Suboffice" + } + ], + "staffOptions": [ + { + "id": 3, + "displayName": "LoanOfficer, Suboffice" + }, + { + "id": 4, + "displayName": "NonLoanOfficer, Suboffice" + } + ] +} + +
+
+ +   +
+
+

Create a Center

+ + + + + + + +
Mandatory Fields
name, officeId
+
+ + + + + + + +
Optional Fields
externalId, staffId
+
+
+ +POST https://DomainName/mifosng-provider/api/v1/centers + + +POST centers +Content-Type: application/json Request Body: +{ + "name": "apicenter", + "officeId": 2 +} + + +{ + "officeId": 2, + "groupId": 4, + "resourceId": 4 +} + +
+
+ +   +
+
+

Update a Center

+
+
+ +PUT https://DomainName/mifosng-provider/api/v1/centers/{centerId} + + +PUT centers/4 +Content-Type: application/json +Request Body: +{ + "name": "apicenter(updated)" +} + + +{ + "officeId": 4, + "groupId": 2, + "resourceId": 4, + "changes": { + "name": "apicenter(updated)" + } +} + +
+
+ +   +
+
+

Delete a Center

+
+
+ +POST https://DomainName/mifosng-provider/api/v1/centers/{centerId} + + +DELETE centers/1 + + +{ + "resourceId":1, + "changes":{} +} + +
+
+ +   +
+
+

List Centers

+

Example Requests:

+
centers
+
+
+ +GET https://DomainName/mifosng-provider/api/v1/centers + + +[ + { + "id": 1, + "name": "Center 001", + "externalId": "001", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1." + }, + { + "id": 3, + "name": "Suboffice Center", + "externalId": "002", + "officeId": 2, + "officeName": "Suboffice", + "hierarchy": ".3." + } +] + +
+
+ +   +
+
+

Retrieve a Center

+

Example Requests:

+
centers/1
+
+
+ +GET https://DomainName/mifosng-provider/api/v1/centers/1 + + +{ + "id": 1, + "name": "Center 001", + "externalId": "001", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1." +} + +
+
+  

Groups

-

Groups are collection of clients for specific purpose (JLG,SHG, Program etc)

+

Groups are used to provide a distinctive banking distribution channel used in microfinance throughout the world. The Group is an administrative unit. It can contain as few as 5 people or as many as 40 depending on how its used.

+ +

Different styles of group lending - Joint-Liability Group, Grameen Model (Center-Group), Self-Help Groups, Village/Communal Banks)

- - - - - - - - - - - - - + + + + + + + + + + + + + - - - + + - +
Field Descriptions
office_id
It stores the officeid of office, to this officer Group belongs.
loan_officer_id
Id of the officer who manages this group.
name
Human friendly identity of the Group (Name given to the group).Name given to the Group.
officeId
The officeId of the office/branch this group is administrated through.
staffId
The staffId of the staff member dealing with this group. The staff member is not specifically the loan officer.
externalId
A place to put an external reference for - this group e.g. The ID another system uses.
If - provided, it must be unique. +
A place to put an external reference for this group e.g. The ID another system uses. If provided, it must be unique.
is_deleted
clientMembers
Indicator for active or archived groups. - The individual client members that make up the group.
+ +   +
+
+

Retrieve Group Template

+

Example Requests:

+
groups/template?centerId=1
+
+
groups/template?officeId=2
+
+
groups/template
+
+
+ +GET https://DomainName/mifosng-provider/api/v1/groups/template + + +{ + "officeId": 1, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Suboffice", + "nameDecorated": "....Suboffice" + } + ], + "staffOptions": [ + { + "id": 1, + "displayName": "LoanOfficer, HeadOffice" + }, + { + "id": 2, + "displayName": "NonLoanOfficer, HeadOffice" + } + ], + "clientOptions": [ + { + "id": 1, + "displayName": "Test one", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+ +GET https://DomainName/mifosng-provider/api/v1/groups/template?officeId=2 + + +{ + "officeId": 2, + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office" + }, + { + "id": 2, + "name": "Suboffice", + "nameDecorated": "....Suboffice" + } + ], + "staffOptions": [ + { + "id": 3, + "displayName": "LoanOfficer, Suboffice" + }, + { + "id": 4, + "displayName": "NonLoanOfficer, Suboffice" + } + ] +} + +
+
+ +GET https://DomainName/mifosng-provider/api/v1/groups/template?centerId=1 + + +{ + "officeId": 1, + "centerId": 1, + "centerName": "Center 001", + "centerOptions": [ + { + "id": 1, + "name": "Center 001", + "externalId": "001", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".1." + } + ], + "officeOptions": [ + { + "id": 1, + "name": "Head Office", + "nameDecorated": "Head Office", + "externalId": "1", + "openingDate": [ + 2009, + 1, + 1 + ], + "hierarchy": "." + } + ], + "staffOptions": [ + { + "id": 1, + "displayName": "LoanOfficer, HeadOffice" + }, + { + "id": 2, + "displayName": "NonLoanOfficer, HeadOffice" + } + ], + "clientOptions": [ + { + "id": 1, + "displayName": "Test one", + "officeId": 1, + "officeName": "Head Office" + } + ] +} + +
+
+  
@@ -2636,32 +3043,51 @@ No Request Body:
Mandatory Fields
- name
- officeId
- clients - + name,officeId + + +
+ + + + + +
Optional Fields
externalId,staffId,clientMembers
- POST https://DomainName/mifosng-provider/api/v1/groups +POST https://DomainName/mifosng-provider/api/v1/groups - POST groups - Content-Type: application/json Request Body: - { - "officeId":"1", - "name":"TA Group", - "externalId":"", - "clientMembers":["82","83","84"] - } +POST groups +Content-Type: application/json Request Body: +{ +"officeId":"1", +"name":"TA Group" +} + + +POST groups +Content-Type: application/json Request Body: +{ +"officeId":"1", +"name":"TA Group" +"externalId": "000-1A", +"clientMembers": ["1"] +} - {"resourceId":24,"changes":{}} +{ + "officeId": 2, + "groupId": 5, + "resourceId": 5 +}
+  
@@ -2674,114 +3100,115 @@ No Request Body: GET https://DomainName/mifosng-provider/api/v1/groups -[{ - "id": 1, - "name": "GWT_2", - "externalId": "GWT_EX_ID_2", - "officeId": 7, - "officeName": "Z2" -}, { - "id": 2, - "name": "group22", - "externalId": "11234", +[ + { + "id": 10, + "name": "GroupU(Suboffice)", + "officeId": 2, + "officeName": "Suboffice", + "centerId": 4, + "centerName": "apicenter(updated)", + "hierarchy": "" + }, + { + "id": 8, + "name": "AnothergroupUI", "officeId": 1, - "officeName": "Head Office" -}, { - "id": 3, - "name": "PlusOne", - "officeId": 22, - "officeName": "North Point Office" -}] + "officeName": "Head Office", + "centerId": 1, + "centerName": "Center 001", + "hierarchy": "" + }, + { + "id": 7, + "name": "NewGroupUI", + "externalId": "0011", + "officeId": 1, + "officeName": "Head Office", + "centerId": 1, + "centerName": "Center 001", + "staffId": 1, + "staffName": "LoanOfficer, HeadOffice", + "hierarchy": "" + }, + { + "id": 9, + "name": "GroupUCenter", + "officeId": 1, + "officeName": "Head Office", + "centerId": 1, + "centerName": "Center 001", + "staffId": 1, + "staffName": "LoanOfficer, HeadOffice", + "hierarchy": "" + }, + { + "id": 2, + "name": "Group 001-A", + "officeId": 1, + "officeName": "Head Office", + "centerId": 1, + "centerName": "Center 001", + "hierarchy": "" + }, + { + "id": 11, + "name": "Test(no parents)", + "officeId": 1, + "officeName": "Head Office", + "hierarchy": ".11." + }, + { + "id": 12, + "name": "SubofficeGroup(no parents)", + "officeId": 2, + "officeName": "Suboffice", + "hierarchy": ".12." + } +]
-   + +  

Retrieve a Group

Example Requests:

-
groups/10
+
groups/12
-GET https://DomainName/mifosng-provider/api/v1/groups/10 +GET https://DomainName/mifosng-provider/api/v1/groups/12 { - "id": 10, - "name": "test123", - "externalId": "tejjjst", - "officeId": 1, - "officeName": "Head Office", - "clientMembers": [{ - "id": 1, - "displayName": "Willie O\u0027Meara" - }] -} - -
-
-   -
-
-

Retrieve a Groups's Loan Account Summary

-

- An example of how a loan portfolio summary can be provided. This - one contains quite a bit of redundant data (like the counts) -

-

Example Requests:

-
groups/7/loans
-
-
- -GET https://DomainName/mifosng-provider/api/v1/groups/7/loans - - -{ - "anyLoanCount": 1, - "pendingApprovalLoanCount": 0, - "pendingApprovalLoans": [], - "awaitingDisbursalLoanCount": 0, - "awaitingDisbursalLoans": [], - "activeLoanCount": 1, - "openLoans": [{ - "id": 79, - "productId": 1, - "productName": "1-PORetailLoan", - "accountStatusId": 300 - }], - "closedLoanCount": 0, - "closedLoans": [], - "anyIndividualLoanCount": 3, - "pendingApprovalIndividualLoanCount": 0, - "pendingApprovalIndividualLoans": [], - "awaitingDisbursalIndividualLoanCount": 0, - "awaitingDisbursalIndividualLoans": [], - "activeIndividualLoanCount": 3, - "openIndividualLoans": [{ - "id": 80, - "productId": 17, - "productName": "17-Intrasoft Business Loan", - "accountStatusId": 300 - }, { - "id": 81, - "productId": 1, - "productName": "1-PORetailLoan", - "accountStatusId": 300 - }, { - "id": 82, - "productId": 13, - "productName": "13-A Flat Loan", - "accountStatusId": 300 - }], - "closedIndividualLoanCount": 0, - "closedIndividualLoans": [] + "id": 12, + "name": "SubofficeGroup(no parents)", + "officeId": 2, + "officeName": "Suboffice", + "hierarchy": ".12.", + "clientMembers": [ + { + "id": 2, + "accountNo": "000000002", + "firstname": "Another", + "lastname": "client", + "displayName": "Another client", + "officeId": 2, + "officeName": "Suboffice", + "joinedDate": [ + 2012, + 4, + 14 + ] + } + ] }
+  
@@ -2792,75 +3219,27 @@ GET https://DomainName/mifosng-provider/api/v1/groups/7/loans PUT https://DomainName/mifosng-provider/api/v1/groups/{groupid} -PUT groups/7 +PUT groups/5 Content-Type: application/json Request Body: { - "officeId": "26", - "name": "Laxmi SSG U", - "externalId": "Unq 2--124", - "clientMembers": ["91", "93", "94"] + "name": "apigroup(changed)" } { - "resourceId":7, - "changes":{} + "officeId": 5, + "groupId": 2, + "resourceId": 5, + "changes": { + "name": "apigroup(changed)" + } }
-   -
-
-

Assign a Loan Officer to Group

-
-
- -POST https://DomainName/mifosng-provider/api/v1/groups/{groupid}/command/assign_loanofficer - - -POST groups/20/command/assign_loanofficer -Content-Type: application/json -Request Body: -{ -{"loanOfficerId":"1"} -} - - -{ - "resourceId":20, - "changes":{} -} - -
-
-   -
-
-

Unassign a loan officer to a Group

-
-
- -POST https://DomainName/mifosng-provider/api/v1/groups/{groupid}/command/assign_loanofficer - - -POST groups/20/command/unassign_loanofficer -Content-Type: application/json -Request Body: -{ -{"loanOfficerId":"1"} -} - - -{ - "resourceId":20, - "changes":{} -} - -
-
-   + +  

Delete a Group

@@ -2870,12 +3249,13 @@ Request Body: POST https://DomainName/mifosng-provider/api/v1/groups/{groupid} -DELETE groups/7 +DELETE groups/5 { - "resourceId":7, - "changes":{} + "officeId": 5, + "groupId": 2, + "resourceId": 5 }
@@ -12385,6 +12765,40 @@ GET https://DomainName/api/v1/search?query=000000111 + + + Center + centers + Create a Center + List Centers + + Delete a Center + + + + centers/{centerId} + + Retrieve a Center + Update a Center + + + + Group + groups + Create a Group + List Groups + + Delete a Group + + + + groups/{group} + + Retrieve a Group + Update a Group + + + Loan Product diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffData.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffData.java index 8f7bd04a1..d2e0557d8 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/data/StaffData.java @@ -20,7 +20,7 @@ public class StaffData { private final String displayName; private final Long officeId; private final String officeName; - private final boolean isLoanOfficer; + private final Boolean isLoanOfficer; @SuppressWarnings("unused") private final Collection allowedOffices; @@ -30,13 +30,17 @@ public class StaffData { staff.isLoanOfficer, allowedOffices); } + public static StaffData lookup(final Long id, final String displayName) { + return new StaffData(id, null, null, displayName, null, null, null, null); + } + public static StaffData instance(final Long id, final String firstname, final String lastname, final String displayName, - final Long officeId, final String officeName, final boolean isLoanOfficer) { + final Long officeId, final String officeName, final Boolean isLoanOfficer) { return new StaffData(id, firstname, lastname, displayName, officeId, officeName, isLoanOfficer, null); } private StaffData(final Long id, final String firstname, final String lastname, final String displayName, final Long officeId, - final String officeName, final boolean isLoanOfficer, final Collection allowedOffices) { + final String officeName, final Boolean isLoanOfficer, final Collection allowedOffices) { this.id = id; this.firstname = firstname; this.lastname = lastname; @@ -47,40 +51,23 @@ public class StaffData { this.allowedOffices = allowedOffices; } - public Long getId() { return this.id; } - - public String getFirstname() { - return this.firstname; - } - - - public String getLastname() { - return this.lastname; - } - - public String getDisplayName() { return this.displayName; } - - public Long getOfficeId() { - return this.officeId; + public String getFirstname() { + return this.firstname; + } + + public String getLastname() { + return this.lastname; } - public String getOfficeName() { return this.officeName; } - - - public boolean isLoanOfficer() { - return this.isLoanOfficer; - } - - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformService.java index d3f814c3f..d9fb62873 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformService.java @@ -7,7 +7,6 @@ package org.mifosplatform.organisation.staff.service; import java.util.Collection; -import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; import org.mifosplatform.organisation.staff.data.StaffData; public interface StaffReadPlatformService { @@ -16,7 +15,7 @@ public interface StaffReadPlatformService { Collection retrieveAllStaff(final String extraCriteria); - Collection retrieveAllLoanOfficersByOffice(final Long officeId); + Collection retrieveAllStaffForDropdown(Long officeId); - StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId); + Collection retrieveAllLoanOfficersByOffice(final Long officeId); } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformServiceImpl.java index f3c1b6fba..18c3d381c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/organisation/staff/service/StaffReadPlatformServiceImpl.java @@ -8,19 +8,12 @@ package org.mifosplatform.organisation.staff.service; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collection; -import java.util.List; 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.staff.data.StaffAccountSummaryCollectionData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.exception.StaffNotFoundException; -import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; -import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; -import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData; -import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -32,16 +25,12 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; - private final ClientReadPlatformService clientReadPlatformService; - private final GroupReadPlatformService groupReadPlatformService; + private final StaffLookupMapper lookupMapper = new StaffLookupMapper(); @Autowired - public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, - final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService) { + public StaffReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource) { this.context = context; this.jdbcTemplate = new JdbcTemplate(dataSource); - this.clientReadPlatformService = clientReadPlatformService; - this.groupReadPlatformService = groupReadPlatformService; } private static final class StaffMapper implements RowMapper { @@ -67,11 +56,36 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { } } + private static final class StaffLookupMapper implements RowMapper { + + private final String schemaSql; + + public StaffLookupMapper() { + + final StringBuilder sqlBuilder = new StringBuilder(100); + sqlBuilder.append("s.id as id, s.display_name as displayName "); + sqlBuilder.append("from m_staff s "); + + this.schemaSql = sqlBuilder.toString(); + } + + public String schema() { + return this.schemaSql; + } + + @Override + public StaffData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String displayName = rs.getString("displayName"); + + return StaffData.lookup(id, displayName); + } + } + @Override public Collection retrieveAllStaff(final String extraCriteria) { - context.authenticatedUser(); - final StaffMapper rm = new StaffMapper(); String sql = "select " + rm.schema(); if (StringUtils.isNotBlank(extraCriteria)) { @@ -86,6 +100,24 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { return retrieveAllStaff(" office_id=" + officeId + " and is_loan_officer=1"); } + @Override + public Collection retrieveAllStaffForDropdown(final Long officeId) { + + final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId); + + final String sql = "select " + this.lookupMapper.schema() + " where s.office_id = ?"; + + return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { defaultOfficeId }); + } + + private Long defaultToUsersOfficeIfNull(final Long officeId) { + Long defaultOfficeId = officeId; + if (defaultOfficeId == null) { + defaultOfficeId = this.context.authenticatedUser().getOffice().getId(); + } + return defaultOfficeId; + } + @Override public StaffData retrieveStaff(final Long staffId) { @@ -100,73 +132,4 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService { throw new StaffNotFoundException(staffId); } } - - @Override - public StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId) { - - context.authenticatedUser(); - - final StaffClientMapper staffClientMapper = new StaffClientMapper(); - final String clientSql = "select distinct " + staffClientMapper.schema(); - - final StaffGroupMapper staffGroupMapper = new StaffGroupMapper(); - final String groupSql = "select distinct " + staffGroupMapper.schema(); - - final List clientSummaryList = this.jdbcTemplate.query(clientSql, - staffClientMapper, new Object[] { loanOfficerId }); - - for (StaffAccountSummaryCollectionData.ClientSummary clientSummary : clientSummaryList) { - - final Collection clientLoanAccounts = this.clientReadPlatformService - .retrieveClientLoanAccountsByLoanOfficerId(clientSummary.getId(), loanOfficerId); - - clientSummary.setLoans(clientLoanAccounts); - } - - final List groupSummaryList = this.jdbcTemplate.query(groupSql, staffGroupMapper, - new Object[] { loanOfficerId }); - - for (StaffAccountSummaryCollectionData.GroupSummary groupSummary : groupSummaryList) { - - final Collection groupLoanAccounts = this.groupReadPlatformService - .retrieveGroupLoanAccountsByLoanOfficerId(groupSummary.getId(), loanOfficerId); - - groupSummary.setLoans(groupLoanAccounts); - } - - return new StaffAccountSummaryCollectionData(clientSummaryList, groupSummaryList); - } - - private static final class StaffClientMapper implements RowMapper { - - public String schema() { - return " c.id as id, c.display_name as displayName from m_client c " - + " join m_loan l on c.id = l.client_id where l.loan_officer_id = ? "; - } - - @Override - public StaffAccountSummaryCollectionData.ClientSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - final Long id = JdbcSupport.getLong(rs, "id"); - final String displayName = rs.getString("displayName"); - - return new StaffAccountSummaryCollectionData.ClientSummary(id, displayName); - } - } - - private static final class StaffGroupMapper implements RowMapper { - - public String schema() { - return " g.id as id, g.name as name from m_group g" + " join m_loan l on g.id = l.group_id where l.loan_officer_id = ? "; - } - - @Override - public StaffAccountSummaryCollectionData.GroupSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) - throws SQLException { - final Long id = JdbcSupport.getLong(rs, "id"); - final String name = rs.getString("name"); - - return new StaffAccountSummaryCollectionData.GroupSummary(id, name); - } - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java index f47a05e7f..99b0ec534 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientData.java @@ -9,14 +9,17 @@ import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.CompareToBuilder; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.joda.time.LocalDate; import org.mifosplatform.organisation.office.data.OfficeLookup; -import org.mifosplatform.portfolio.group.data.GroupLookup; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; /** * Immutable data object representing client data. */ -final public class ClientData { +final public class ClientData implements Comparable { private final Long id; private final String accountNo; @@ -32,9 +35,12 @@ final public class ClientData { private final String imageKey; @SuppressWarnings("unused") private final Boolean imagePresent; - private final Collection parentGroups; - private final List allowedOffices; + // associations + private final Collection parentGroups; + + // template + private final List allowedOffices; private final ClientData currentChange; private final Collection allChanges; @@ -46,7 +52,8 @@ final public class ClientData { joiningDate, null, null, null, null, null); } - public static ClientData integrateChanges(final ClientData clientData, ClientData currentChange, final Collection allChanges) { + public static ClientData integrateChanges(final ClientData clientData, final ClientData currentChange, + final Collection allChanges) { return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, currentChange, allChanges, clientData.parentGroups); @@ -65,7 +72,7 @@ final public class ClientData { clientData.parentGroups); } - public static ClientData setParentGroups(final ClientData clientData, final Collection parentGroups) { + public static ClientData setParentGroups(final ClientData clientData, final Collection parentGroups) { return new ClientData(clientData.accountNo, clientData.officeId, clientData.officeName, clientData.id, clientData.firstname, clientData.middlename, clientData.lastname, clientData.fullname, clientData.displayName, clientData.externalId, clientData.joinedDate, clientData.imageKey, clientData.allowedOffices, clientData.currentChange, clientData.allChanges, @@ -80,10 +87,14 @@ final public class ClientData { null, null, null, null, null, null); } + public static ClientData lookup(final Long id, final String displayName, final Long officeId, final String officeName) { + return new ClientData(null, officeId, officeName, id, null, null, null, null, displayName, null, null, null, null, null, null, null); + } + public ClientData(final String accountNo, final Long officeId, final String officeName, final Long id, final String firstname, final String middlename, final String lastname, final String fullname, final String displayName, final String externalId, final LocalDate joinedDate, final String imageKey, final List allowedOffices, final ClientData currentChange, - final Collection allChanges, final Collection parentGroups) { + final Collection allChanges, final Collection parentGroups) { this.accountNo = accountNo; this.officeId = officeId; this.officeName = officeName; @@ -107,6 +118,35 @@ final public class ClientData { this.parentGroups = parentGroups; } + @Override + public int compareTo(final ClientData obj) { + if (obj == null) { return -1; } + return new CompareToBuilder() // + .append(this.id, obj.id) // + .append(this.displayName, obj.displayName) // + .toComparison(); + } + + @Override + public boolean equals(final Object obj) { + if (obj == null) { return false; } + if (obj == this) { return true; } + if (obj.getClass() != getClass()) { return false; } + ClientData rhs = (ClientData) obj; + return new EqualsBuilder() // + .append(this.id, rhs.id) // + .append(this.displayName, rhs.displayName) // + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) // + .append(this.id) // + .append(this.displayName) // + .toHashCode(); + } + public String displayName() { return this.displayName; } @@ -162,5 +202,4 @@ final public class ClientData { public LocalDate getJoinedDate() { return this.joinedDate; } - } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLookup.java deleted file mode 100644 index 407fb8334..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/client/data/ClientLookup.java +++ /dev/null @@ -1,88 +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.apache.commons.lang.StringUtils; - -public class ClientLookup { - - private final Long id; - private final String displayName; - private final Long officeId; - private final String officeName; - - public static ClientLookup template(final Long id, final String displayName, final Long officeId, final String officeName) { - return new ClientLookup(id, displayName, officeId, officeName); - } - - public static ClientLookup create(final Long id, final String displayName) { - return new ClientLookup(id, displayName, null, null); - } - - public ClientLookup(final Long id, final String firstname, final String lastname, final Long officeId, final String officeName) { - this.id = id; - - StringBuilder displayNameBuilder = new StringBuilder(firstname); - if (StringUtils.isNotBlank(displayNameBuilder.toString())) { - displayNameBuilder.append(' '); - } - displayNameBuilder.append(lastname); - - this.displayName = displayNameBuilder.toString(); - - this.officeId = officeId; - this.officeName = officeName; - } - - public ClientLookup(final Long id, final String displayName, final Long officeId, final String officeName) { - this.id = id; - this.displayName = displayName; - this.officeId = officeId; - this.officeName = officeName; - } - - public ClientLookup(final Long id, final String firstname, final String lastname) { - this.id = id; - - StringBuilder displayNameBuilder = new StringBuilder(firstname); - if (StringUtils.isNotBlank(displayNameBuilder.toString())) { - displayNameBuilder.append(' '); - } - displayNameBuilder.append(lastname); - - this.displayName = displayNameBuilder.toString(); - - this.officeId = null; - this.officeName = null; - } - - @Override - public boolean equals(Object obj) { - ClientLookup clientLookup = (ClientLookup) obj; - return this.id.equals(clientLookup.id); - } - - @Override - public int hashCode() { - return this.id.hashCode(); - } - - public Long getId() { - return id; - } - - public String getDisplayName() { - return displayName; - } - - public Long getOfficeId() { - return officeId; - } - - public String getOfficeName() { - return officeName; - } -} \ 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 9719380e5..fa22c0165 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 @@ -10,7 +10,6 @@ import java.util.Collection; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; -import org.mifosplatform.portfolio.client.data.ClientLookup; public interface ClientReadPlatformService { @@ -20,9 +19,9 @@ public interface ClientReadPlatformService { ClientData retrieveNewClientDetails(); - Collection retrieveAllIndividualClientsForLookup(String extraCriteria); + Collection retrieveAllIndividualClientsForLookup(String extraCriteria); - Collection retrieveAllIndividualClientsForLookupByOfficeId(Long officeId); + Collection retrieveAllIndividualClientsForLookupByOfficeId(Long officeId); ClientAccountSummaryCollectionData retrieveClientAccountDetails(Long clientId); @@ -30,4 +29,5 @@ public interface ClientReadPlatformService { ClientData retrieveClientByIdentifier(Long identifierTypeId, String identifierKey); + Collection retrieveClientMembersOfGroup(Long groupId); } \ No newline at end of file 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 b6e1330a8..1c69bccfa 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 @@ -21,9 +21,8 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; import org.mifosplatform.portfolio.client.data.ClientData; -import org.mifosplatform.portfolio.client.data.ClientLookup; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; -import org.mifosplatform.portfolio.group.data.GroupLookup; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.loanaccount.data.LoanStatusEnumData; import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations; import org.mifosplatform.useradministration.domain.AppUser; @@ -39,6 +38,8 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService private final JdbcTemplate jdbcTemplate; private final PlatformSecurityContext context; private final OfficeReadPlatformService officeReadPlatformService; + private final ClientLookupMapper lookupMapper = new ClientLookupMapper(); + private final ClientMembersOfGroupMapper membersOfGroupMapper = new ClientMembersOfGroupMapper(); @Autowired public ClientReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, @@ -70,7 +71,6 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService public ClientData retrieveIndividualClient(final Long clientId) { try { - AppUser currentUser = context.authenticatedUser(); String hierarchy = currentUser.getOffice().getHierarchy(); String hierarchySearchString = hierarchy + "%"; @@ -81,7 +81,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService ParentGroupsMapper cgrm = new ParentGroupsMapper(); String cgSql = "select " + cgrm.parentGroupsSchema(); - Collection parentGroups = this.jdbcTemplate.query(cgSql, cgrm, new Object[] { clientId }); + Collection parentGroups = this.jdbcTemplate.query(cgSql, cgrm, new Object[] { clientId }); return ClientData.setParentGroups(clientData , parentGroups); @@ -91,30 +91,23 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } @Override - public Collection retrieveAllIndividualClientsForLookup(final String extraCriteria) { + public Collection retrieveAllIndividualClientsForLookup(final String extraCriteria) { - this.context.authenticatedUser(); - - ClientLookupMapper rm = new ClientLookupMapper(); - - String sql = "select " + rm.clientLookupSchema(); + String sql = "select " + this.lookupMapper.schema(); if (StringUtils.isNotBlank(extraCriteria)) { sql += " and (" + extraCriteria + ")"; } - return this.jdbcTemplate.query(sql, rm, new Object[] {}); + return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] {}); } @Override - public Collection retrieveAllIndividualClientsForLookupByOfficeId(final Long officeId) { - this.context.authenticatedUser(); + public Collection retrieveAllIndividualClientsForLookupByOfficeId(final Long officeId) { - ClientLookupMapper rm = new ClientLookupMapper(); + final String sql = "select " + this.lookupMapper.schema() + " and c.office_id = ?"; - String sql = "select " + rm.clientLookupSchema() + " and c.office_id = " + officeId; - - return this.jdbcTemplate.query(sql, rm, new Object[] {}); + return this.jdbcTemplate.query(sql, this.lookupMapper, new Object[] { officeId }); } @Override @@ -128,6 +121,63 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService return ClientData.template(officeId, new LocalDate(), offices); } + @Override + public Collection retrieveClientMembersOfGroup(final Long groupId) { + + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + final String sql = "select " + this.membersOfGroupMapper.schema() + + " where o.hierarchy like ? and pgc.group_id = ? and c.is_deleted=0"; + + return this.jdbcTemplate.query(sql, this.membersOfGroupMapper, new Object[] { hierarchySearchString, groupId }); + } + + private static final class ClientMembersOfGroupMapper implements RowMapper { + + private final String schema; + + public ClientMembersOfGroupMapper() { + final StringBuilder sqlBuilder = new StringBuilder(200); + + sqlBuilder.append("c.id as id, c.account_no as accountNo, c.external_id as externalId, "); + sqlBuilder.append("c.office_id as officeId, o.name as officeName, "); + sqlBuilder.append("c.firstname as firstname, c.middlename as middlename, c.lastname as lastname, "); + sqlBuilder.append("c.fullname as fullname, c.display_name as displayName, "); + sqlBuilder.append("c.joined_date as joinedDate, c.image_key as imagekey "); + sqlBuilder.append("from m_client c "); + sqlBuilder.append("join m_office o on o.id = c.office_id "); + sqlBuilder.append("join m_group_client pgc on pgc.client_id = c.id"); + + this.schema = sqlBuilder.toString(); + } + + public String schema() { + return this.schema; + } + + @Override + public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final String accountNo = rs.getString("accountNo"); + final Long officeId = JdbcSupport.getLong(rs, "officeId"); + final Long id = JdbcSupport.getLong(rs, "id"); + final String firstname = rs.getString("firstname"); + final String middlename = rs.getString("middlename"); + final String lastname = rs.getString("lastname"); + final String fullname = rs.getString("fullname"); + final String displayName = rs.getString("displayName"); + final String externalId = rs.getString("externalId"); + final LocalDate joinedDate = JdbcSupport.getLocalDate(rs, "joinedDate"); + final String imageKey = rs.getString("imageKey"); + final String officeName = rs.getString("officeName"); + + return new ClientData(accountNo, officeId, officeName, id, firstname, middlename, lastname, fullname, displayName, externalId, + joinedDate, imageKey, null, null, null, null); + } + } + private static final class ClientMapper implements RowMapper { public String clientSchema() { @@ -160,7 +210,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } - private static final class ParentGroupsMapper implements RowMapper { + private static final class ParentGroupsMapper implements RowMapper { public String parentGroupsSchema() { return "gp.id As groupId , gp.name As groupName from m_client cl JOIN m_group_client gc ON cl.id = gc.client_id " @@ -168,31 +218,44 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService } @Override - public GroupLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { final Long groupId = JdbcSupport.getLong(rs, "groupId"); final String groupName = rs.getString("groupName"); - return new GroupLookup(groupId, groupName); + return GroupGeneralData.lookup(groupId, groupName); } - } - private static final class ClientLookupMapper implements RowMapper { + private static final class ClientLookupMapper implements RowMapper { - public String clientLookupSchema() { - return "c.id as id, c.display_name as displayName, " + "c.office_id as officeId, o.name as officeName " - + "from m_client c join m_office o on o.id = c.office_id where c.is_deleted=0 "; + private final String schema; + + public ClientLookupMapper() { + StringBuilder builder = new StringBuilder(200); + + builder.append("c.id as id, c.display_name as displayName, "); + builder.append("c.office_id as officeId, o.name as officeName "); + builder.append("from m_client c "); + builder.append("join m_office o on o.id = c.office_id "); + builder.append("where c.is_deleted=0"); + + this.schema = builder.toString(); + } + + public String schema() { + return this.schema; } @Override - public ClientLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - Long id = rs.getLong("id"); - String displayName = rs.getString("displayName"); - Long officeId = rs.getLong("officeId"); - String officeName = rs.getString("officeName"); + public ClientData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - return ClientLookup.template(id, displayName, officeId, officeName); + final Long id = rs.getLong("id"); + final String displayName = rs.getString("displayName"); + final Long officeId = rs.getLong("officeId"); + final String officeName = rs.getString("officeName"); + + return ClientData.lookup(id, displayName, officeId, officeName); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java index aa8e51964..f4c3a4e64 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/collectionsheet/service/CollectionSheetReadPlatformServiceImpl.java @@ -21,10 +21,8 @@ import org.mifosplatform.portfolio.collectionsheet.data.JLGClientsData; import org.mifosplatform.portfolio.collectionsheet.data.JLGCollectionSheetData; import org.mifosplatform.portfolio.collectionsheet.data.JLGCollectionSheetFlatData; import org.mifosplatform.portfolio.collectionsheet.data.LoanDueData; -import org.mifosplatform.portfolio.group.data.GroupData; -import org.mifosplatform.portfolio.group.data.GroupTypes; -import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; -import org.mifosplatform.portfolio.group.service.GroupReadPlatformServiceImpl; +import org.mifosplatform.portfolio.group.data.CenterData; +import org.mifosplatform.portfolio.group.service.CenterReadPlatformService; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.beans.factory.annotation.Autowired; @@ -39,43 +37,35 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe private final PlatformSecurityContext context; private final NamedParameterJdbcTemplate namedParameterjdbcTemplate; - private final GroupReadPlatformServiceImpl groupReadPlatformServiceImpl; + private final CenterReadPlatformService centerReadPlatformService; @Autowired public CollectionSheetReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, - final GroupReadPlatformServiceImpl groupReadPlatformServiceImpl) { + final CenterReadPlatformService centerReadPlatformService) { this.context = context; + this.centerReadPlatformService = centerReadPlatformService; this.namedParameterjdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - this.groupReadPlatformServiceImpl = groupReadPlatformServiceImpl; } @Override - public JLGCollectionSheetData retriveCollectionSheet(final LocalDate dueDate, final Long groupId) { + public JLGCollectionSheetData retriveCollectionSheet(final LocalDate dueDate, final Long centerId) { final AppUser currentUser = this.context.authenticatedUser(); final String hierarchy = currentUser.getOffice().getHierarchy(); final String officeHierarchy = hierarchy + "%"; - final GroupData groupData = this.groupReadPlatformServiceImpl.retrieveGroup(groupId , GroupTypes.CENTER.getId()); - if (groupData == null) { throw new GroupNotFoundException(groupId); } - - final String groupHierarchy = groupData.getHierarchy() + "%"; + final CenterData center = this.centerReadPlatformService.retrieveOne(centerId); + final String groupHierarchy = center.getHierarchy() + "%"; final JLGCollectionSheetData jlgCollectionSheetData = buildJLGCollectionSheet(groupHierarchy, officeHierarchy, dueDate); return jlgCollectionSheetData; } - /** - * @param groupHierarchy - * @param officeHierarchy - * @param dueDate - * @return - * - * Reads all the loans which are due for disbursement or collection - * and builds hierarchical data structure for collections sheet with - * hierarchy Groups >> Clients >> Loans. - * + /* + * Reads all the loans which are due for disbursement or collection and + * builds hierarchical data structure for collections sheet with hierarchy + * Groups >> Clients >> Loans. */ @SuppressWarnings("null") private JLGCollectionSheetData buildJLGCollectionSheet(final String groupHierarchy, final String officeHierarchy, @@ -99,8 +89,9 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe if (jlgCollectionSheetFlatData != null) { for (final JLGCollectionSheetFlatData collectionSheetFlatData : jlgCollectionSheetFlatData) { - - loanProducts.add(LoanProductData.lookupWithCurrency(collectionSheetFlatData.getProductId(), collectionSheetFlatData.getProductShortName(), collectionSheetFlatData.getCurrency())); + + loanProducts.add(LoanProductData.lookupWithCurrency(collectionSheetFlatData.getProductId(), + collectionSheetFlatData.getProductShortName(), collectionSheetFlatData.getCurrency())); corrCollectioSheetFlatData = collectionSheetFlatData; if (firstTime || collectionSheetFlatData.getGroupId().equals(prevGroupId)) { @@ -113,7 +104,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe clientLoansData.setLoans(loanDueDatas); clientLoansDatas.add(clientLoansData); loanDueDatas = new ArrayList(); - + if (collectionSheetFlatData.getLoanId() != null) { loanDueDatas.add(collectionSheetFlatData.getLoanDueData()); } @@ -147,11 +138,11 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe // FIXME Need to check last loan is added under previous // client/group or new client / previous group or new client / new // group - if(corrCollectioSheetFlatData != null){ + if (corrCollectioSheetFlatData != null) { final ClientLoansData lastClientLoansData = corrCollectioSheetFlatData.getClientLoansData(); lastClientLoansData.setLoans(loanDueDatas); clientLoansDatas.add(lastClientLoansData); - + final JLGClientsData jlgClientsData = corrCollectioSheetFlatData.getJLGClientsData(); jlgClientsData.setClients(clientLoansDatas); jlgClientsDatas.add(jlgClientsData); @@ -230,7 +221,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe final Integer accountStatusId = JdbcSupport.getInteger(rs, "accountStatusId"); final String productShortName = rs.getString("productShortName"); final Long productId = JdbcSupport.getLong(rs, "productId"); - + final String currencyCode = rs.getString("currencyCode"); final String currencyName = rs.getString("currencyName"); final String currencyNameCode = rs.getString("currencyNameCode"); @@ -238,7 +229,7 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe final Integer currencyDigits = JdbcSupport.getInteger(rs, "currencyDigits"); final CurrencyData currencyData = new CurrencyData(currencyCode, currencyName, currencyDigits, currencyDisplaySymbol, currencyNameCode); - + final BigDecimal disbursementAmount = rs.getBigDecimal("disbursementAmount"); final BigDecimal principalDue = rs.getBigDecimal("principalDue"); final BigDecimal principalPaid = rs.getBigDecimal("principalPaid"); @@ -247,8 +238,8 @@ public class CollectionSheetReadPlatformServiceImpl implements CollectionSheetRe final BigDecimal chargesDue = rs.getBigDecimal("chargesDue"); return new JLGCollectionSheetFlatData(groupName, groupId, staffId, staffName, levelId, levelName, clientName, clientId, loanId, - accountId, accountStatusId, productShortName, productId, currencyData, disbursementAmount, - principalDue, principalPaid, interestDue, interestPaid, chargesDue); + accountId, accountStatusId, productShortName, productId, currencyData, disbursementAmount, principalDue, principalPaid, + interestDue, interestPaid, chargesDue); } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java index a3e774c04..7dd4acf6c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/CentersApiResource.java @@ -23,7 +23,6 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.apache.commons.lang.StringUtils; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; @@ -33,10 +32,11 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.group.data.CenterData; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; -import org.mifosplatform.portfolio.group.data.GroupData; -import org.mifosplatform.portfolio.group.data.GroupTypes; +import org.mifosplatform.portfolio.group.service.CenterReadPlatformService; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; +import org.mifosplatform.portfolio.group.service.SearchParameters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -46,30 +46,26 @@ import org.springframework.stereotype.Component; @Scope("singleton") public class CentersApiResource { - /* - * GROUP_DATA_PARAMETERS is used by ToApiJsonSerializer, make sure E's properties and E_PARAMETERS are in same - */ - private static final Set CENTER_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "name", "externalId", "officeId", - "officeName", "staffId", "staffName", "parentId", "parentName", "hierarchy", "groupSummaryData", "groupLevelData", - "clientMembers", "allowedClients", "allowedOffices", "allowedParentGroups", "allowedStaffs", "childGroups")); - private final PlatformSecurityContext context; + private final CenterReadPlatformService centerReadPlatformService; private final GroupReadPlatformService groupReadPlatformService; - private final ToApiJsonSerializer toApiJsonSerializer; + private final ToApiJsonSerializer centerApiJsonSerializer; + private final ToApiJsonSerializer toApiJsonSerializer; private final ToApiJsonSerializer groupSummaryToApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - - private static final Long LEVEL_ID = GroupTypes.CENTER.getId(); @Autowired - public CentersApiResource(final PlatformSecurityContext context, final GroupReadPlatformService groupReadPlatformService, - final ToApiJsonSerializer toApiJsonSerializer, + public CentersApiResource(final PlatformSecurityContext context, final CenterReadPlatformService centerReadPlatformService, + final GroupReadPlatformService groupReadPlatformService, final ToApiJsonSerializer centerApiJsonSerializer, + final ToApiJsonSerializer toApiJsonSerializer, final ToApiJsonSerializer groupSummaryToApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.context = context; + this.centerReadPlatformService = centerReadPlatformService; this.groupReadPlatformService = groupReadPlatformService; + this.centerApiJsonSerializer = centerApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer; this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; @@ -77,61 +73,59 @@ public class CentersApiResource { } @GET + @Path("template") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllCenters(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, - @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId, - @QueryParam("name") final String name , @QueryParam("underHierarchy") final String hierarchy) { + public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) { - this.context.authenticatedUser().validateHasReadPermission("CENTER"); + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.CENTER_RESOURCE_NAME); - - final String extraCriteria = getCenterExtraCriteria(sqlSearch, officeId, externalId, name , LEVEL_ID , hierarchy); - final Collection centers = this.groupReadPlatformService.retrieveAllGroups(extraCriteria); + final CenterData template = this.centerReadPlatformService.retrieveTemplate(officeId); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, centers, CENTER_DATA_PARAMETERS); + return this.centerApiJsonSerializer.serialize(settings, template, GroupingTypesApiConstants.CENTER_RESPONSE_DATA_PARAMETERS); + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId, + @QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy) { + + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.CENTER_RESOURCE_NAME); + + final SearchParameters searchCriteria = SearchParameters.from(sqlSearch, officeId, externalId, name, hierarchy); + final Collection centers = this.centerReadPlatformService.retrieveAll(searchCriteria); + + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.centerApiJsonSerializer.serialize(settings, centers, GroupingTypesApiConstants.CENTER_RESPONSE_DATA_PARAMETERS); } @GET @Path("{centerId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveCenterData(@Context final UriInfo uriInfo, @PathParam("centerId") final Long centerId) { + public String retrieveOne(@Context final UriInfo uriInfo, @PathParam("centerId") final Long centerId) { - this.context.authenticatedUser().validateHasReadPermission("CENTER"); + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.CENTER_RESOURCE_NAME); + + CenterData center = this.centerReadPlatformService.retrieveOne(centerId); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - final GroupData group = this.groupReadPlatformService.retrieveGroupDetails(centerId, LEVEL_ID, template); - - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, group, CENTER_DATA_PARAMETERS); - } - - @GET - @Path("template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId) { - - this.context.authenticatedUser().validateHasReadPermission("CENTER"); - - GroupData centerTemplateData = null; - if (officeId != null) { - centerTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId, LEVEL_ID); - } else { - centerTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(this.context.authenticatedUser().getOffice().getId(), - LEVEL_ID); + if (template) { + final CenterData templateCenter = this.centerReadPlatformService.retrieveTemplate(center.officeId()); + center = CenterData.withTemplate(templateCenter, center); } final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, centerTemplateData, CENTER_DATA_PARAMETERS); + return this.centerApiJsonSerializer.serialize(settings, center, GroupingTypesApiConstants.CENTER_RESPONSE_DATA_PARAMETERS); } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String createCenter(final String apiRequestBodyAsJson) { + public String create(final String apiRequestBodyAsJson) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .createCenter() // @@ -146,7 +140,7 @@ public class CentersApiResource { @Path("{centerId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateGroup(@PathParam("centerId") final Long centerId, final String apiRequestBodyAsJson) { + public String update(@PathParam("centerId") final Long centerId, final String apiRequestBodyAsJson) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .updateCenter(centerId) // @@ -160,25 +154,24 @@ public class CentersApiResource { @Path("{centerId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String deleteGroup(@PathParam("centerId") final Long centerId) { + public String delete(@PathParam("centerId") final Long centerId) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .deleteCenter(centerId) // .build(); // final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); - } @GET - @Path("{groupId}/loans") + @Path("{centerId}/loans") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) { + public String retrieveGroupAccount(@PathParam("centerId") final Long centerId, @Context final UriInfo uriInfo) { - this.context.authenticatedUser().validateHasReadPermission("GROUP"); + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.CENTER_RESOURCE_NAME); - final GroupAccountSummaryCollectionData groupAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(groupId); + final GroupAccountSummaryCollectionData groupAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(centerId); final Set GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet(Arrays.asList("pendingApprovalLoans", "awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", @@ -187,45 +180,4 @@ public class CentersApiResource { final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.groupSummaryToApiJsonSerializer.serialize(settings, groupAccount, GROUP_ACCOUNTS_DATA_PARAMETERS); } - - // 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where - // clause is ambiguous - // caused by the same name of columns in m_office and m_group tables - private String getCenterExtraCriteria(String sqlSearch, final Long officeId, final String externalId, final String name , final Long levelId ,final String hierarchy) { - - String extraCriteria = " and g.level_id = " + LEVEL_ID + " "; - - if (sqlSearch != null) { - sqlSearch = sqlSearch.replaceAll(" name ", " g.name "); - sqlSearch = sqlSearch.replaceAll("name ", "g.name "); - extraCriteria = " and (" + sqlSearch + ")"; - } - - if (officeId != null) { - extraCriteria += " and g.office_id = " + officeId; - } - - if (levelId != null) { - extraCriteria += " and g.level_Id = " + levelId; - } - - if (externalId != null) { - extraCriteria += " and g.external_id = " + ApiParameterHelper.sqlEncodeString(externalId); - } - - if (name != null) { - extraCriteria += " and g.name like " + ApiParameterHelper.sqlEncodeString(name + "%"); - } - - - if (hierarchy != null) { - extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%"); - } - - if (StringUtils.isNotBlank(extraCriteria)) { - extraCriteria = extraCriteria.substring(4); - } - - return extraCriteria; - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java new file mode 100644 index 000000000..c45e7c550 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupingTypesApiConstants.java @@ -0,0 +1,50 @@ +package org.mifosplatform.portfolio.group.api; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.mifosplatform.portfolio.group.data.CenterData; + +public class GroupingTypesApiConstants { + + public static final String CENTER_RESOURCE_NAME = "center"; + public static final String GROUP_RESOURCE_NAME = "group"; + public static final String COMMUNAL_BANK_RESOURCE_NAME = "communalbank"; + + // general + public static final String localeParamName = "locale"; + public static final String dateFormatParamName = "dateFormat"; + + // center parameters + public static final String idParamName = "id"; + public static final String nameParamName = "name"; + public static final String externalIdParamName = "externalId"; + public static final String officeIdParamName = "officeId"; + public static final String staffIdParamName = "staffId"; + + // response parameters + public static final String hierarchyParamName = "hierarchy"; + public static final String officeNameParamName = "officeName"; + public static final String staffNameParamName = "staffName"; + + public static final Set CENTER_REQUEST_DATA_PARAMETERS = new HashSet(Arrays.asList(localeParamName, + dateFormatParamName, nameParamName, externalIdParamName, officeIdParamName, staffIdParamName)); + + /** + * These parameters will match the class level parameters of + * {@link CenterData}. Where possible, we try to get response parameters to + * match those of request parameters. + */ + public static final Set CENTER_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, nameParamName, + externalIdParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName, + "officeOptions", "staffOptions")); + + public static final Set CENTER_GROUP_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, nameParamName, + externalIdParamName, officeIdParamName, officeNameParamName, staffIdParamName, staffNameParamName, hierarchyParamName, + "officeOptions", "staffOptions")); + + public static final Set GROUP_RESPONSE_DATA_PARAMETERS = new HashSet(Arrays.asList(idParamName, nameParamName, + externalIdParamName, officeIdParamName, officeNameParamName, "parentId", "parentName", staffIdParamName, staffNameParamName, + hierarchyParamName, "officeOptions", "staffOptions", "clientOptions")); +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java index dc2b45ba4..c3f6c6eab 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/api/GroupsApiResource.java @@ -23,7 +23,6 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriInfo; -import org.apache.commons.lang.StringUtils; import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.service.CommandWrapperBuilder; import org.mifosplatform.commands.service.PortfolioCommandSourceWritePlatformService; @@ -33,107 +32,122 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.serialization.ApiRequestJsonSerializationSettings; import org.mifosplatform.infrastructure.core.serialization.ToApiJsonSerializer; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; +import org.mifosplatform.portfolio.client.data.ClientData; +import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; -import org.mifosplatform.portfolio.group.data.GroupData; -import org.mifosplatform.portfolio.group.data.GroupTypes; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; +import org.mifosplatform.portfolio.group.service.CenterReadPlatformService; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; +import org.mifosplatform.portfolio.group.service.SearchParameters; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; @Path("/groups") @Component @Scope("singleton") public class GroupsApiResource { - /* - * GROUP_DATA_PARAMETERS is used by ToApiJsonSerializer, make sure E's properties and E_PARAMETERS are in same - */ - private static final Set GROUP_DATA_PARAMETERS = new HashSet(Arrays.asList("id", "name", "externalId", "officeId", - "officeName", "staffId", "staffName", "parentId", "parentName", "hierarchy", "groupSummaryData", "groupLevelData", - "clientMembers", "allowedClients", "allowedOffices", "allowedParentGroups", "allowedStaffs", "childGroups")); - private final PlatformSecurityContext context; private final GroupReadPlatformService groupReadPlatformService; - private final ToApiJsonSerializer toApiJsonSerializer; + private final CenterReadPlatformService centerReadPlatformService; + private final ClientReadPlatformService clientReadPlatformService; + private final ToApiJsonSerializer toApiJsonSerializer; + private final ToApiJsonSerializer groupGeneralApiJsonSerializer; private final ToApiJsonSerializer groupSummaryToApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; - - private static final Long LEVEL_ID = GroupTypes.GROUP.getId(); @Autowired public GroupsApiResource(final PlatformSecurityContext context, final GroupReadPlatformService groupReadPlatformService, - final ToApiJsonSerializer toApiJsonSerializer, + final CenterReadPlatformService centerReadPlatformService, final ClientReadPlatformService clientReadPlatformService, + final ToApiJsonSerializer toApiJsonSerializer, + final ToApiJsonSerializer groupTopOfHierarchyApiJsonSerializer, final ToApiJsonSerializer groupSummaryToApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.context = context; this.groupReadPlatformService = groupReadPlatformService; + this.centerReadPlatformService = centerReadPlatformService; + this.clientReadPlatformService = clientReadPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; + this.groupGeneralApiJsonSerializer = groupTopOfHierarchyApiJsonSerializer; this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; } @GET + @Path("template") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveAllGroups(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, + public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId, + @QueryParam("center") final boolean isCenterGroup, + @QueryParam("centerId") final Long centerId) { + + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME); + + if (centerId != null) { + final GroupGeneralData centerGroupTemplate = this.centerReadPlatformService.retrieveCenterGroupTemplate(centerId); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.groupGeneralApiJsonSerializer.serialize(settings, centerGroupTemplate, + GroupingTypesApiConstants.CENTER_GROUP_RESPONSE_DATA_PARAMETERS); + } + + final GroupGeneralData groupTemplate = this.groupReadPlatformService.retrieveTemplate(officeId, isCenterGroup); + final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); + return this.groupGeneralApiJsonSerializer.serialize(settings, groupTemplate, + GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS); + } + + @GET + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public String retrieveAll(@Context final UriInfo uriInfo, @QueryParam("sqlSearch") final String sqlSearch, @QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId, - @QueryParam("name") final String name , @QueryParam("underHierarchy") final String hierarchy) { + @QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy) { - this.context.authenticatedUser().validateHasReadPermission("GROUP"); + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME); - final String extraCriteria = getGroupExtraCriteria(sqlSearch, officeId, externalId, name , LEVEL_ID , hierarchy); - final Collection groups = this.groupReadPlatformService.retrieveAllGroups(extraCriteria); + final SearchParameters searchCriteria = SearchParameters.from(sqlSearch, officeId, externalId, name, hierarchy); + final Collection groups = this.groupReadPlatformService.retrieveAll(searchCriteria); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, groups, GROUP_DATA_PARAMETERS); + return this.groupGeneralApiJsonSerializer.serialize(settings, groups, GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS); } @GET @Path("{groupId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveGroupData(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId) { + public String retrieveOne(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId) { - this.context.authenticatedUser().validateHasReadPermission("GROUP"); + this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME); + GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId); + + Collection membersOfGroup = this.clientReadPlatformService.retrieveClientMembersOfGroup(groupId); + if (CollectionUtils.isEmpty(membersOfGroup)) { + membersOfGroup = null; + } + final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); - final GroupData group = this.groupReadPlatformService.retrieveGroupDetails(groupId, LEVEL_ID, template); - - final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, group, GROUP_DATA_PARAMETERS); - } - - @GET - @Path("template") - @Consumes({ MediaType.APPLICATION_JSON }) - @Produces({ MediaType.APPLICATION_JSON }) - public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId, - @QueryParam("centerId") final Long centerId) { - - this.context.authenticatedUser().validateHasReadPermission("GROUP"); - - GroupData groupTemplateData = null; - if (centerId != null) { - groupTemplateData = this.groupReadPlatformService.retrieveNewChildGroupDetails(officeId, LEVEL_ID, centerId); - } else if (officeId != null ) { - groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId, LEVEL_ID); - } else{ - groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(this.context.authenticatedUser().getOffice().getId(), - LEVEL_ID); + if (template) { + final GroupGeneralData templateGroup = this.groupReadPlatformService.retrieveTemplate(group.officeId(), false); + group = GroupGeneralData.withTemplateAndAssociations(templateGroup, group, membersOfGroup); + } else { + group = GroupGeneralData.withAssocations(group, membersOfGroup); } final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); - return this.toApiJsonSerializer.serialize(settings, groupTemplateData, GROUP_DATA_PARAMETERS); + return this.groupGeneralApiJsonSerializer.serialize(settings, group, GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS); } @POST @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String createGroup(final String apiRequestBodyAsJson) { + public String create(final String apiRequestBodyAsJson) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .createGroup() // @@ -141,7 +155,6 @@ public class GroupsApiResource { .build(); // final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); - } @POST @@ -163,7 +176,7 @@ public class GroupsApiResource { @Path("{groupId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String updateGroup(@PathParam("groupId") final Long groupId, final String apiRequestBodyAsJson) { + public String update(@PathParam("groupId") final Long groupId, final String apiRequestBodyAsJson) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .updateGroup(groupId) // @@ -177,21 +190,20 @@ public class GroupsApiResource { @Path("{groupId}") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String deleteGroup(@PathParam("groupId") final Long groupId) { + public String delete(@PathParam("groupId") final Long groupId) { final CommandWrapper commandRequest = new CommandWrapperBuilder() // .deleteGroup(groupId) // .build(); // final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); return this.toApiJsonSerializer.serialize(result); - } @GET @Path("{groupId}/loans") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) { + public String retrieveLoans(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) { this.context.authenticatedUser().validateHasReadPermission("GROUP"); @@ -204,46 +216,4 @@ public class GroupsApiResource { final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); return this.groupSummaryToApiJsonSerializer.serialize(settings, groupAccount, GROUP_ACCOUNTS_DATA_PARAMETERS); } - - // 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where - // clause is ambiguous - // caused by the same name of columns in m_office and m_group tables - private String getGroupExtraCriteria(String sqlSearch, final Long officeId, final String externalId, final String name, - final Long levelId , final String hierarchy) { - - String extraCriteria = ""; - - if (sqlSearch != null) { - sqlSearch = sqlSearch.replaceAll(" name ", " g.name "); - sqlSearch = sqlSearch.replaceAll("name ", "g.name "); - extraCriteria = " and (" + sqlSearch + ")"; - } - - if (officeId != null) { - extraCriteria += " and g.office_id = " + officeId; - } - - if (levelId != null) { - extraCriteria += " and g.level_Id = " + levelId; - } - - if (externalId != null) { - extraCriteria += " and g.external_id = " + ApiParameterHelper.sqlEncodeString(externalId); - } - - if (name != null) { - extraCriteria += " and g.name like " + ApiParameterHelper.sqlEncodeString(name + "%"); - } - - - if (hierarchy != null) { - extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%"); - } - - if (StringUtils.isNotBlank(extraCriteria)) { - extraCriteria = extraCriteria.substring(4); - } - - return extraCriteria; - } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/CenterData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/CenterData.java new file mode 100644 index 000000000..3ce0f270b --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/CenterData.java @@ -0,0 +1,90 @@ +/** + * 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.office.data.OfficeData; +import org.mifosplatform.organisation.staff.data.StaffData; + +/** + * Immutable data object representing groups. + */ +public class CenterData { + + private final Long id; + private final String name; + private final String externalId; + private final Long officeId; + private final String officeName; + private final Long staffId; + private final String staffName; + private final String hierarchy; + + // associations + @SuppressWarnings("unused") + private final Collection groups; + + // template + private final Collection officeOptions; + private final Collection staffOptions; + + public static CenterData template(final Long officeId, final Collection officeOptions, + final Collection staffOptions) { + return new CenterData(null, null, null, officeId, null, null, null, null, officeOptions, staffOptions); + } + + public static CenterData withTemplate(final CenterData templateCenter, final CenterData center) { + return new CenterData(center.id, center.name, center.externalId, center.officeId, center.officeName, center.staffId, + center.staffName, center.hierarchy, templateCenter.officeOptions, templateCenter.staffOptions); + } + + public static CenterData instance(final Long id, final String name, final String externalId, final Long officeId, + final String officeName, final Long staffId, final String staffName, final String hierarchy) { + + final Collection officeOptions = null; + final Collection staffOptions = null; + + return new CenterData(id, name, externalId, officeId, officeName, staffId, staffName, hierarchy, officeOptions, staffOptions); + } + + private CenterData(final Long id, final String name, final String externalId, final Long officeId, final String officeName, + final Long staffId, final String staffName, final String hierarchy, final Collection officeOptions, + final Collection staffOptions) { + this.id = id; + this.name = name; + this.externalId = externalId; + this.officeId = officeId; + this.officeName = officeName; + this.staffId = staffId; + this.staffName = staffName; + this.hierarchy = hierarchy; + + this.officeOptions = officeOptions; + this.staffOptions = staffOptions; + this.groups = null; + } + + public Long officeId() { + return this.officeId; + } + + public Long staffId() { + return this.staffId; + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getHierarchy() { + return this.hierarchy; + } +} \ 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 deleted file mode 100644 index 17831e1af..000000000 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupData.java +++ /dev/null @@ -1,179 +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.group.data; - -import java.util.Collection; - -import org.mifosplatform.organisation.office.data.OfficeData; -import org.mifosplatform.organisation.staff.data.StaffData; -import org.mifosplatform.portfolio.client.data.ClientLookup; - -/** - * Immutable data object representing groups. - */ -public class GroupData { - - private final Long id; - private final String name; - private final String externalId; - private final Long officeId; - private final String officeName; - private final Long staffId; - private final String staffName; - private final Long parentId; - private final String parentName; - private final String hierarchy; - @SuppressWarnings("unused") - private final GroupSummary groupSummaryData; - @SuppressWarnings("unused") - private final GroupLevelData groupLevelData; - private final Collection clientMembers; - @SuppressWarnings("unused") - private final Collection allowedClients; - @SuppressWarnings("unused") - private final Collection allowedOffices; - @SuppressWarnings("unused") - private final Collection allowedParentGroups; - @SuppressWarnings("unused") - private final Collection allowedStaffs; - @SuppressWarnings("unused") - private final Collection childGroups; - - public GroupData(Long id, String name, String externalId, Long officeId, Long staffId, Long parentId, String hierarchy) { - this.id = id; - this.name = name; - this.externalId = externalId; - this.officeId = officeId; - this.staffId = staffId; - this.parentId = parentId; - this.hierarchy = hierarchy; - this.officeName = null; - this.parentName = null; - this.staffName = null; - this.groupSummaryData = null; - this.groupLevelData = null; - this.clientMembers = null; - this.allowedClients = null; - this.allowedOffices = null; - this.allowedParentGroups = null; - this.allowedStaffs = null; - this.childGroups = null; - } - - public GroupData(final Long id, final Long officeId, final String officeName, final String name, final String externalId, - final Long parentId, final String parentName, final Long staffId, final String staffName, final String hierarchy) { - this.id = id; - this.officeId = officeId; - this.officeName = officeName; - this.name = name; - this.externalId = externalId; - this.parentId = parentId; - this.parentName = parentName; - this.staffId = staffId; - this.staffName = staffName; - this.hierarchy = hierarchy; - this.groupSummaryData = null; - this.groupLevelData = null; - this.clientMembers = null; - this.allowedClients = null; - this.allowedOffices = null; - this.allowedParentGroups = null; - this.allowedStaffs = null; - this.childGroups = null; - } - - 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 GroupSummary groupSummaryData) { - this.id = group.getId(); - this.officeId = group.getOfficeId(); - this.officeName = group.getOfficeName(); - this.name = group.getName(); - this.externalId = group.getExternalId(); - this.parentId = group.getParentId(); - this.parentName = group.getParentName(); - this.staffId = group.getStaffId(); - this.staffName = group.getStaffName(); - this.hierarchy = group.getHierarchy(); - - this.groupSummaryData = groupSummaryData; - this.groupLevelData = groupLevelData; - this.clientMembers = clientMembers; - this.allowedClients = allowedClients; - this.allowedOffices = allowedOffices; - this.allowedParentGroups = allowedParentGroups; - this.allowedStaffs = allowedStaffs; - this.childGroups = childGroups; - } - - public GroupData(final Long officeId, final Collection allowedClients, final Collection allowedOffices, - final Collection allowedParentGroups, final GroupLevelData groupLevelData, - final Collection allowedStaffs) { - this.id = null; - this.officeId = officeId; - this.officeName = null; - this.name = null; - this.externalId = null; - this.clientMembers = null; - this.parentId = null; - this.parentName = null; - this.staffId = null; - this.staffName = null; - this.hierarchy = null; - this.groupSummaryData = null; - this.groupLevelData = groupLevelData; - this.allowedClients = allowedClients; - this.allowedOffices = allowedOffices; - this.allowedParentGroups = allowedParentGroups; - this.allowedStaffs = allowedStaffs; - this.childGroups = null; - } - - public Long getId() { - return this.id; - } - - public String getName() { - return this.name; - } - - public String getExternalId() { - return this.externalId; - } - - public Long getOfficeId() { - return this.officeId; - } - - public String getOfficeName() { - return this.officeName; - } - - public Long getParentId() { - return this.parentId; - } - - public Long getStaffId() { - return this.staffId; - } - - public String getStaffName() { - return this.staffName; - } - - public String getParentName() { - return this.parentName; - } - - public String getHierarchy() { - return this.hierarchy; - } - - public Collection clientMembers() { - return this.clientMembers; - } -} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java new file mode 100644 index 000000000..4254d73dd --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupGeneralData.java @@ -0,0 +1,132 @@ +/** + * 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.office.data.OfficeData; +import org.mifosplatform.organisation.staff.data.StaffData; +import org.mifosplatform.portfolio.client.data.ClientData; + +/** + * Immutable data object representing a general group (so may or may not have a + * parent). + */ +public class GroupGeneralData { + + private final Long id; + private final String name; + private final String externalId; + private final Long officeId; + private final String officeName; + private final Long centerId; + private final String centerName; + private final Long staffId; + private final String staffName; + private final String hierarchy; + + // associations + private final Collection clientMembers; + + // template + private final Collection centerOptions; + private final Collection officeOptions; + private final Collection staffOptions; + private final Collection clientOptions; + + public static GroupGeneralData lookup(final Long groupId, final String groupName) { + final Collection clientMembers = null; + + return new GroupGeneralData(groupId, groupName, null, null, null, null, null, null, null, null, clientMembers, null, null, null, + null); + } + + public static GroupGeneralData template(final Long officeId, final Long centerId, final String centerName, final Long staffId, + final String staffName, final Collection centerOptions, final Collection officeOptions, + final Collection staffOptions, final Collection clientOptions) { + + final Collection clientMembers = null; + + return new GroupGeneralData(null, null, null, officeId, null, centerId, centerName, staffId, staffName, null, clientMembers, + centerOptions, officeOptions, staffOptions, clientOptions); + } + + public static GroupGeneralData withTemplate(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping) { + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, + grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, grouping.clientMembers, + templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, + templatedGrouping.clientOptions); + } + + public static GroupGeneralData withTemplateAndAssociations(final GroupGeneralData templatedGrouping, final GroupGeneralData grouping, + final Collection membersOfGroup) { + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, + grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, + templatedGrouping.centerOptions, templatedGrouping.officeOptions, templatedGrouping.staffOptions, + templatedGrouping.clientOptions); + } + + public static GroupGeneralData withAssocations(final GroupGeneralData grouping, final Collection membersOfGroup) { + return new GroupGeneralData(grouping.id, grouping.name, grouping.externalId, grouping.officeId, grouping.officeName, + grouping.centerId, grouping.centerName, grouping.staffId, grouping.staffName, grouping.hierarchy, membersOfGroup, + grouping.centerOptions, grouping.officeOptions, grouping.staffOptions, grouping.clientOptions); + } + + public static GroupGeneralData instance(final Long id, final String name, final String externalId, final Long officeId, + final String officeName, final Long parentId, final String parentName, final Long staffId, final String staffName, + final String hierarchy) { + + final Collection clientMembers = null; + final Collection centerOptions = null; + final Collection officeOptions = null; + final Collection staffOptions = null; + final Collection clientOptions = null; + + return new GroupGeneralData(id, name, externalId, officeId, officeName, parentId, parentName, staffId, staffName, hierarchy, + clientMembers, centerOptions, officeOptions, staffOptions, clientOptions); + } + + private GroupGeneralData(final Long id, final String name, final String externalId, final Long officeId, final String officeName, + final Long parentId, final String parentName, final Long staffId, final String staffName, final String hierarchy, + final Collection clientMembers, final Collection centerOptions, + final Collection officeOptions, final Collection staffOptions, final Collection clientOptions) { + this.id = id; + this.name = name; + this.externalId = externalId; + this.officeId = officeId; + this.officeName = officeName; + this.centerId = parentId; + this.centerName = parentName; + this.staffId = staffId; + this.staffName = staffName; + this.hierarchy = hierarchy; + + // associations + this.clientMembers = clientMembers; + + // template + this.centerOptions = centerOptions; + this.officeOptions = officeOptions; + this.staffOptions = staffOptions; + + if (clientMembers != null && clientOptions != null) { + clientOptions.removeAll(clientMembers); + } + this.clientOptions = clientOptions; + } + + public Long getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Long officeId() { + return this.officeId; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLookup.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLookup.java index eb2793e99..fc79a3493 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLookup.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupLookup.java @@ -8,6 +8,7 @@ package org.mifosplatform.portfolio.group.data; /** * Immutable data object representing groups. */ +@Deprecated public class GroupLookup { private final Long id; diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupTypes.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupTypes.java index 92ae44760..9a9d83dca 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupTypes.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/data/GroupTypes.java @@ -68,5 +68,4 @@ public enum GroupTypes { public String getValue() { return this.value; } - -} +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformService.java new file mode 100644 index 000000000..2ca782e1a --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformService.java @@ -0,0 +1,24 @@ +/** + * 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.service; + +import java.util.Collection; + +import org.mifosplatform.portfolio.group.data.CenterData; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; + +public interface CenterReadPlatformService { + + CenterData retrieveTemplate(Long officeId); + + CenterData retrieveOne(Long centerId); + + Collection retrieveAllForDropdown(Long officeId); + + Collection retrieveAll(SearchParameters searchCriteria); + + GroupGeneralData retrieveCenterGroupTemplate(Long centerId); +} diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformServiceImpl.java new file mode 100644 index 000000000..243777fbf --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/CenterReadPlatformServiceImpl.java @@ -0,0 +1,234 @@ +/** + * 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.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collection; + +import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; +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.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.ClientData; +import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; +import org.mifosplatform.portfolio.group.data.CenterData; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; +import org.mifosplatform.portfolio.group.data.GroupTypes; +import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; +import org.mifosplatform.useradministration.domain.AppUser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Service +public class CenterReadPlatformServiceImpl implements CenterReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + private final ClientReadPlatformService clientReadPlatformService; + private final OfficeReadPlatformService officeReadPlatformService; + private final StaffReadPlatformService staffReadPlatformService; + private final CenterDataMapper centerMapper = new CenterDataMapper(); + + @Autowired + public CenterReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, + final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService, + final StaffReadPlatformService staffReadPlatformService) { + this.context = context; + this.clientReadPlatformService = clientReadPlatformService; + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.officeReadPlatformService = officeReadPlatformService; + this.staffReadPlatformService = staffReadPlatformService; + } + + // 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where + // clause is ambiguous + // caused by the same name of columns in m_office and m_group tables + private String getCenterExtraCriteria(final SearchParameters searchCriteria) { + + String extraCriteria = " and g.level_id = " + GroupTypes.CENTER.getId() + " "; + + String sqlQueryCriteria = searchCriteria.getSqlSearch(); + if (StringUtils.isNotBlank(sqlQueryCriteria)) { + sqlQueryCriteria = sqlQueryCriteria.replaceAll(" name ", " g.name "); + sqlQueryCriteria = sqlQueryCriteria.replaceAll("name ", "g.name "); + extraCriteria = " and (" + sqlQueryCriteria + ")"; + } + + final Long officeId = searchCriteria.getOfficeId(); + if (officeId != null) { + extraCriteria += " and g.office_id = " + officeId; + } + + final String externalId = searchCriteria.getExternalId(); + if (externalId != null) { + extraCriteria += " and g.external_id = " + ApiParameterHelper.sqlEncodeString(externalId); + } + + final String name = searchCriteria.getName(); + if (name != null) { + extraCriteria += " and g.name like " + ApiParameterHelper.sqlEncodeString(name + "%"); + } + + final String hierarchy = searchCriteria.getHierarchy(); + if (hierarchy != null) { + extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%"); + } + + if (StringUtils.isNotBlank(extraCriteria)) { + extraCriteria = extraCriteria.substring(4); + } + + return extraCriteria; + } + + private static final class CenterDataMapper implements RowMapper { + + private final String schemaSql; + + public CenterDataMapper() { + final StringBuilder sqlBuilder = new StringBuilder(400); + + sqlBuilder.append("g.id as id, g.external_id as externalId, g.name as name, "); + sqlBuilder.append("g.office_id as officeId, o.name as officeName, "); + sqlBuilder.append("g.staff_id as staffId, s.display_name as staffName, "); + sqlBuilder.append("g.hierarchy as hierarchy "); + sqlBuilder.append("from m_group g "); + sqlBuilder.append("join m_office o on o.id = g.office_id "); + sqlBuilder.append("left join m_staff s on s.id = g.staff_id "); + + this.schemaSql = sqlBuilder.toString(); + } + + public String schema() { + return this.schemaSql; + } + + @Override + public CenterData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + + final Long id = rs.getLong("id"); + final String name = rs.getString("name"); + final String externalId = rs.getString("externalId"); + final Long officeId = rs.getLong("officeId"); + final String officeName = rs.getString("officeName"); + final Long staffId = JdbcSupport.getLong(rs, "staffId"); + final String staffName = rs.getString("staffName"); + final String hierarchy = rs.getString("hierarchy"); + + return CenterData.instance(id, name, externalId, officeId, officeName, staffId, staffName, hierarchy); + } + } + + @Override + public Collection retrieveAll(final SearchParameters searchCriteria) { + + this.context.authenticatedUser(); + + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + String sql = "select " + centerMapper.schema() + " where o.hierarchy like ?"; + + final String extraCriteria = getCenterExtraCriteria(searchCriteria); + + if (StringUtils.isNotBlank(extraCriteria)) { + sql += " and (" + extraCriteria + ")"; + } + + sql += "order by g.hierarchy"; + + return this.jdbcTemplate.query(sql, centerMapper, new Object[] { hierarchySearchString }); + } + + @Override + public Collection retrieveAllForDropdown(final Long officeId) { + + this.context.authenticatedUser(); + + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + final String sql = "select " + centerMapper.schema() + + " where g.office_id = ? and g.parent_id is null and g.level_Id = ? and o.hierarchy like ? order by g.hierarchy"; + + return this.jdbcTemplate.query(sql, centerMapper, new Object[] { officeId, GroupTypes.CENTER.getId(), hierarchySearchString }); + } + + @Override + public CenterData retrieveTemplate(final Long officeId) { + + final Collection officeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); + + Collection staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(officeId); + if (CollectionUtils.isEmpty(staffOptions)) { + staffOptions = null; + } + + return CenterData.template(officeId, officeOptions, staffOptions); + } + + @Override + public CenterData retrieveOne(final Long centerId) { + + try { + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + String sql = "select " + this.centerMapper.schema() + " where g.id = ? and o.hierarchy like ?"; + return this.jdbcTemplate.queryForObject(sql, this.centerMapper, new Object[] { centerId, hierarchySearchString }); + } catch (EmptyResultDataAccessException e) { + throw new GroupNotFoundException(centerId); + } + } + + @Override + public GroupGeneralData retrieveCenterGroupTemplate(final Long centerId) { + + final CenterData center = this.retrieveOne(centerId); + + final Long centerOfficeId = center.officeId(); + final OfficeData centerOffice = this.officeReadPlatformService.retrieveOffice(centerOfficeId); + + StaffData staff = null; + final Long staffId = center.staffId(); + String staffName = null; + if (staffId != null) { + staff = this.staffReadPlatformService.retrieveStaff(staffId); + staffName = staff.getDisplayName(); + } + + final Collection centerOptions = Arrays.asList(center); + final Collection officeOptions = Arrays.asList(centerOffice); + + Collection staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(centerOfficeId); + if (CollectionUtils.isEmpty(staffOptions)) { + staffOptions = null; + } + + Collection clientOptions = this.clientReadPlatformService + .retrieveAllIndividualClientsForLookupByOfficeId(centerOfficeId); + if (CollectionUtils.isEmpty(clientOptions)) { + clientOptions = null; + } + + return GroupGeneralData.template(centerOfficeId, center.getId(), center.getName(), staffId, staffName, centerOptions, + officeOptions, staffOptions, clientOptions); + } +} \ No newline at end of file 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 9f0774784..f2002a4c0 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 @@ -9,47 +9,35 @@ 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; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData; -import org.mifosplatform.portfolio.group.data.GroupData; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.data.GroupLevelData; -import org.mifosplatform.portfolio.group.data.GroupLookup; public interface GroupReadPlatformService { - Collection retrieveAllGroups(String extraCriteria); + GroupGeneralData retrieveTemplate(Long officeId, boolean isCenterGroup); - GroupData retrieveGroup(Long groupId, Long levelId); + Collection retrieveAll(SearchParameters searchCriteria); - GroupData retrieveNewGroupDetails(Long officeId, Long levelId); - - Collection retrieveClientMembers(Long groupId); + GroupGeneralData retrieveOne(Long groupId); + // GroupAccountSummaryCollectionData retrieveGroupAccountDetails(Long groupId); Collection retrieveGroupLoanAccountsByLoanOfficerId(Long groupId, Long loanOfficerId); - Collection retrieveAllGroupsbyOfficeIdAndLevelId(Long officeId, Long levelId); - GroupLevelData retrieveGroupLevelDetails(Long levelId); Collection retrieveStaffsbyOfficeId(Long officeId); - GroupData retrieveGroupDetails(Long groupId, Long levelId, boolean template); - - Collection retrieveChildGroupsbyGroupId(Long groupId); - Long retrieveTotalNoOfChildGroups(Long groupId); Long retrieveTotalClients(String hierarchy); Collection retrieveGroupLoanPortfolio(String hierarchy); - GroupData retrieveNewChildGroupDetails(Long officeId, Long levelId, Long parentGroupId); - StaffData retrieveStaffsbyId(Long staffId); - - Long getLevelIdByGroupId(final Long groupId); -} + Long getLevelIdByGroupId(final Long groupId); +} \ No newline at end of file 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 6aeff92f2..2b60e20ea 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 @@ -13,6 +13,7 @@ import java.util.Collection; import java.util.List; import org.apache.commons.lang.StringUtils; +import org.mifosplatform.infrastructure.core.api.ApiParameterHelper; import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; @@ -21,17 +22,16 @@ 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.exception.StaffNotFoundException; -import org.mifosplatform.portfolio.client.data.ClientLookup; +import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; +import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.LoanStatusMapper; +import org.mifosplatform.portfolio.group.data.CenterData; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData; import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData; -import org.mifosplatform.portfolio.group.data.GroupData; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.data.GroupLevelData; -import org.mifosplatform.portfolio.group.data.GroupLookup; -import org.mifosplatform.portfolio.group.data.GroupSummary; -import org.mifosplatform.portfolio.group.domain.Group; -import org.mifosplatform.portfolio.group.domain.GroupRepository; +import org.mifosplatform.portfolio.group.data.GroupTypes; import org.mifosplatform.portfolio.group.exception.GroupLevelNotFoundException; import org.mifosplatform.portfolio.group.exception.GroupNotFoundException; import org.mifosplatform.useradministration.domain.AppUser; @@ -40,6 +40,7 @@ import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; @Service public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { @@ -48,90 +49,136 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { private final PlatformSecurityContext context; private final ClientReadPlatformService clientReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService; - private final GroupRepository groupRepository; + private final StaffReadPlatformService staffReadPlatformService; + private final AllGroupTypesDataMapper allGroupTypesDataMapper = new AllGroupTypesDataMapper(); + private final CenterReadPlatformService centerReadPlatformService; @Autowired public GroupReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, - final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService, - final GroupRepository groupRepository) { + final CenterReadPlatformService centerReadPlatformService, final ClientReadPlatformService clientReadPlatformService, + final OfficeReadPlatformService officeReadPlatformService, final StaffReadPlatformService staffReadPlatformService) { this.context = context; this.jdbcTemplate = new JdbcTemplate(dataSource); + this.centerReadPlatformService = centerReadPlatformService; this.clientReadPlatformService = clientReadPlatformService; this.officeReadPlatformService = officeReadPlatformService; - this.groupRepository = groupRepository; + this.staffReadPlatformService = staffReadPlatformService; } @Override - public Collection retrieveAllGroups(final String extraCriteria) { + public GroupGeneralData retrieveTemplate(final Long officeId, final boolean isCenterGroup) { - this.context.authenticatedUser(); - - AppUser currentUser = context.authenticatedUser(); - String hierarchy = currentUser.getOffice().getHierarchy(); - String hierarchySearchString = hierarchy + "%"; + final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId); - final GroupDataMapper rm = new GroupDataMapper(); + Collection centerOptions = null; + if (isCenterGroup) { + centerOptions = this.centerReadPlatformService.retrieveAllForDropdown(defaultOfficeId); + } - String sql = "select " + rm.groupSchema() + " where o.hierarchy like ? and g.is_deleted=0 "; - + final Collection officeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); + Collection staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(defaultOfficeId); + if (CollectionUtils.isEmpty(staffOptions)) { + staffOptions = null; + } + + Collection clientOptions = this.clientReadPlatformService + .retrieveAllIndividualClientsForLookupByOfficeId(defaultOfficeId); + if (CollectionUtils.isEmpty(clientOptions)) { + clientOptions = null; + } + + final Long centerId = null; + final String centerName = null; + final Long staffId = null; + final String staffName = null; + + return GroupGeneralData.template(defaultOfficeId, centerId, centerName, staffId, staffName, centerOptions, officeOptions, + staffOptions, clientOptions); + } + + private Long defaultToUsersOfficeIfNull(final Long officeId) { + Long defaultOfficeId = officeId; + if (defaultOfficeId == null) { + defaultOfficeId = this.context.authenticatedUser().getOffice().getId(); + } + return defaultOfficeId; + } + + @Override + public Collection retrieveAll(final SearchParameters searchCriteria) { + + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; + + String sql = "select " + this.allGroupTypesDataMapper.schema() + " where o.hierarchy like ?"; + + final String extraCriteria = getGroupExtraCriteria(searchCriteria); if (StringUtils.isNotBlank(extraCriteria)) { sql += " and (" + extraCriteria + ")"; } - sql += "order by g.hierarchy"; - - return this.jdbcTemplate.query(sql, rm, new Object[] {hierarchySearchString}); + sql += " order by g.hierarchy"; + + return this.jdbcTemplate.query(sql, this.allGroupTypesDataMapper, new Object[] { hierarchySearchString }); + } + + // 'g.' preffix because of ERROR 1052 (23000): Column 'column_name' in where + // clause is ambiguous + // caused by the same name of columns in m_office and m_group tables + private String getGroupExtraCriteria(final SearchParameters searchCriteria) { + + String extraCriteria = " and g.level_Id = " + GroupTypes.GROUP.getId(); + + String sqlSearch = searchCriteria.getSqlSearch(); + if (sqlSearch != null) { + sqlSearch = sqlSearch.replaceAll(" name ", " g.name "); + sqlSearch = sqlSearch.replaceAll("name ", "g.name "); + extraCriteria = " and (" + sqlSearch + ")"; + } + + final Long officeId = searchCriteria.getOfficeId(); + if (officeId != null) { + extraCriteria += " and g.office_id = " + officeId; + } + + final String externalId = searchCriteria.getExternalId(); + if (externalId != null) { + extraCriteria += " and g.external_id = " + ApiParameterHelper.sqlEncodeString(externalId); + } + + final String name = searchCriteria.getName(); + if (name != null) { + extraCriteria += " and g.name like " + ApiParameterHelper.sqlEncodeString("%" + name + "%"); + } + + final String hierarchy = searchCriteria.getHierarchy(); + if (hierarchy != null) { + extraCriteria += " and o.hierarchy like " + ApiParameterHelper.sqlEncodeString(hierarchy + "%"); + } + + if (StringUtils.isNotBlank(extraCriteria)) { + extraCriteria = extraCriteria.substring(4); + } + + return extraCriteria; } @Override - public GroupData retrieveGroup(final Long groupId , final Long levelId) { + public GroupGeneralData retrieveOne(final Long groupId) { try { - this.context.authenticatedUser(); + final AppUser currentUser = context.authenticatedUser(); + final String hierarchy = currentUser.getOffice().getHierarchy(); + final String hierarchySearchString = hierarchy + "%"; - final GroupDataMapper rm = new GroupDataMapper(); - - final String sql = "select " + rm.groupSchema() + " where g.id = ? and g.is_deleted=0 and g.level_id = " + levelId; - - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { groupId }); - } catch (final EmptyResultDataAccessException e) { + String sql = "select " + this.allGroupTypesDataMapper.schema() + " where g.id = ? and o.hierarchy like ?"; + return this.jdbcTemplate.queryForObject(sql, this.allGroupTypesDataMapper, new Object[] { groupId, hierarchySearchString }); + } catch (EmptyResultDataAccessException e) { throw new GroupNotFoundException(groupId); } } - @Override - public Collection retrieveAllGroupsbyOfficeIdAndLevelId(final Long officeId, final Long levelId) { - - this.context.authenticatedUser(); - final GroupLookupMapper rm = new GroupLookupMapper(); - final String sql = "select " + rm.groupLookupSchema() + " from m_group g where g.office_id = ? and level_id = ? and g.is_deleted=0"; - return this.jdbcTemplate.query(sql, rm, new Object[] { officeId, levelId }); - } - - private GroupLookup retrieveGroupbyId(final Long parentGroupId) { - try { - this.context.authenticatedUser(); - final GroupLookupMapper rm = new GroupLookupMapper(); - final String sql = "select " + rm.groupLookupSchema() + " from m_group g where g.id = ? and g.is_deleted=0"; - return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { parentGroupId }); - - } catch (final EmptyResultDataAccessException e) { - throw new GroupNotFoundException(parentGroupId); - } - } - - @Override - public Collection retrieveChildGroupsbyGroupId(final Long groupId) { - - this.context.authenticatedUser(); - final GroupLookupMapper rm = new GroupLookupMapper(); - final 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 }); - - } - @Override public GroupLevelData retrieveGroupLevelDetails(final Long levelId) { @@ -146,108 +193,6 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { } } - @Override - public GroupData retrieveNewGroupDetails(final Long officeId, final Long levelId) { - - final GroupLevelData groupLevelData = retrieveGroupLevelDetails(levelId); - - if (groupLevelData == null) { throw new GroupLevelNotFoundException(levelId); } - - List allowedClients = null; - - if (groupLevelData.isCanHaveClients()) { - allowedClients = new ArrayList( - this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId)); - } - - final List allowedOffices = new ArrayList(this.officeReadPlatformService.retrieveAllOfficesForDropdown()); - - List allowedParentGroups = null; - - if (groupLevelData.getParentLevelId() != null) { - allowedParentGroups = new ArrayList(retrieveAllGroupsbyOfficeIdAndLevelId(officeId, - groupLevelData.getParentLevelId())); - } - - final List allowedStaffs = new ArrayList(retrieveStaffsbyOfficeId(officeId)); - - return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs); - } - - @Override - public GroupData retrieveNewChildGroupDetails(Long officeId, final Long levelId, final Long parentGroupId) { - - final GroupLevelData groupLevelData = retrieveGroupLevelDetails(levelId); - if (groupLevelData == null) { throw new GroupLevelNotFoundException(levelId); } - - final Group group = this.groupRepository.findOne(parentGroupId); - if (group == null || group.isDeleted()) { throw new GroupNotFoundException(parentGroupId); } - - if (officeId == null) { - officeId = group.getOfficeId(); - } - - List allowedClients = null; - - if (groupLevelData.isCanHaveClients()) { - allowedClients = new ArrayList( - this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId)); - } - - final List allowedOffices = new ArrayList(); - allowedOffices.add(this.officeReadPlatformService.retrieveOffice(officeId)); - - final List allowedParentGroups = new ArrayList(); - allowedParentGroups.add(retrieveGroupbyId(parentGroupId)); - - final List allowedStaffs = new ArrayList(); - allowedStaffs.addAll(retrieveStaffsbyOfficeId(officeId)); - - return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs); - } - - @Override - public GroupData retrieveGroupDetails(final Long groupId, final Long levelId , final boolean template) { - - GroupData group = retrieveGroup(groupId, levelId); - final Collection clientMembers = retrieveClientMembers(groupId); - Collection availableClients = null; - Collection allowedOffices = null; - Collection allowedParentGroups = null; - final GroupLevelData groupLevelData = retrieveGroupLevelDetails(getLevelIdByGroupId(groupId)); - ; - Collection allowedStaffs = null; - final Collection childGroups = retrieveChildGroupsbyGroupId(groupId); - - final Long totalActiveClients = retrieveTotalClients(group.getHierarchy()); - final Long totalChildGroups = retrieveTotalNoOfChildGroups(groupId); - final Collection totalLoanPortfolio = retrieveGroupLoanPortfolio(group.getHierarchy()); - - final GroupSummary groupSummaryData = new GroupSummary(totalActiveClients, totalChildGroups, totalLoanPortfolio, null); - - group = new GroupData(group, clientMembers, availableClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs, - childGroups, groupSummaryData); - - if (template) { - - if (groupLevelData.isCanHaveClients()) { - availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(group.getOfficeId()); - availableClients.removeAll(group.clientMembers()); - } - allowedOffices = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); - if (groupLevelData.getParentLevelId() != null) { - allowedParentGroups = retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), groupLevelData.getParentLevelId()); - } - - allowedStaffs = retrieveStaffsbyOfficeId(group.getOfficeId()); - - group = new GroupData(group, group.clientMembers(), availableClients, allowedOffices, allowedParentGroups, groupLevelData, - allowedStaffs, childGroups, groupSummaryData); - } - - return group; - } - @Override public Collection retrieveStaffsbyOfficeId(final Long officeId) { @@ -273,14 +218,14 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { } @Override - public Long getLevelIdByGroupId(final Long groupId){ + public Long getLevelIdByGroupId(final Long groupId) { this.context.authenticatedUser(); final String sqlTotalClients = "SELECT g.level_Id as levelId FROM m_group g WHERE g.id = ?"; return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupId }); - + } - + @Override public Long retrieveTotalClients(final String hierarchy) { @@ -333,25 +278,39 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { return new MoneyData(currencyCode, amount, decimalPlaces); } - } - private static final class GroupDataMapper implements RowMapper { + // GroupTopOfHierarchyData + private static final class AllGroupTypesDataMapper implements RowMapper { - public String groupSchema() { - return "g.office_id as officeId, g.parent_id as parentId , o.name as officeName," - + " g.id as id, g.external_id as externalId, g.name as name , s.display_name as staffName , pg.name as" - + " parentName , g.staff_id as staffId , g.hierarchy as hierarchy from m_group g join m_office o on o.id = g.office_id left join" - + " m_staff s on s.id = g.staff_id left join m_group pg on pg.id = g.parent_id"; + private final String schemaSql; + + public AllGroupTypesDataMapper() { + final StringBuilder sqlBuilder = new StringBuilder(400); + sqlBuilder.append("g.id as id, g.external_id as externalId, g.name as name, "); + sqlBuilder.append("g.office_id as officeId, o.name as officeName, "); + sqlBuilder.append("g.parent_id as parentId, pg.name as parentName, "); + sqlBuilder.append("g.staff_id as staffId, s.display_name as staffName, "); + sqlBuilder.append("g.hierarchy as hierarchy "); + sqlBuilder.append("from m_group g "); + sqlBuilder.append("join m_office o on o.id = g.office_id "); + sqlBuilder.append("left join m_staff s on s.id = g.staff_id "); + sqlBuilder.append("left join m_group pg on pg.id = g.parent_id "); + + this.schemaSql = sqlBuilder.toString(); + } + + public String schema() { + return this.schemaSql; } @Override - public GroupData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { + public GroupGeneralData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { final Long id = rs.getLong("id"); final String name = rs.getString("name"); final String externalId = rs.getString("externalId"); - final Long officeId = rs.getLong("officeId"); + final Long officeId = JdbcSupport.getLong(rs, "officeId"); final String officeName = rs.getString("officeName"); final Long parentId = JdbcSupport.getLong(rs, "parentId"); final String parentName = rs.getString("parentName"); @@ -359,27 +318,9 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { final String staffName = rs.getString("staffName"); final String hierarchy = rs.getString("hierarchy"); - return new GroupData(id, officeId, officeName, name, externalId, parentId, parentName, staffId, staffName, + return GroupGeneralData.instance(id, name, externalId, officeId, officeName, parentId, parentName, staffId, staffName, hierarchy); } - - } - - private static final class GroupLookupMapper implements RowMapper { - - public String groupLookupSchema() { - return "g.id as id, g.name as name "; - } - - @Override - public GroupLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - - final Long id = rs.getLong("id"); - final String name = rs.getString("name"); - - return new GroupLookup(id, name); - } - } private static final class GroupLevelDataMapper implements RowMapper { @@ -430,35 +371,6 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { return StaffData.instance(id, firstname, lastname, displayName, officeId, officeName, isLoanOfficer); } - - } - - @Override - public Collection retrieveClientMembers(final Long groupId) { - - this.context.authenticatedUser(); - - final ClientMemberSummaryDataMapper rm = new ClientMemberSummaryDataMapper(); - - final String sql = "select " + rm.clientMemberSummarySchema() + " where cm.is_deleted = 0 and pgc.group_id = ?"; - - return this.jdbcTemplate.query(sql, rm, new Object[] { groupId }); - } - - private static final class ClientMemberSummaryDataMapper implements RowMapper { - - public String clientMemberSummarySchema() { - return "cm.id, cm.display_name as displayName from m_client cm INNER JOIN m_group_client pgc ON pgc.client_id = cm.id"; - } - - @Override - public ClientLookup mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { - final Long id = rs.getLong("id"); - final String displayName = rs.getString("displayName"); - - return ClientLookup.create(id, displayName); - } - } @Override @@ -467,7 +379,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { this.context.authenticatedUser(); // Check if group exists - //retrieveGroup(groupId); + // retrieveGroup(groupId); final List pendingApprovalLoans = new ArrayList(); final List awaitingDisbursalLoans = new ArrayList(); @@ -534,7 +446,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { this.context.authenticatedUser(); // Check if group exists - //retrieveGroup(groupId); + // retrieveGroup(groupId); final GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper(); @@ -569,5 +481,4 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { return new GroupAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId); } } - -} +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformService.java index 6f7d49a85..c24ad5dab 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformService.java @@ -10,10 +10,9 @@ import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; public interface GroupWritePlatformService { - CommandProcessingResult createGroup(Long parentId, Long levelId, - JsonCommand command); + CommandProcessingResult createGroup(Long parentId, Long levelId, JsonCommand command); - CommandProcessingResult updateGroup(Long grouptId, JsonCommand command); + CommandProcessingResult updateGroup(Long groupId, JsonCommand command); CommandProcessingResult deleteGroup(Long groupId); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java index 67eddf9ed..8cd246e57 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java @@ -42,6 +42,7 @@ import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; + import com.google.common.collect.Sets; @Service @@ -72,8 +73,8 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla @Transactional @Override - public CommandProcessingResult createGroup(final Long parentId , final Long levelId , final JsonCommand command) { - + public CommandProcessingResult createGroup(final Long parentId, final Long levelId, final JsonCommand command) { + GroupLevel groupLevel = this.groupLevelRepository.findOne(levelId); try { this.context.authenticatedUser(); @@ -137,17 +138,17 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla .build(); } catch (final DataIntegrityViolationException dve) { - handleGroupDataIntegrityIssues(command, dve , groupLevel ); + handleGroupDataIntegrityIssues(command, dve, groupLevel); return new CommandProcessingResult(Long.valueOf(-1)); } } @Transactional @Override - public CommandProcessingResult updateGroup(final Long grouptId, final JsonCommand command) { + public CommandProcessingResult updateGroup(final Long groupId, final JsonCommand command) { GroupLevel groupLevel = null; - + try { this.context.authenticatedUser(); @@ -155,8 +156,8 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla this.fromApiJsonDeserializer.validateForUpdate(command.json()); - final Group groupForUpdate = this.groupRepository.findOne(grouptId); - if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(grouptId); } + final Group groupForUpdate = this.groupRepository.findOne(groupId); + if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(groupId); } final Long officeId = groupForUpdate.getOfficeId(); @@ -184,9 +185,9 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla if (command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) { final Long newValue = command.longValueOfParameterNamed(staffIdParamName); actualChanges.put(staffIdParamName, newValue); - + Staff newStaff = null; - if(newValue != null){ + if (newValue != null) { newStaff = this.staffRepository.findByOffice(newValue, officeId); if (newStaff == null) { throw new StaffNotFoundException(newValue); } } @@ -235,12 +236,13 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla throw new InvalidGroupLevelException("add", "invalid.level", errorMessage); } } - + groupForUpdate.setParent(newParentGroup); - - // Parent has changed, re-generate 'Hierarchy' as parent is changed + + // Parent has changed, re-generate 'Hierarchy' as parent is + // changed groupForUpdate.generateHierarchy(); - + } } @@ -248,7 +250,7 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla final String clientMembersParamName = "clientMembers"; if (!clientMembers.equals(groupForUpdate.getClientMembers())) { - Set diffClients = Sets.symmetricDifference(clientMembers, groupForUpdate.getClientMembers()); + Set diffClients = Sets.symmetricDifference(clientMembers, groupForUpdate.getClientMembers()); final String[] diffClientsIds = getClientIds(diffClients); actualChanges.put(clientMembersParamName, diffClientsIds); groupForUpdate.setClientMembers(clientMembers); @@ -265,7 +267,7 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla .build(); } catch (final DataIntegrityViolationException dve) { - handleGroupDataIntegrityIssues(command, dve , groupLevel); + handleGroupDataIntegrityIssues(command, dve, groupLevel); return new CommandProcessingResult(Long.valueOf(-1)); } } @@ -305,18 +307,28 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla } + /** + * Switched delete to hard delete of group. Will use 'status' when is added + * to determine if group can be deleted or not along with contraints on + * database i.e. cant delete group with any loans/savings accounts. + */ @Transactional @Override public CommandProcessingResult deleteGroup(final Long groupId) { this.context.authenticatedUser(); - // TODO add logic to check any active group loans are preset - final Group groupForDelete = this.groupRepository.findOne(groupId); - if (groupForDelete == null || groupForDelete.isDeleted()) { throw new GroupNotFoundException(groupId); } - groupForDelete.delete(); - this.groupRepository.save(groupForDelete); + if (groupForDelete == null) { throw new GroupNotFoundException(groupId); } + + // groupForDelete.delete(); + // this.groupRepository.save(groupForDelete); + + // List relatedNotes = + // this.noteRepository.findByLoanId(loan.getId()); + // this.noteRepository.deleteInBatch(relatedNotes); + + this.groupRepository.delete(groupId); return new CommandProcessingResultBuilder() // .withOfficeId(groupForDelete.getId()) // @@ -371,8 +383,8 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla String[] clientIds = new String[clients.size()]; Iterator it = clients.iterator(); - for (int i = 0; it.hasNext(); i++) { - clientIds[i] = it.next().getId().toString(); + for (int i = 0; it.hasNext(); i++) { + clientIds[i] = it.next().getId().toString(); } return clientIds; } @@ -381,7 +393,8 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleGroupDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve, GroupLevel groupLevel) { + private void handleGroupDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve, + final GroupLevel groupLevel) { final Throwable realCause = dve.getMostSpecificCause(); String errorMessageForUser = null; @@ -389,18 +402,16 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla if (realCause.getMessage().contains("external_id")) { - errorMessageForUser = groupLevel.getLevelName() + " with externalId {0} already exists"; + final String externalId = command.stringValueOfParameterNamed("externalId"); + errorMessageForUser = groupLevel.getLevelName() + " with externalId `" + externalId + "` already exists."; errorMessageForMachine = "error.msg." + groupLevel.getLevelName().toLowerCase() + ".duplicate.externalId"; - throw new PlatformDataIntegrityException(errorMessageForMachine, errorMessageForUser, "externalId", - command.stringValueOfParameterNamed("externalId")); - + throw new PlatformDataIntegrityException(errorMessageForMachine, errorMessageForUser, "externalId", externalId); } else if (realCause.getMessage().contains("name")) { - errorMessageForUser = groupLevel.getLevelName() + " with name {0} already exists"; + final String name = command.stringValueOfParameterNamed("name"); + errorMessageForUser = groupLevel.getLevelName() + " with name `" + name + "` already exists."; errorMessageForMachine = "error.msg." + groupLevel.getLevelName().toLowerCase() + ".duplicate.name"; - throw new PlatformDataIntegrityException(errorMessageForMachine, errorMessageForUser, "name", - command.stringValueOfParameterNamed("name")); - + throw new PlatformDataIntegrityException(errorMessageForMachine, errorMessageForUser, "name", name); } logger.error(dve.getMessage(), dve); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/SearchParameters.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/SearchParameters.java new file mode 100644 index 000000000..df47e8d34 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/group/service/SearchParameters.java @@ -0,0 +1,43 @@ +package org.mifosplatform.portfolio.group.service; + +public class SearchParameters { + + private final String sqlSearch; + private final Long officeId; + private final String externalId; + private final String name; + private final String hierarchy; + + public static SearchParameters from(final String sqlSearch, final Long officeId, final String externalId, final String name, + final String hierarchy) { + return new SearchParameters(sqlSearch, officeId, externalId, name, hierarchy); + } + + private SearchParameters(final String sqlSearch, final Long officeId, final String externalId, final String name, final String hierarchy) { + this.sqlSearch = sqlSearch; + this.officeId = officeId; + this.externalId = externalId; + this.name = name; + this.hierarchy = hierarchy; + } + + public String getSqlSearch() { + return this.sqlSearch; + } + + public Long getOfficeId() { + return this.officeId; + } + + public String getExternalId() { + return this.externalId; + } + + public String getName() { + return this.name; + } + + public String getHierarchy() { + return this.hierarchy; + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java index 9bc3f13b1..5d5c5a216 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/api/BulkLoansApiResource.java @@ -35,6 +35,7 @@ import org.mifosplatform.organisation.staff.data.BulkTransferLoanOfficerData; import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.organisation.staff.service.StaffReadPlatformService; +import org.mifosplatform.portfolio.loanaccount.service.BulkLoansReadPlatformService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -52,19 +53,21 @@ public class BulkLoansApiResource { private final PlatformSecurityContext context; private final StaffReadPlatformService staffReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService; + private final BulkLoansReadPlatformService bulkLoansReadPlatformService; private final DefaultToApiJsonSerializer toApiJsonSerializer; private final ApiRequestParameterHelper apiRequestParameterHelper; private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService; @Autowired public BulkLoansApiResource(final PlatformSecurityContext context, final StaffReadPlatformService staffReadPlatformService, - final OfficeReadPlatformService officeReadPlatformService, + final OfficeReadPlatformService officeReadPlatformService, final BulkLoansReadPlatformService bulkLoansReadPlatformService, final DefaultToApiJsonSerializer toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) { this.context = context; this.staffReadPlatformService = staffReadPlatformService; this.officeReadPlatformService = officeReadPlatformService; + this.bulkLoansReadPlatformService = bulkLoansReadPlatformService; this.toApiJsonSerializer = toApiJsonSerializer; this.apiRequestParameterHelper = apiRequestParameterHelper; this.commandsSourceWritePlatformService = commandsSourceWritePlatformService; @@ -89,7 +92,7 @@ public class BulkLoansApiResource { } if (loanOfficerId != null) { - staffAccountSummaryCollectionData = this.staffReadPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); + staffAccountSummaryCollectionData = this.bulkLoansReadPlatformService.retrieveLoanOfficerAccountSummary(loanOfficerId); } final BulkTransferLoanOfficerData loanReassignmentData = BulkTransferLoanOfficerData.templateForBulk(officeId, loanOfficerId, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java index 9aec45848..c29341c00 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/data/LoanAccountData.java @@ -19,7 +19,7 @@ import org.mifosplatform.organisation.staff.data.StaffData; import org.mifosplatform.portfolio.charge.data.ChargeData; import org.mifosplatform.portfolio.collateral.data.CollateralData; import org.mifosplatform.portfolio.fund.data.FundData; -import org.mifosplatform.portfolio.group.data.GroupData; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.loanaccount.guarantor.data.GuarantorData; import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanScheduleData; import org.mifosplatform.portfolio.loanproduct.data.LoanProductData; @@ -46,7 +46,7 @@ public class LoanAccountData { private final Long clientId; private final String clientName; private final Long clientOfficeId; - private final GroupData group; + private final GroupGeneralData group; private final Long loanProductId; private final String loanProductName; private final String loanProductDescription; @@ -107,7 +107,7 @@ public class LoanAccountData { private final Collection loanCollateralOptions; @Transient - private BigDecimal feeChargesAtDisbursementCharged; + private final BigDecimal feeChargesAtDisbursementCharged; /** * Used to produce a {@link LoanAccountData} with only collateral options @@ -121,7 +121,7 @@ public class LoanAccountData { final Long clientId = null; final String clientName = null; final Long clientOfficeId = null; - final GroupData group = null; + final GroupGeneralData group = null; final Long loanProductId = null; final String loanProductName = null; final String loanProductDescription = null; @@ -171,16 +171,16 @@ public class LoanAccountData { final Collection loanOfficerOptions = null; final Collection loanPurposeOptions = null; - return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, - loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, - loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, - numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, - interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, - expectedFirstRepaymentOnDate, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, - repaymentSchedule, transactions, charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, - repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, - amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, - chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions); + return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId, + loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, + currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, + interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, + collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, + transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, + interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, + loanCollateralOptions); } /** @@ -193,7 +193,7 @@ public class LoanAccountData { final String accountNo = null; final LoanStatusEnumData status = null; final String externalId = null; - final GroupData group = null; + final GroupGeneralData group = null; final String groupName = null; final Long loanProductId = null; final String loanProductName = null; @@ -245,24 +245,22 @@ public class LoanAccountData { final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; - return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, - loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, - loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, - numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, - interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, - expectedFirstRepaymentOnDate, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, - repaymentSchedule, transactions, charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, - repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, - interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, - loanPurposeOptions, loanCollateralOptions); + return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId, + loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, + currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, + interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, + collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions, + interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, + fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions); } /** * Used to produce a {@link LoanAccountData} with only group information * defaulted. */ - public static LoanAccountData groupDefaults(final GroupData group, - final LocalDate expectedDisbursementDate) { + public static LoanAccountData groupDefaults(final GroupGeneralData group, final LocalDate expectedDisbursementDate) { final Long id = null; final String accountNo = null; @@ -321,16 +319,15 @@ public class LoanAccountData { final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; - return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, - loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, - loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, - numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, - interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, - expectedFirstRepaymentOnDate, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, - repaymentSchedule, transactions, charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, - repaymentFrequencyTypeOptions, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, - interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, - loanPurposeOptions, loanCollateralOptions); + return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId, + loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, + currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, transactionProcessingStrategyId, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, + interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, + collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions, + interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, + fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions); } public static LoanAccountData populateLoanProductDefaults(final LoanAccountData acc, final LoanProductData product) { @@ -363,9 +360,9 @@ public class LoanAccountData { } return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, - acc.group, product.getId(), product.getName(), product.getDescription(), - product.getFundId(), product.getFundName(), acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, - product.getCurrency(), product.getPrincipal(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, + acc.group, product.getId(), product.getName(), product.getDescription(), product.getFundId(), product.getFundName(), + acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, product.getCurrency(), + product.getPrincipal(), product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(), product.getTransactionProcessingStrategyId(), product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(), @@ -381,15 +378,14 @@ public class LoanAccountData { * query. */ public static LoanAccountData basicLoanDetails(final Long id, final String accountNo, final LoanStatusEnumData status, - final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final GroupData group, - final Long loanProductId, final String loanProductName, - final String loanProductDescription, final Long fundId, final String fundName, final Long loanPurposeId, - final String loanPurposeName, final Long loanOfficerId, final String loanOfficerName, final CurrencyData currencyData, - final BigDecimal principal, final BigDecimal inArrearsTolerance, final Integer termFrequency, - final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery, - final EnumOptionData repaymentFrequencyType, final Long transactionStrategyId, final EnumOptionData amortizationType, - final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType, final BigDecimal annualInterestRate, - final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType, + final String externalId, final Long clientId, final String clientName, final Long clientOfficeId, final GroupGeneralData group, + final Long loanProductId, final String loanProductName, final String loanProductDescription, final Long fundId, + final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId, + final String loanOfficerName, final CurrencyData currencyData, final BigDecimal principal, final BigDecimal inArrearsTolerance, + final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, + final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, final Long transactionStrategyId, + final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType, + final BigDecimal annualInterestRate, final EnumOptionData interestType, final EnumOptionData interestCalculationPeriodType, final LocalDate expectedFirstRepaymentOnDate, final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary, final BigDecimal feeChargesDueAtDisbursementCharged) { @@ -414,16 +410,15 @@ public class LoanAccountData { final Collection loanPurposeOptions = null; final Collection loanCollateralOptions = null; - return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, - loanProductId, loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, - loanOfficerId, loanOfficerName, currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, - numberOfRepayments, repaymentEvery, repaymentFrequencyType, transactionStrategyId, amortizationType, interestRatePerPeriod, - interestRateFrequencyType, annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, - interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, - charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, - repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, - interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, - loanCollateralOptions); + return new LoanAccountData(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, group, loanProductId, + loanProductName, loanProductDescription, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, + currencyData, principal, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, + repaymentFrequencyType, transactionStrategyId, amortizationType, interestRatePerPeriod, interestRateFrequencyType, + annualInterestRate, interestType, interestCalculationPeriodType, expectedFirstRepaymentOnDate, interestChargedFromDate, + timeline, loanSummary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, + guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentStrategyOptions, + interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, + fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions); } /* @@ -442,16 +437,16 @@ public class LoanAccountData { final Collection loanOfficerOptions, final Collection loanPurposeOptions, final Collection loanCollateralOptions) { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientName, acc.clientOfficeId, - acc.group, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, - acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, - acc.principal, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, - acc.repaymentEvery, acc.repaymentFrequencyType, acc.transactionProcessingStrategyId, acc.amortizationType, - acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, - acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, acc.interestChargedFromDate, acc.timeline, - acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, - productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, transactionProcessingStrategyOptions, - interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, - fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions); + acc.group, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.fundId, acc.fundName, acc.loanPurposeId, + acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.principal, acc.inArrearsTolerance, + acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType, + acc.transactionProcessingStrategyId, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, + acc.annualInterestRate, acc.interestType, acc.interestCalculationPeriodType, acc.expectedFirstRepaymentOnDate, + acc.interestChargedFromDate, acc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, + transactions, charges, collateral, guarantors, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, + transactionProcessingStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, + interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, + loanCollateralOptions); } private LoanAccountData( @@ -462,7 +457,7 @@ public class LoanAccountData { final Long clientId, final String clientName, final Long clientOfficeId, // - final GroupData group, + final GroupGeneralData group, final Long loanProductId, final String loanProductName, final String loanProductDescription, // diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformService.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformService.java new file mode 100644 index 000000000..2af46b9f5 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformService.java @@ -0,0 +1,9 @@ +package org.mifosplatform.portfolio.loanaccount.service; + +import org.mifosplatform.organisation.staff.data.StaffAccountSummaryCollectionData; + + +public interface BulkLoansReadPlatformService { + + StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId); +} 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 new file mode 100644 index 000000000..cc8cddc07 --- /dev/null +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/BulkLoansReadPlatformServiceImpl.java @@ -0,0 +1,111 @@ +/** + * 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.loanaccount.service; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Collection; +import java.util.List; + +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.staff.data.StaffAccountSummaryCollectionData; +import org.mifosplatform.portfolio.client.data.ClientAccountSummaryData; +import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; +import org.mifosplatform.portfolio.group.data.GroupAccountSummaryData; +import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Service; + +@Service +public class BulkLoansReadPlatformServiceImpl implements BulkLoansReadPlatformService { + + private final JdbcTemplate jdbcTemplate; + private final PlatformSecurityContext context; + private final ClientReadPlatformService clientReadPlatformService; + private final GroupReadPlatformService groupReadPlatformService; + + @Autowired + public BulkLoansReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, + final ClientReadPlatformService clientReadPlatformService, final GroupReadPlatformService groupReadPlatformService) { + this.context = context; + this.jdbcTemplate = new JdbcTemplate(dataSource); + this.clientReadPlatformService = clientReadPlatformService; + this.groupReadPlatformService = groupReadPlatformService; + } + + @Override + public StaffAccountSummaryCollectionData retrieveLoanOfficerAccountSummary(final Long loanOfficerId) { + + context.authenticatedUser(); + + final StaffClientMapper staffClientMapper = new StaffClientMapper(); + final String clientSql = "select distinct " + staffClientMapper.schema(); + + final StaffGroupMapper staffGroupMapper = new StaffGroupMapper(); + final String groupSql = "select distinct " + staffGroupMapper.schema(); + + final List clientSummaryList = this.jdbcTemplate.query(clientSql, + staffClientMapper, new Object[] { loanOfficerId }); + + for (StaffAccountSummaryCollectionData.ClientSummary clientSummary : clientSummaryList) { + + final Collection clientLoanAccounts = this.clientReadPlatformService + .retrieveClientLoanAccountsByLoanOfficerId(clientSummary.getId(), loanOfficerId); + + clientSummary.setLoans(clientLoanAccounts); + } + + final List groupSummaryList = this.jdbcTemplate.query(groupSql, staffGroupMapper, + new Object[] { loanOfficerId }); + + for (StaffAccountSummaryCollectionData.GroupSummary groupSummary : groupSummaryList) { + + final Collection groupLoanAccounts = this.groupReadPlatformService + .retrieveGroupLoanAccountsByLoanOfficerId(groupSummary.getId(), loanOfficerId); + + groupSummary.setLoans(groupLoanAccounts); + } + + return new StaffAccountSummaryCollectionData(clientSummaryList, groupSummaryList); + } + + private static final class StaffClientMapper implements RowMapper { + + public String schema() { + return " c.id as id, c.display_name as displayName from m_client c " + + " join m_loan l on c.id = l.client_id where l.loan_officer_id = ? "; + } + + @Override + public StaffAccountSummaryCollectionData.ClientSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) + throws SQLException { + final Long id = JdbcSupport.getLong(rs, "id"); + final String displayName = rs.getString("displayName"); + + return new StaffAccountSummaryCollectionData.ClientSummary(id, displayName); + } + } + + private static final class StaffGroupMapper implements RowMapper { + + public String schema() { + return " g.id as id, g.name as name from m_group g" + " join m_loan l on g.id = l.group_id where l.loan_officer_id = ? "; + } + + @Override + public StaffAccountSummaryCollectionData.GroupSummary mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) + throws SQLException { + final Long id = JdbcSupport.getLong(rs, "id"); + final String name = rs.getString("name"); + + return new StaffAccountSummaryCollectionData.GroupSummary(id, name); + } + } +} \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index 8107c2531..771a35b8c 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -26,8 +26,7 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; -import org.mifosplatform.portfolio.group.data.GroupData; -import org.mifosplatform.portfolio.group.data.GroupTypes; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; import org.mifosplatform.portfolio.loanaccount.data.DisbursementData; import org.mifosplatform.portfolio.loanaccount.data.LoanAccountData; @@ -167,7 +166,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { context.authenticatedUser(); - final GroupData groupAccount = this.groupReadPlatformService.retrieveGroupDetails(groupId, GroupTypes.GROUP.getId(), false); + final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId); final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant(); LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate); @@ -184,7 +183,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { context.authenticatedUser(); - final GroupData groupAccount = this.groupReadPlatformService.retrieveGroup(groupId, GroupTypes.GROUP.getId()); + final GroupGeneralData groupAccount = this.groupReadPlatformService.retrieveOne(groupId); final LocalDate expectedDisbursementDate = DateUtils.getLocalDateOfTenant(); LoanAccountData loanDetails = LoanAccountData.groupDefaults(groupAccount, expectedDisbursementDate); @@ -525,11 +524,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { totalWaived, totalWrittenOff, totalOutstanding, totalOverdue, overdueSinceDate); } - GroupData groupData = null; - + GroupGeneralData groupData = null; if (groupId != null) { - - groupData = new GroupData(groupId, groupName, groupExternalId, groupOfficeId, groupStaffId, groupParentId, groupHierarchy); + groupData = GroupGeneralData.instance(groupId, groupName, groupExternalId, groupOfficeId, null, groupParentId, null, + groupStaffId, null, groupHierarchy); } return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientName, clientOfficeId, groupData, diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java index 6b2368d73..d13257b27 100644 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountReadPlatformServiceImpl.java @@ -19,8 +19,7 @@ import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext import org.mifosplatform.organisation.monetary.data.CurrencyData; import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; -import org.mifosplatform.portfolio.group.data.GroupData; -import org.mifosplatform.portfolio.group.data.GroupTypes; +import org.mifosplatform.portfolio.group.data.GroupGeneralData; import org.mifosplatform.portfolio.group.service.GroupReadPlatformService; import org.mifosplatform.portfolio.savings.data.SavingsAccountData; import org.mifosplatform.portfolio.savings.data.SavingsAccountStatusEnumData; @@ -211,9 +210,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead client = this.clientReadPlatformService.retrieveIndividualClient(clientId); } - GroupData group = null; + GroupGeneralData group = null; if (groupId != null) { - group = this.groupReadPlatformService.retrieveGroup(groupId , GroupTypes.GROUP.getId()); + group = this.groupReadPlatformService.retrieveOne(groupId); } final Collection productOptions = this.savingsProductReadPlatformService.retrieveAllForLookup(); @@ -385,11 +384,11 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead private static final class SavingAccountTemplateMapper implements RowMapper { private final ClientData client; - private final GroupData group; + private final GroupGeneralData group; private final String schemaSql; - public SavingAccountTemplateMapper(final ClientData client, final GroupData group) { + public SavingAccountTemplateMapper(final ClientData client, final GroupGeneralData group) { this.client = client; this.group = group; @@ -432,8 +431,9 @@ public class SavingsAccountReadPlatformServiceImpl implements SavingsAccountRead final BigDecimal nominalAnnualIterestRate = rs.getBigDecimal("nominalAnnualIterestRate"); - EnumOptionData interestCompoundingPeriodType = SavingsEnumerations.compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType - .fromInt(JdbcSupport.getInteger(rs, "interestCompoundingPeriodType"))); + EnumOptionData interestCompoundingPeriodType = SavingsEnumerations + .compoundingInterestPeriodType(SavingsCompoundingInterestPeriodType.fromInt(JdbcSupport.getInteger(rs, + "interestCompoundingPeriodType"))); final EnumOptionData interestPostingPeriodType = SavingsEnumerations.interestPostingPeriodType(SavingsInterestPostingPeriodType .fromInt(JdbcSupport.getInteger(rs, "interestPostingPeriodType")));