MIFOSX-445: support ability to use staff from branches higher in hierarchy on groups.

This commit is contained in:
Keith Woodlock
2013-06-13 14:29:21 +01:00
parent 256cdd3c47
commit 0393ed5017
7 changed files with 88 additions and 41 deletions
+36 -4
View File
@@ -1372,6 +1372,10 @@
<td>clients/template</td> <td>clients/template</td>
<td><a href="#clients_template">Retrieve Client Template</a></td> <td><a href="#clients_template">Retrieve Client Template</a></td>
</tr> </tr>
<tr class="alt">
<td>groups/template</td>
<td><a href="#groups_template">Retrieve Group Template</a></td>
</tr>
<tr > <tr >
<td>loanproducts/template</td> <td>loanproducts/template</td>
<td><a href="#loanproducts_template">Retrieve Loan Product Template</a></td> <td><a href="#loanproducts_template">Retrieve Loan Product Template</a></td>
@@ -3353,6 +3357,33 @@ GET https://DomainName/mifosng-provider/api/v1/centers
<div class="method-section"> <div class="method-section">
<div class="method-description"> <div class="method-description">
<h4>Retrieve Group Template</h4> <h4>Retrieve Group Template</h4>
<p>This is a convenience resource. It can be useful when
building maintenance user interface screens for client
applications. The template data returned consists of any or all
of:
<ul>
<li class=normalli>Field Defaults</li>
<li class=normalli>Allowed Value Lists</li>
</ul>
</p>
<h5>Arguments</h5>
<dl class="argument-list">
<dt>officeId</dt>
<dd>
Integer <span>optional</span>
</dd>
<dt>centerId</dt>
<dd>
Integer <span>optional</span>
</dd>
<dt>staffInSelectedOfficeOnly</dt>
<dd>
Boolean <span>optional</span>
</dd>
<dd>Defaults to false if not provided. If <strong>staffInSelectedOfficeOnly=true</strong> only staff
who are associated with the selected branch are returned.</dd>
</dl>
<p>Example Requests:</p> <p>Example Requests:</p>
<div class=apiClick>groups/template</div> <div class=apiClick>groups/template</div>
<br/> <br/>
@@ -3360,7 +3391,8 @@ GET https://DomainName/mifosng-provider/api/v1/centers
<br/> <br/>
<div class=apiClick>groups/template?centerId=1</div> <div class=apiClick>groups/template?centerId=1</div>
<br/> <br/>
<div class=apiClick>groups/template?centerId=1&staffInSelectedOfficeOnly=true</div>
<br/>
</div> </div>
<div class="method-example"> <div class="method-example">
<p>Template to create a standard group</p> <p>Template to create a standard group</p>
@@ -4076,12 +4108,12 @@ GET https://DomainName/mifosng-provider/api/v1/groups
<dd>If entered, productId, productName and selectedProduct <dd>If entered, productId, productName and selectedProduct
fields are returned.</dd> fields are returned.</dd>
<dt>loanOfficersInSelectedOfficeOnly</dt> <dt>staffInSelectedOfficeOnly</dt>
<dd> <dd>
Boolean <span>optional</span> Boolean <span>optional</span>
</dd> </dd>
<dd>Defaults to false if not provided. If <strong>loanOfficersInSelectedOfficeOnly=true</strong> only loan officers <dd>Defaults to false if not provided. If <strong>staffInSelectedOfficeOnly=true</strong> only loan officers
who are associated with the select branch are returned.</dd> who are associated with the selected branch are returned.</dd>
</dl> </dl>
<p>Example Requests:</p> <p>Example Requests:</p>
<div class=apiClick>loans/template?templateType=individual&clientId=1</div> <div class=apiClick>loans/template?templateType=individual&clientId=1</div>
@@ -18,10 +18,10 @@ public interface StaffReadPlatformService {
Collection<StaffData> retrieveAllLoanOfficersInOfficeById(final Long officeId); Collection<StaffData> retrieveAllLoanOfficersInOfficeById(final Long officeId);
/** /**
* returns all loan officers in offices that are above the provided * returns all staff in offices that are above the provided
* <code>officeId</code>. * <code>officeId</code>.
*/ */
Collection<StaffData> retrieveAllLoanOfficersInOfficeAndItsParentOfficeHierarchy(Long officeId); Collection<StaffData> retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(Long officeId, boolean loanOfficersOnly);
Collection<StaffData> retrieveAllStaff(String sqlSearch, Long officeId); Collection<StaffData> retrieveAllStaff(String sqlSearch, Long officeId);
} }
@@ -59,24 +59,23 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
private static final class StaffInOfficeHierarchyMapper implements RowMapper<StaffData> { private static final class StaffInOfficeHierarchyMapper implements RowMapper<StaffData> {
final String schema; public String schema(final boolean loanOfficersOnly) {
public StaffInOfficeHierarchyMapper() {
StringBuilder sqlBuilder = new StringBuilder(200); StringBuilder sqlBuilder = new StringBuilder(200);
sqlBuilder.append("s.id as id, s.office_id as officeId, o.name as officeName,"); sqlBuilder.append("s.id as id, s.office_id as officeId, o.name as officeName,");
sqlBuilder.append("s.firstname as firstname, s.lastname as lastname,"); sqlBuilder.append("s.firstname as firstname, s.lastname as lastname,");
sqlBuilder.append("s.display_name as displayName, s.is_loan_officer as isLoanOfficer "); sqlBuilder.append("s.display_name as displayName, s.is_loan_officer as isLoanOfficer ");
sqlBuilder.append("from m_office o "); sqlBuilder.append("from m_office o ");
sqlBuilder.append("join m_office ohierarchy on o.hierarchy like concat(ohierarchy.hierarchy, '%') "); sqlBuilder.append("join m_office ohierarchy on o.hierarchy like concat(ohierarchy.hierarchy, '%') ");
sqlBuilder.append("join m_staff s on s.office_id = ohierarchy.id and s.is_loan_officer is true "); sqlBuilder.append("join m_staff s on s.office_id = ohierarchy.id ");
sqlBuilder.append("where o.id = ? ");
this.schema = sqlBuilder.toString();
}
public String schema() { if (loanOfficersOnly) {
return this.schema; sqlBuilder.append("and s.is_loan_officer is true ");
}
sqlBuilder.append("where o.id = ? ");
return sqlBuilder.toString();
} }
@Override @Override
@@ -195,9 +194,9 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
} }
@Override @Override
public Collection<StaffData> retrieveAllLoanOfficersInOfficeAndItsParentOfficeHierarchy(final Long officeId) { public Collection<StaffData> retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(final Long officeId, final boolean loanOfficersOnly) {
String sql = "select " + this.staffInOfficeHierarchyMapper.schema(); String sql = "select " + this.staffInOfficeHierarchyMapper.schema(loanOfficersOnly);
sql = sql + " order by s.lastname"; sql = sql + " order by s.lastname";
return this.jdbcTemplate.query(sql, this.staffInOfficeHierarchyMapper, new Object[] { officeId }); return this.jdbcTemplate.query(sql, this.staffInOfficeHierarchyMapper, new Object[] { officeId });
@@ -12,6 +12,7 @@ import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
@@ -97,8 +98,8 @@ public class GroupsApiResource {
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId, public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("center") final boolean isCenterGroup, @QueryParam("center") final boolean isCenterGroup, @QueryParam("centerId") final Long centerId,
@QueryParam("centerId") final Long centerId) { @DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly) {
this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME); this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME);
@@ -109,7 +110,8 @@ public class GroupsApiResource {
GroupingTypesApiConstants.CENTER_GROUP_RESPONSE_DATA_PARAMETERS); GroupingTypesApiConstants.CENTER_GROUP_RESPONSE_DATA_PARAMETERS);
} }
final GroupGeneralData groupTemplate = this.groupReadPlatformService.retrieveTemplate(officeId, isCenterGroup); final GroupGeneralData groupTemplate = this.groupReadPlatformService.retrieveTemplate(officeId, isCenterGroup,
staffInSelectedOfficeOnly);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.groupGeneralApiJsonSerializer.serialize(settings, groupTemplate, return this.groupGeneralApiJsonSerializer.serialize(settings, groupTemplate,
GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS); GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS);
@@ -138,13 +140,14 @@ public class GroupsApiResource {
@Path("{groupId}") @Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveOne(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId) { public String retrieveOne(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly) {
this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME); this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME);
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters()); final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId); GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId);
// associations // associations
Collection<ClientData> membersOfGroup = null; Collection<ClientData> membersOfGroup = null;
if (!associationParameters.isEmpty()) { if (!associationParameters.isEmpty()) {
@@ -155,10 +158,11 @@ public class GroupsApiResource {
} }
} }
} }
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters()); final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
if (template) { if (template) {
final GroupGeneralData templateGroup = this.groupReadPlatformService.retrieveTemplate(group.officeId(), false); final GroupGeneralData templateGroup = this.groupReadPlatformService.retrieveTemplate(group.officeId(), false,
staffInSelectedOfficeOnly);
group = GroupGeneralData.withTemplateAndAssociations(templateGroup, group, membersOfGroup); group = GroupGeneralData.withTemplateAndAssociations(templateGroup, group, membersOfGroup);
} else { } else {
group = GroupGeneralData.withAssocations(group, membersOfGroup); group = GroupGeneralData.withAssocations(group, membersOfGroup);
@@ -227,8 +231,8 @@ public class GroupsApiResource {
@Path("{groupId}") @Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String activateOrGenerateCollectionSheet(@PathParam("groupId") final Long groupId, @QueryParam("command") final String commandParam, public String activateOrGenerateCollectionSheet(@PathParam("groupId") final Long groupId,
final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) { @QueryParam("command") final String commandParam, final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson); final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
@@ -237,32 +241,34 @@ public class GroupsApiResource {
final CommandWrapper commandRequest = builder.activateGroup(groupId).build(); final CommandWrapper commandRequest = builder.activateGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "associateClients")) { } else if (is(commandParam, "associateClients")) {
final CommandWrapper commandRequest = builder.associateClientsToGroup(groupId).build(); final CommandWrapper commandRequest = builder.associateClientsToGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "disassociateClients")) { } else if (is(commandParam, "disassociateClients")) {
final CommandWrapper commandRequest = builder.disassociateClientsFromGroup(groupId).build(); final CommandWrapper commandRequest = builder.disassociateClientsFromGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "generateCollectionSheet")) { } else if (is(commandParam, "generateCollectionSheet")) {
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson); final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper); final JsonQuery query = JsonQuery.from(apiRequestBodyAsJson, parsedQuery, this.fromJsonHelper);
final JLGCollectionSheetData collectionSheet = this.collectionSheetReadPlatformService.generateGroupCollectionSheet(groupId, query); final JLGCollectionSheetData collectionSheet = this.collectionSheetReadPlatformService.generateGroupCollectionSheet(groupId,
query);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters()); final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, collectionSheet, GroupingTypesApiConstants.COLLECTIONSHEET_DATA_PARAMETERS); return this.toApiJsonSerializer.serialize(settings, collectionSheet, GroupingTypesApiConstants.COLLECTIONSHEET_DATA_PARAMETERS);
}else if (is(commandParam, "saveCollectionSheet")) { } else if (is(commandParam, "saveCollectionSheet")) {
final CommandWrapper commandRequest = builder.saveGroupCollectionSheet(groupId).build(); final CommandWrapper commandRequest = builder.saveGroupCollectionSheet(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "unassignStaff")) { } else if (is(commandParam, "unassignStaff")) {
final CommandWrapper commandRequest = builder.unassignGroupStaff(groupId).build(); final CommandWrapper commandRequest = builder.unassignGroupStaff(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest); result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} else { } else {
throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "generateCollectionSheet", "saveCollectionSheet", "unassignStaff" }); throw new UnrecognizedQueryParamException("command", commandParam, new Object[] { "activate", "generateCollectionSheet",
"saveCollectionSheet", "unassignStaff" });
} }
} }
private boolean is(final String commandParam, final String commandValue) { private boolean is(final String commandParam, final String commandValue) {
@@ -14,7 +14,7 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
public interface GroupReadPlatformService { public interface GroupReadPlatformService {
GroupGeneralData retrieveTemplate(Long officeId, boolean isCenterGroup); GroupGeneralData retrieveTemplate(Long officeId, boolean isCenterGroup, boolean staffInSelectedOfficeOnly);
Page<GroupGeneralData> retrieveAll(SearchParameters searchParameters); Page<GroupGeneralData> retrieveAll(SearchParameters searchParameters);
@@ -65,7 +65,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
} }
@Override @Override
public GroupGeneralData retrieveTemplate(final Long officeId, final boolean isCenterGroup) { public GroupGeneralData retrieveTemplate(final Long officeId, final boolean isCenterGroup, final boolean staffInSelectedOfficeOnly) {
final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId); final Long defaultOfficeId = defaultToUsersOfficeIfNull(officeId);
@@ -75,7 +75,16 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
} }
final Collection<OfficeData> officeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown(); final Collection<OfficeData> officeOptions = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
Collection<StaffData> staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(defaultOfficeId);
final boolean loanOfficersOnly = false;
Collection<StaffData> staffOptions = null;
if (staffInSelectedOfficeOnly) {
staffOptions = this.staffReadPlatformService.retrieveAllStaffForDropdown(defaultOfficeId);
} else {
staffOptions = this.staffReadPlatformService.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(defaultOfficeId,
loanOfficersOnly);
}
if (CollectionUtils.isEmpty(staffOptions)) { if (CollectionUtils.isEmpty(staffOptions)) {
staffOptions = null; staffOptions = null;
} }
@@ -164,7 +164,7 @@ public class LoansApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId, public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
@QueryParam("productId") final Long productId, @QueryParam("templateType") final String templateType, @QueryParam("productId") final Long productId, @QueryParam("templateType") final String templateType,
@DefaultValue("false") @QueryParam("loanOfficersInSelectedOfficeOnly") final boolean loanOfficersInSelectedOfficeOnly, @DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly,
@Context final UriInfo uriInfo) { @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions); context.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
@@ -227,7 +227,7 @@ public class LoansApiResource {
} }
if (officeId != null) { if (officeId != null) {
if (loanOfficersInSelectedOfficeOnly) { if (staffInSelectedOfficeOnly) {
// only bring back loan officers in selected branch/office // only bring back loan officers in selected branch/office
Collection<StaffData> loanOfficersInBranch = this.staffReadPlatformService Collection<StaffData> loanOfficersInBranch = this.staffReadPlatformService
.retrieveAllLoanOfficersInOfficeById(officeId); .retrieveAllLoanOfficersInOfficeById(officeId);
@@ -239,8 +239,9 @@ public class LoansApiResource {
// by default bring back all loan officers in selected // by default bring back all loan officers in selected
// branch/office as well as loan officers in officer above // branch/office as well as loan officers in officer above
// this office // this office
final boolean restrictToLoanOfficersOnly = true;
Collection<StaffData> loanOfficersInHierarchy = this.staffReadPlatformService Collection<StaffData> loanOfficersInHierarchy = this.staffReadPlatformService
.retrieveAllLoanOfficersInOfficeAndItsParentOfficeHierarchy(officeId); .retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(officeId, restrictToLoanOfficersOnly);
if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) { if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) {
allowedLoanOfficers = new ArrayList<StaffData>(loanOfficersInHierarchy); allowedLoanOfficers = new ArrayList<StaffData>(loanOfficersInHierarchy);