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><a href="#clients_template">Retrieve Client Template</a></td>
</tr>
<tr class="alt">
<td>groups/template</td>
<td><a href="#groups_template">Retrieve Group Template</a></td>
</tr>
<tr >
<td>loanproducts/template</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-description">
<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>
<div class=apiClick>groups/template</div>
<br/>
@@ -3360,7 +3391,8 @@ GET https://DomainName/mifosng-provider/api/v1/centers
<br/>
<div class=apiClick>groups/template?centerId=1</div>
<br/>
<div class=apiClick>groups/template?centerId=1&staffInSelectedOfficeOnly=true</div>
<br/>
</div>
<div class="method-example">
<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
fields are returned.</dd>
<dt>loanOfficersInSelectedOfficeOnly</dt>
<dt>staffInSelectedOfficeOnly</dt>
<dd>
Boolean <span>optional</span>
</dd>
<dd>Defaults to false if not provided. If <strong>loanOfficersInSelectedOfficeOnly=true</strong> only loan officers
who are associated with the select branch are returned.</dd>
<dd>Defaults to false if not provided. If <strong>staffInSelectedOfficeOnly=true</strong> only loan officers
who are associated with the selected branch are returned.</dd>
</dl>
<p>Example Requests:</p>
<div class=apiClick>loans/template?templateType=individual&clientId=1</div>
@@ -18,10 +18,10 @@ public interface StaffReadPlatformService {
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>.
*/
Collection<StaffData> retrieveAllLoanOfficersInOfficeAndItsParentOfficeHierarchy(Long officeId);
Collection<StaffData> retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(Long officeId, boolean loanOfficersOnly);
Collection<StaffData> retrieveAllStaff(String sqlSearch, Long officeId);
}
@@ -59,24 +59,23 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
private static final class StaffInOfficeHierarchyMapper implements RowMapper<StaffData> {
final String schema;
public String schema(final boolean loanOfficersOnly) {
public StaffInOfficeHierarchyMapper() {
StringBuilder sqlBuilder = new StringBuilder(200);
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.display_name as displayName, s.is_loan_officer as isLoanOfficer ");
sqlBuilder.append("from m_office o ");
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("where o.id = ? ");
this.schema = sqlBuilder.toString();
}
sqlBuilder.append("join m_staff s on s.office_id = ohierarchy.id ");
public String schema() {
return this.schema;
if (loanOfficersOnly) {
sqlBuilder.append("and s.is_loan_officer is true ");
}
sqlBuilder.append("where o.id = ? ");
return sqlBuilder.toString();
}
@Override
@@ -195,9 +194,9 @@ public class StaffReadPlatformServiceImpl implements StaffReadPlatformService {
}
@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";
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.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@@ -97,8 +98,8 @@ public class GroupsApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveTemplate(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("center") final boolean isCenterGroup,
@QueryParam("centerId") final Long centerId) {
@QueryParam("center") final boolean isCenterGroup, @QueryParam("centerId") final Long centerId,
@DefaultValue("false") @QueryParam("staffInSelectedOfficeOnly") final boolean staffInSelectedOfficeOnly) {
this.context.authenticatedUser().validateHasReadPermission(GroupingTypesApiConstants.GROUP_RESOURCE_NAME);
@@ -109,7 +110,8 @@ public class GroupsApiResource {
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());
return this.groupGeneralApiJsonSerializer.serialize(settings, groupTemplate,
GroupingTypesApiConstants.GROUP_RESPONSE_DATA_PARAMETERS);
@@ -138,13 +140,14 @@ public class GroupsApiResource {
@Path("{groupId}")
@Consumes({ 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);
final Set<String> associationParameters = ApiParameterHelper.extractAssociationsForResponseIfProvided(uriInfo.getQueryParameters());
GroupGeneralData group = this.groupReadPlatformService.retrieveOne(groupId);
// associations
Collection<ClientData> membersOfGroup = null;
if (!associationParameters.isEmpty()) {
@@ -155,10 +158,11 @@ public class GroupsApiResource {
}
}
}
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
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);
} else {
group = GroupGeneralData.withAssocations(group, membersOfGroup);
@@ -227,8 +231,8 @@ public class GroupsApiResource {
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String activateOrGenerateCollectionSheet(@PathParam("groupId") final Long groupId, @QueryParam("command") final String commandParam,
final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
public String activateOrGenerateCollectionSheet(@PathParam("groupId") final Long groupId,
@QueryParam("command") final String commandParam, final String apiRequestBodyAsJson, @Context final UriInfo uriInfo) {
final CommandWrapperBuilder builder = new CommandWrapperBuilder().withJson(apiRequestBodyAsJson);
@@ -237,32 +241,34 @@ public class GroupsApiResource {
final CommandWrapper commandRequest = builder.activateGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "associateClients")) {
} else if (is(commandParam, "associateClients")) {
final CommandWrapper commandRequest = builder.associateClientsToGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "disassociateClients")) {
} else if (is(commandParam, "disassociateClients")) {
final CommandWrapper commandRequest = builder.disassociateClientsFromGroup(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "generateCollectionSheet")) {
} else if (is(commandParam, "generateCollectionSheet")) {
final JsonElement parsedQuery = this.fromJsonHelper.parse(apiRequestBodyAsJson);
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());
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();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}else if (is(commandParam, "unassignStaff")) {
} else if (is(commandParam, "unassignStaff")) {
final CommandWrapper commandRequest = builder.unassignGroupStaff(groupId).build();
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
} 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) {
@@ -14,7 +14,7 @@ import org.mifosplatform.portfolio.group.data.GroupGeneralData;
public interface GroupReadPlatformService {
GroupGeneralData retrieveTemplate(Long officeId, boolean isCenterGroup);
GroupGeneralData retrieveTemplate(Long officeId, boolean isCenterGroup, boolean staffInSelectedOfficeOnly);
Page<GroupGeneralData> retrieveAll(SearchParameters searchParameters);
@@ -65,7 +65,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@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);
@@ -75,7 +75,16 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
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)) {
staffOptions = null;
}
@@ -164,7 +164,7 @@ public class LoansApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String template(@QueryParam("clientId") final Long clientId, @QueryParam("groupId") final Long groupId,
@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.authenticatedUser().validateHasReadPermission(resourceNameForPermissions);
@@ -227,7 +227,7 @@ public class LoansApiResource {
}
if (officeId != null) {
if (loanOfficersInSelectedOfficeOnly) {
if (staffInSelectedOfficeOnly) {
// only bring back loan officers in selected branch/office
Collection<StaffData> loanOfficersInBranch = this.staffReadPlatformService
.retrieveAllLoanOfficersInOfficeById(officeId);
@@ -239,8 +239,9 @@ public class LoansApiResource {
// by default bring back all loan officers in selected
// branch/office as well as loan officers in officer above
// this office
final boolean restrictToLoanOfficersOnly = true;
Collection<StaffData> loanOfficersInHierarchy = this.staffReadPlatformService
.retrieveAllLoanOfficersInOfficeAndItsParentOfficeHierarchy(officeId);
.retrieveAllStaffInOfficeAndItsParentOfficeHierarchy(officeId, restrictToLoanOfficersOnly);
if (!CollectionUtils.isEmpty(loanOfficersInHierarchy)) {
allowedLoanOfficers = new ArrayList<StaffData>(loanOfficersInHierarchy);