Merge remote-tracking branch 'nayan/MIFOSX-186'

This commit is contained in:
Keith Woodlock
2013-03-10 22:53:37 +00:00
30 changed files with 901 additions and 745 deletions
@@ -0,0 +1,2 @@
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UNASSIGNSTAFF_GROUP', 'GROUP', 'UNASSIGNSTAFF', 1);
INSERT INTO `m_permission` (`grouping`, `code`, `entity_name`, `action_name`, `can_maker_checker`) VALUES ('portfolio', 'UNASSIGNSTAFF_GROUP_CHECKER', 'GROUP', 'UNASSIGNSTAFF', 1);
@@ -367,6 +367,10 @@ public class CommandWrapper {
return isDatatableResource() && isUpdateOperation() && this.apptableId != null && this.datatableId != null;
}
public boolean isUnassignStaff() {
return this.actionName.equalsIgnoreCase("UNASSIGNSTAFF") && this.entityName.equalsIgnoreCase("GROUP");
}
public String commandName() {
return this.actionName + "_" + this.entityName;
}
@@ -461,5 +465,10 @@ public class CommandWrapper {
}
return isnoteResource;
}
public boolean isGroupResource() {
return this.entityName.equalsIgnoreCase("GROUP");
}
}
@@ -904,4 +904,35 @@ public class CommandWrapperBuilder {
this.href = "/" + resourceType + "/" + resourceId + "/calendars/" + noteId;
return this;
}
public CommandWrapperBuilder createGroup() {
this.actionName = "CREATE";
this.entityName = "GROUP";
this.href = "/groups/template";
return this;
}
public CommandWrapperBuilder updateGroup(final Long groupId) {
this.actionName = "UPDATE";
this.entityName = "GROUP";
this.entityId = groupId;
this.href = "/groups/" + groupId;
return this;
}
public CommandWrapperBuilder unassignStaff(final Long groupId) {
this.actionName = "UNASSIGNSTAFF";
this.entityName = "GROUP";
this.entityId = groupId;
this.href = "/groups/" + groupId;
return this;
}
public CommandWrapperBuilder deleteGroup(final Long groupId) {
this.actionName = "DELETE";
this.entityName = "GROUP";
this.entityId = groupId;
this.href = "/groups/" + groupId;
return this;
}
}
@@ -415,6 +415,19 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else if (wrapper.isGroupResource()) {
if (wrapper.isCreate()) {
handler = applicationContext.getBean("createGroupCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUpdate()) {
handler = applicationContext.getBean("updateGroupCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isUnassignStaff()) {
handler = applicationContext.getBean("unassignStaffCommandHandler", NewCommandSourceHandler.class);
} else if (wrapper.isDelete()) {
handler = applicationContext.getBean("deleteGroupCommandHandler", NewCommandSourceHandler.class);
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
} else {
throw new UnsupportedCommandException(wrapper.commandName());
}
@@ -1,13 +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;
import org.mifosplatform.portfolio.group.command.GroupCommand;
public interface PortfolioApiDataConversionService {
GroupCommand convertJsonToGroupCommand(Long resourceIdentifier, String json);
}
@@ -1,118 +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;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.UnsupportedParameterException;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.springframework.stereotype.Service;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
@Service
public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataConversionService {
/**
* Google-gson class for converting to and from json.
*/
private final Gson gsonConverter;
public PortfolioApiDataConversionServiceImpl() {
this.gsonConverter = new Gson();
}
@Override
public GroupCommand convertJsonToGroupCommand(final Long resourceIdentifier, final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
final Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
final Set<String> supportedParams = new HashSet<String>(Arrays.asList("name", "officeId", "levelId", "parentId", "staffId",
"externalId", "clientMembers"));
checkForUnsupportedParameters(requestMap, supportedParams);
final Set<String> modifiedParameters = new HashSet<String>();
final String name = extractStringParameter("name", requestMap, modifiedParameters);
final Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters);
final Long levelId = extractLongParameter("levelId", requestMap, modifiedParameters);
final Long parentId = extractLongParameter("parentId", requestMap, modifiedParameters);
final Long staffId = extractLongParameter("staffId", requestMap, modifiedParameters);
final String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
final JsonParser parser = new JsonParser();
String[] clientMembers = null;
JsonElement element = parser.parse(json);
if (element.isJsonObject()) {
JsonObject object = element.getAsJsonObject();
if (object.has("clientMembers")) {
modifiedParameters.add("clientMembers");
JsonArray array = object.get("clientMembers").getAsJsonArray();
clientMembers = new String[array.size()];
for (int i = 0; i < array.size(); i++) {
clientMembers[i] = array.get(i).getAsString();
}
}
}
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, staffId, clientMembers, parentId,
levelId);
}
private void checkForUnsupportedParameters(final Map<String, ?> requestMap, final Set<String> supportedParams) {
List<String> unsupportedParameterList = new ArrayList<String>();
for (String providedParameter : requestMap.keySet()) {
if (!supportedParams.contains(providedParameter)) {
unsupportedParameterList.add(providedParameter);
}
}
if (!unsupportedParameterList.isEmpty()) { throw new UnsupportedParameterException(unsupportedParameterList); }
}
private String extractStringParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
String paramValue = null;
if (requestMap.containsKey(paramName)) {
paramValue = (String) requestMap.get(paramName);
modifiedParameters.add(paramName);
}
if (paramValue != null) {
paramValue = paramValue.trim();
}
return paramValue;
}
private Long extractLongParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
Long paramValue = null;
if (requestMap.containsKey(paramName)) {
String valueAsString = (String) requestMap.get(paramName);
if (StringUtils.isNotBlank(valueAsString)) {
paramValue = Long.valueOf(Double.valueOf(valueAsString).longValue());
}
modifiedParameters.add(paramName);
}
return paramValue;
}
}
@@ -24,18 +24,18 @@ 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;
import org.mifosplatform.infrastructure.core.api.ApiParameterHelper;
import org.mifosplatform.infrastructure.core.api.ApiRequestParameterHelper;
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.PortfolioApiDataConversionService;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.mifosplatform.portfolio.group.data.GroupAccountSummaryCollectionData;
import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.group.service.GroupReadPlatformService;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@@ -46,32 +46,27 @@ import org.springframework.stereotype.Component;
public class GroupsApiResource {
private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("id", "officeId", "name", "externalId",
"clientMembers", "allowedClients", "allowedOffices" , "allowedParentGroups" ,"groupLevel" ,"allowedStaffs" ,"childGroups"));
"clientMembers", "allowedClients", "allowedOffices", "allowedParentGroups", "groupLevel", "allowedStaffs", "childGroups"));
private final PlatformSecurityContext context;
private final GroupReadPlatformService groupReadPlatformService;
private final GroupWritePlatformService groupWritePlatformService;
private final ToApiJsonSerializer<GroupData> toApiJsonSerializer;
private final ToApiJsonSerializer<GroupAccountSummaryCollectionData> groupSummaryToApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioApiDataConversionService apiDataConversionService;
private final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService;
@Autowired
public GroupsApiResource(
final PlatformSecurityContext context,
final GroupReadPlatformService groupReadPlatformService,
final GroupWritePlatformService groupWritePlatformService,
public GroupsApiResource(final PlatformSecurityContext context, final GroupReadPlatformService groupReadPlatformService,
final ToApiJsonSerializer<GroupData> toApiJsonSerializer,
final ToApiJsonSerializer<GroupAccountSummaryCollectionData> groupSummaryToApiJsonSerializer,
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioApiDataConversionService apiDataConversionService) {
final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioCommandSourceWritePlatformService commandsSourceWritePlatformService) {
this.context = context;
this.groupReadPlatformService = groupReadPlatformService;
this.groupWritePlatformService = groupWritePlatformService;
this.toApiJsonSerializer = toApiJsonSerializer;
this.groupSummaryToApiJsonSerializer = groupSummaryToApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.apiDataConversionService = apiDataConversionService;
this.commandsSourceWritePlatformService = commandsSourceWritePlatformService;
}
@GET
@@ -81,12 +76,12 @@ public class GroupsApiResource {
@QueryParam("officeId") final Long officeId, @QueryParam("externalId") final String externalId,
@QueryParam("name") final String name, @QueryParam("underHierarchy") final String hierarchy) {
context.authenticatedUser().validateHasReadPermission("GROUP");
this.context.authenticatedUser().validateHasReadPermission("GROUP");
final String extraCriteria = getGroupExtraCriteria(sqlSearch, officeId, externalId, name, hierarchy);
Collection<GroupData> groups = this.groupReadPlatformService.retrieveAllGroups(extraCriteria);
final Collection<GroupData> groups = this.groupReadPlatformService.retrieveAllGroups(extraCriteria);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, groups, GROUP_DATA_PARAMETERS);
}
@@ -96,12 +91,12 @@ public class GroupsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@Context final UriInfo uriInfo, @PathParam("groupId") final Long groupId) {
context.authenticatedUser().validateHasReadPermission("GROUP");
boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
GroupData group = this.groupReadPlatformService.retrieveGroupDetails(groupId, template);
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
this.context.authenticatedUser().validateHasReadPermission("GROUP");
final boolean template = ApiParameterHelper.template(uriInfo.getQueryParameters());
final GroupData group = this.groupReadPlatformService.retrieveGroupDetails(groupId, template);
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, group, GROUP_DATA_PARAMETERS);
}
@@ -112,7 +107,7 @@ public class GroupsApiResource {
public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("levelId") final Long levelId, @QueryParam("parentGroupId") final Long parentGroupId) {
context.authenticatedUser().validateHasReadPermission("GROUP");
this.context.authenticatedUser().validateHasReadPermission("GROUP");
GroupData groupTemplateData = null;
if (levelId != null && parentGroupId != null) {
@@ -120,63 +115,55 @@ public class GroupsApiResource {
} else if (officeId != null && levelId != null) {
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId, levelId);
} else if (levelId != null) {
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId(),
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(this.context.authenticatedUser().getOffice().getId(),
levelId);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
final ApiRequestJsonSerializationSettings settings = this.apiRequestParameterHelper.process(uriInfo.getQueryParameters());
return this.toApiJsonSerializer.serialize(settings, groupTemplateData, GROUP_DATA_PARAMETERS);
}
@POST
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String createGroup(final String jsonRequestBody) {
public String createGroup(final String apiRequestBodyAsJson) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(null, jsonRequestBody);
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.createGroup() //
.withJson(apiRequestBodyAsJson) //
.build(); //
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.createGroup(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@POST
@Path("{groupId}/command/assign_staff")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String assignLoanOfficer(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.assignStaff(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@POST
@Path("{groupId}/command/unassign_staff")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String unassignLoanOfficer(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
public String unassignLoanOfficer(@PathParam("groupId") final Long groupId, final String apiRequestBodyAsJson) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.unassignStaff(groupId) //
.withJson(apiRequestBodyAsJson) //
.build(); //
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.unassignStaff(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@PUT
@Path("{groupId}")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String updateGroup(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
public String updateGroup(@PathParam("groupId") final Long groupId, final String apiRequestBodyAsJson) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.updateGroup(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.updateGroup(groupId) //
.withJson(apiRequestBodyAsJson) //
.build(); //
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
}
@DELETE
@@ -185,9 +172,12 @@ public class GroupsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String deleteGroup(@PathParam("groupId") final Long groupId) {
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.deleteGroup(groupId);
final CommandWrapper commandRequest = new CommandWrapperBuilder() //
.deleteGroup(groupId) //
.build(); //
final CommandProcessingResult result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
return this.toApiJsonSerializer.serialize(result);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@GET
@@ -196,22 +186,23 @@ public class GroupsApiResource {
@Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupAccount(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
context.authenticatedUser().validateHasReadPermission("GROUP");
this.context.authenticatedUser().validateHasReadPermission("GROUP");
final GroupAccountSummaryCollectionData groupAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(groupId);
GroupAccountSummaryCollectionData groupAccount = this.groupReadPlatformService.retrieveGroupAccountDetails(groupId);
final Set<String> GROUP_ACCOUNTS_DATA_PARAMETERS = new HashSet<String>(Arrays.asList("pendingApprovalLoans",
"awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount", "awaitingDisbursalLoanCount",
"activeLoanCount", "closedLoanCount"));
"awaitingDisbursalLoans", "openLoans", "closedLoans", "anyLoanCount", "pendingApprovalLoanCount",
"awaitingDisbursalLoanCount", "activeLoanCount", "closedLoanCount"));
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
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 String hierarchy) {
private String getGroupExtraCriteria(String sqlSearch, final Long officeId, final String externalId, final String name,
final String hierarchy) {
String extraCriteria = "";
@@ -5,94 +5,54 @@
*/
package org.mifosplatform.portfolio.group.command;
import java.util.Set;
public class GroupCommand {
private final Long id;
private final String externalId;
private final String name;
private final Long officeId;
private final Long staffId;
private final Long parentId;
private final Long levelId;
private final String[] clientMembers;
private final String[] childGroups;
private final Set<String> modifiedParameters;
public GroupCommand(Set<String> modifiedParameters, final Long id, final String externalId, final String name,
final Long officeId, final Long staffId, String[] clientMembers , final Long parentId ,final Long levelId) {
this.id = id;
public GroupCommand(final String externalId, final String name, final Long officeId, final Long staffId, final String[] clientMembers,
final String[] childGroups, final Long parentId) {
this.officeId = officeId;
this.staffId = staffId;
this.parentId = parentId;
this.levelId = levelId;
this.externalId = externalId;
this.name = name;
this.clientMembers = clientMembers;
this.modifiedParameters = modifiedParameters;
this.childGroups = childGroups;
}
public Long getOfficeId() {
return officeId;
return this.officeId;
}
public Long getParentId() {
return parentId;
}
public Long getLevelId() {
return levelId;
return this.parentId;
}
public Long getStaffId() {
return staffId;
return this.staffId;
}
public String getExternalId() {
return externalId;
return this.externalId;
}
public String getName() {
return name;
}
public Long getId() {
return id;
return this.name;
}
public String[] getClientMembers() {
return clientMembers;
return this.clientMembers;
}
public boolean isOfficeIdChanged() {
return this.modifiedParameters.contains("officeId");
public String[] getChildGroups() {
return this.childGroups;
}
public boolean isParentIdChanged() {
return this.modifiedParameters.contains("parentId");
}
public boolean isLevelIdChanged() {
return this.modifiedParameters.contains("levelId");
}
public boolean isStaffChanged() {
return this.modifiedParameters.contains("staffId");
}
public boolean isNameChanged() {
return this.modifiedParameters.contains("name");
}
public boolean isExternalIdChanged() {
return this.modifiedParameters.contains("externalId");
}
public boolean isClientMembersChanged() {
return this.modifiedParameters.contains("clientMembers");
}
}
}
@@ -1,75 +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.command;
import java.util.ArrayList;
import java.util.List;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
public class GroupCommandValidator {
private final GroupCommand command;
public GroupCommandValidator(GroupCommand command) {
this.command = command;
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
baseDataValidator.reset().parameter("levelId").value(command.getLevelId()).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
baseDataValidator.reset().parameter("name").value(command.getName()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
if (command.isOfficeIdChanged()) {
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
public void validateForStaffUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
if (command.isStaffChanged()) {
baseDataValidator.reset().parameter("staffId").value(command.getStaffId()).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
@@ -34,11 +34,11 @@ public class GroupAccountSummaryCollectionData {
@SuppressWarnings("unused")
private final List<GroupAccountSummaryData> closedIndividualLoans;
public GroupAccountSummaryCollectionData(List<GroupAccountSummaryData> pendingApprovalLoans,
List<GroupAccountSummaryData> awaitingDisbursalLoans, List<GroupAccountSummaryData> openLoans,
List<GroupAccountSummaryData> closedLoans, List<GroupAccountSummaryData> pendingApprovalIndividualLoans,
List<GroupAccountSummaryData> awaitingDisbursalIndividualLoans, List<GroupAccountSummaryData> openIndividualLoans,
List<GroupAccountSummaryData> closedIndividualLoans) {
public GroupAccountSummaryCollectionData(final List<GroupAccountSummaryData> pendingApprovalLoans,
final List<GroupAccountSummaryData> awaitingDisbursalLoans, final List<GroupAccountSummaryData> openLoans,
final List<GroupAccountSummaryData> closedLoans, final List<GroupAccountSummaryData> pendingApprovalIndividualLoans,
final List<GroupAccountSummaryData> awaitingDisbursalIndividualLoans, final List<GroupAccountSummaryData> openIndividualLoans,
final List<GroupAccountSummaryData> closedIndividualLoans) {
this.pendingApprovalLoans = pendingApprovalLoans;
this.pendingApprovalLoanCount = pendingApprovalLoans.size();
this.awaitingDisbursalLoans = awaitingDisbursalLoans;
@@ -48,7 +48,7 @@ public class GroupAccountSummaryCollectionData {
this.closedLoans = closedLoans;
this.closedLoanCount = closedLoans.size();
this.anyLoanCount = pendingApprovalLoanCount + awaitingDisbursalLoanCount + activeLoanCount + closedLoanCount;
this.anyLoanCount = this.pendingApprovalLoanCount + this.awaitingDisbursalLoanCount + this.activeLoanCount + this.closedLoanCount;
this.pendingApprovalIndividualLoans = pendingApprovalIndividualLoans;
this.pendingApprovalIndividualLoanCount = pendingApprovalIndividualLoans.size();
@@ -59,43 +59,43 @@ public class GroupAccountSummaryCollectionData {
this.closedIndividualLoans = closedIndividualLoans;
this.closedIndividualLoanCount = closedIndividualLoans.size();
this.anyIndividualLoanCount = pendingApprovalIndividualLoanCount + awaitingDisbursalIndividualLoanCount + activeIndividualLoanCount
+ closedIndividualLoanCount;
this.anyIndividualLoanCount = this.pendingApprovalIndividualLoanCount + this.awaitingDisbursalIndividualLoanCount
+ this.activeIndividualLoanCount + this.closedIndividualLoanCount;
}
public int getAnyLoanCount() {
return anyLoanCount;
return this.anyLoanCount;
}
public int getPendingApprovalLoanCount() {
return pendingApprovalLoanCount;
return this.pendingApprovalLoanCount;
}
public List<GroupAccountSummaryData> getPendingApprovalLoans() {
return pendingApprovalLoans;
return this.pendingApprovalLoans;
}
public int getAwaitingDisbursalLoanCount() {
return awaitingDisbursalLoanCount;
return this.awaitingDisbursalLoanCount;
}
public List<GroupAccountSummaryData> getAwaitingDisbursalLoans() {
return awaitingDisbursalLoans;
return this.awaitingDisbursalLoans;
}
public int getActiveLoanCount() {
return activeLoanCount;
return this.activeLoanCount;
}
public List<GroupAccountSummaryData> getOpenLoans() {
return openLoans;
return this.openLoans;
}
public int getClosedLoanCount() {
return closedLoanCount;
return this.closedLoanCount;
}
public List<GroupAccountSummaryData> getClosedLoans() {
return closedLoans;
return this.closedLoans;
}
}
@@ -16,10 +16,8 @@ public class GroupAccountSummaryData {
private final String productName;
private final Integer accountStatusId;
public GroupAccountSummaryData(Long id, String externalId,
Long productId,
String productName,
Integer accountStatusId) {
public GroupAccountSummaryData(final Long id, final String externalId, final Long productId, final String productName,
final Integer accountStatusId) {
this.id = id;
this.externalId = externalId;
this.productId = productId;
@@ -28,22 +26,22 @@ public class GroupAccountSummaryData {
}
public Long getId() {
return id;
return this.id;
}
public String getExternalId() {
return externalId;
return this.externalId;
}
public Long getProductId() {
return productId;
return this.productId;
}
public String getProductName() {
return productName;
return this.productName;
}
public Integer getAccountStatusId() {
return accountStatusId;
return this.accountStatusId;
}
}
@@ -44,7 +44,8 @@ public class GroupData {
private final Collection<GroupLookupData> childGroups;
public GroupData(final Long id, final Long officeId, final String officeName, final String name, final String externalId,
final Long groupLevel, final Long parentId, final String parentName, final Long staffId, final String staffName , final String hierarchy) {
final Long groupLevel, final Long parentId, final String parentName, final Long staffId, final String staffName,
final String hierarchy) {
this.id = id;
this.officeId = officeId;
this.officeName = officeName;
@@ -68,7 +69,8 @@ public class GroupData {
public GroupData(final GroupData group, final Collection<ClientLookup> clientMembers, final Collection<ClientLookup> allowedClients,
final Collection<OfficeData> allowedOffices, final Collection<GroupLookupData> allowedParentGroups,
final GroupLevelData groupLevelData, final Collection<StaffData> allowedStaffs, final Collection<GroupLookupData> childGroups , final GroupSummaryData groupSummaryData) {
final GroupLevelData groupLevelData, final Collection<StaffData> allowedStaffs, final Collection<GroupLookupData> childGroups,
final GroupSummaryData groupSummaryData) {
this.id = group.getId();
this.officeId = group.getOfficeId();
this.officeName = group.getOfficeName();
@@ -116,23 +118,23 @@ public class GroupData {
}
public Long getId() {
return id;
return this.id;
}
public String getName() {
return name;
return this.name;
}
public String getExternalId() {
return externalId;
return this.externalId;
}
public Long getOfficeId() {
return officeId;
return this.officeId;
}
public String getOfficeName() {
return officeName;
return this.officeName;
}
public Long getGroupLevel() {
@@ -155,7 +157,6 @@ public class GroupData {
return this.parentName;
}
public String getHierarchy() {
return this.hierarchy;
}
@@ -10,7 +10,6 @@ package org.mifosplatform.portfolio.group.data;
*/
public class GroupLevelData {
private final Long levelId;
private final String levelName;
private final Long parentLevelId;
@@ -20,9 +19,10 @@ public class GroupLevelData {
private final boolean superParent;
private final boolean recursable;
private final boolean canHaveClients;
public GroupLevelData(Long levelId, String levelName, Long parentLevelId, String parentLevelName, Long childLevelId,
String childLevelName, boolean superParent, boolean recursable, boolean canHaveClients) {
public GroupLevelData(final Long levelId, final String levelName, final Long parentLevelId, final String parentLevelName,
final Long childLevelId, final String childLevelName, final boolean superParent, final boolean recursable,
final boolean canHaveClients) {
super();
this.levelId = levelId;
this.levelName = levelName;
@@ -35,50 +35,38 @@ public class GroupLevelData {
this.canHaveClients = canHaveClients;
}
public String getParentLevelName() {
return this.parentLevelName;
}
public Long getChildLevelId() {
return this.childLevelId;
}
public String getChildLevelName() {
return this.childLevelName;
}
public Long getLevelId() {
return this.levelId;
}
public Long getParentLevelId() {
return this.parentLevelId;
}
public String getLevelName() {
return this.levelName;
}
public boolean isSuperParent() {
return this.superParent;
}
public boolean isRecursable() {
return this.recursable;
}
public boolean isCanHaveClients() {
return this.canHaveClients;
}
@@ -19,10 +19,10 @@ public class GroupLookupData {
}
public Long getId() {
return id;
return this.id;
}
public String getName() {
return name;
return this.name;
}
}
@@ -24,7 +24,6 @@ import org.apache.commons.lang.StringUtils;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@@ -46,9 +45,10 @@ public class Group extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "staff_id", nullable = true)
private Staff staff;
@Column(name = "level_id", nullable = false)
private Long levelId;
@ManyToOne
@JoinColumn(name = "level_id", nullable = false)
private GroupLevel groupLevel;
@Column(name = "hierarchy", length = 100)
private String hierarchy;
@@ -72,20 +72,22 @@ public class Group extends AbstractPersistable<Long> {
this.clientMembers = new HashSet<Client>();
}
public static Group newGroup(final Office office, final Staff staff , final Group parent ,final long levelId , final String name, final String externalId, final Set<Client> clientMembers) {
return new Group(office, staff , parent , levelId , name, externalId, clientMembers);
public static Group newGroup(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel,
final String name, final String externalId, final Set<Client> clientMembers, final Set<Group> childGroups) {
return new Group(office, staff, parent, groupLevel, name, externalId, clientMembers, childGroups);
}
public Group(final Office office, final Staff staff , final Group parent ,final long levelId , final String name, final String externalId, final Set<Client> clientMembers) {
public Group(final Office office, final Staff staff, final Group parent, final GroupLevel groupLevel, final String name,
final String externalId, final Set<Client> clientMembers, final Set<Group> childGroups) {
this.office = office;
this.staff = staff;
this.levelId =levelId;
this.groupLevel = groupLevel;
this.parent = parent;
if (parent != null) {
this.parent.addChild(this);
}
if (StringUtils.isNotBlank(name)) {
this.name = name.trim();
} else {
@@ -99,6 +101,9 @@ public class Group extends AbstractPersistable<Long> {
if (clientMembers != null) {
this.clientMembers = clientMembers;
}
if (childGroups != null) {
this.children.addAll(childGroups);
}
}
private void addChild(final Group group) {
@@ -109,12 +114,10 @@ public class Group extends AbstractPersistable<Long> {
return this.office.getId();
}
public Staff getStaff() {
return this.staff;
}
public void setStaff(final Staff staff) {
this.staff = staff;
}
@@ -123,48 +126,52 @@ public class Group extends AbstractPersistable<Long> {
return this.staff.getId();
}
public Long getLevelId() {
return this.levelId;
public GroupLevel getGroupLevel() {
return this.groupLevel;
}
public void setLevelId(final Long levelId) {
this.levelId = levelId;
public String getExternalId() {
return this.externalId;
}
public void update(final GroupCommand command, final Office groupOffice, final Staff staff, final Set<Client> clientMembers) {
if (command.isExternalIdChanged()) {
this.externalId = command.getExternalId();
}
if (command.isOfficeIdChanged()) {
this.office = groupOffice;
}
if (command.isStaffChanged()) {
this.staff = staff;
}
if (command.isNameChanged()) {
this.name = command.getName();
}
if (clientMembers != null && command.isClientMembersChanged()) {
this.clientMembers = clientMembers;
}
public String getName() {
return this.name;
}
public void assigStaff(final GroupCommand command , final Staff newStaff){
if (command.isStaffChanged()) {
this.staff = newStaff;
}
public Set<Client> getClientMembers() {
return this.clientMembers;
}
public void unassigStaff(final GroupCommand command) {
if (command.isStaffChanged()) {
this.staff = null;
}
public Group getParent() {
return this.parent;
}
public void setParent(final Group parent) {
this.parent = parent;
}
public void setClientMembers(final Set<Client> clientMembers) {
this.clientMembers = clientMembers;
}
public void setName(final String name) {
this.name = name;
}
public void setExternalId(final String externalId) {
this.externalId = externalId;
}
public void setLevelId(final GroupLevel groupLevel) {
this.groupLevel = groupLevel;
}
public void assigStaff(final Staff newStaff) {
this.staff = newStaff;
}
public void unassigStaff() {
this.staff = null;
}
public void addClientMember(final Client member) {
@@ -183,20 +190,20 @@ public class Group extends AbstractPersistable<Long> {
*/
public void delete() {
this.deleted = true;
this.externalId = this.getId() + "_" + this.externalId;
this.name = this.getId() + "_" + this.name;
this.externalId = getId() + "_" + this.externalId;
this.name = getId() + "_" + this.name;
}
public boolean isDeleted() {
return deleted;
return this.deleted;
}
public void generateHierarchy() {
if (parent != null) {
this.hierarchy = this.parent.hierarchyOf(this.getId());
if (this.parent != null) {
this.hierarchy = this.parent.hierarchyOf(getId());
} else {
this.hierarchy = "." + this.getId() + ".";
this.hierarchy = "." + getId() + ".";
}
}
@@ -204,4 +211,8 @@ public class Group extends AbstractPersistable<Long> {
return this.hierarchy + id.toString() + ".";
}
public boolean isOfficeIdentifiedBy(final Long officeId) {
return this.office.identifiedBy(officeId);
}
}
@@ -55,25 +55,24 @@ public class GroupLevel extends AbstractPersistable<Long> {
return this.parentId;
}
public boolean getIsSuperParent() {
return this.superParent;
}
public String getLevelName() {
return this.levelName;
}
public boolean getRecursable() {
public boolean isRecursable() {
return this.recursable;
}
public boolean getCanHaveClients() {
public boolean canHaveClients() {
return this.canHaveClients;
}
public boolean isSuperParent() {
return this.superParent;
}
public boolean isIdentifiedByParentId(final Long parentLevelId) {
return this.parentId.equals(parentLevelId);
}
}
@@ -9,5 +9,9 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface GroupLevelRepository extends JpaRepository<GroupLevel, Long>, JpaSpecificationExecutor<GroupLevel> {
// no behaviour added
GroupLevel findBySuperParent(boolean superParent);
GroupLevel findByParentId(Long parentId);
}
@@ -10,10 +10,10 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
/**
* A {@link RuntimeException} thrown when group resources are not found.
*/
public class LoanOfficerNotFoundException extends AbstractPlatformResourceNotFoundException {
public class GroupHasNoStaffException extends AbstractPlatformResourceNotFoundException {
public LoanOfficerNotFoundException(Long id){
super("error.msg.loanofficer.id.invalid", "Loan Officer with identifier " + id + " does not exist", id);
public GroupHasNoStaffException(final Long groupId) {
super("error.msg.group.has.no.staff", "Group with identifier " + groupId + " does not have staff", groupId);
}
}
@@ -12,8 +12,8 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
*/
public class GroupLevelNotFoundException extends AbstractPlatformResourceNotFoundException {
public GroupLevelNotFoundException(Long id){
public GroupLevelNotFoundException(final Long id) {
super("error.msg.group.level.id.invalid", "Group level with identifier " + id + " does not exist", id);
}
}
@@ -12,8 +12,8 @@ import org.mifosplatform.infrastructure.core.exception.AbstractPlatformResourceN
*/
public class GroupNotFoundException extends AbstractPlatformResourceNotFoundException {
public GroupNotFoundException(Long id){
public GroupNotFoundException(final Long id) {
super("error.msg.group.id.invalid", "Group with identifier " + id + " does not exist", id);
}
}
@@ -8,12 +8,14 @@ package org.mifosplatform.portfolio.group.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown when parentGroup'd level is not equal to parent level of the levelid param,.
* {@link AbstractPlatformDomainRuleException} thrown when parentGroup'd level
* is not equal to parent level of the levelid param,.
*/
public class InvalidGroupLevelException extends AbstractPlatformDomainRuleException {
public InvalidGroupLevelException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
public InvalidGroupLevelException(final String action, final String postFix, final String defaultUserMessage,
final Object... defaultUserMessageArgs) {
super("error.msg.group." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
}
}
}
@@ -0,0 +1,32 @@
/**
* 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.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class CreateGroupCommandHandler implements NewCommandSourceHandler {
private final GroupWritePlatformService groupWritePlatformService;
@Autowired
public CreateGroupCommandHandler(final GroupWritePlatformService groupWritePlatformService) {
this.groupWritePlatformService = groupWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.groupWritePlatformService.createGroup(command);
}
}
@@ -0,0 +1,31 @@
/**
* 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.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class DeleteGroupCommandHandler implements NewCommandSourceHandler {
private final GroupWritePlatformService groupWritePlatformService;
@Autowired
public DeleteGroupCommandHandler(final GroupWritePlatformService groupWritePlatformService) {
this.groupWritePlatformService = groupWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.groupWritePlatformService.deleteGroup(command.entityId());
}
}
@@ -0,0 +1,31 @@
/**
* 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.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UnassignStaffCommandHandler implements NewCommandSourceHandler {
private final GroupWritePlatformService groupWritePlatformService;
@Autowired
public UnassignStaffCommandHandler(final GroupWritePlatformService groupWritePlatformService) {
this.groupWritePlatformService = groupWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.groupWritePlatformService.unassignStaff(command.entityId(), command);
}
}
@@ -0,0 +1,32 @@
/**
* 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.handler;
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.group.service.GroupWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UpdateGroupCommandHandler implements NewCommandSourceHandler {
private final GroupWritePlatformService groupWritePlatformService;
@Autowired
public UpdateGroupCommandHandler(final GroupWritePlatformService groupWritePlatformService) {
this.groupWritePlatformService = groupWritePlatformService;
}
@Transactional
@Override
public CommandProcessingResult processCommand(final JsonCommand command) {
return this.groupWritePlatformService.updateGroup(command.entityId(), command);
}
}
@@ -0,0 +1,179 @@
/**
* 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.serialization;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
import com.google.gson.reflect.TypeToken;
/**
* Implementation of {@link FromApiJsonDeserializer} for {@link ClientCommand}
* 's.
*/
@Component
public final class GroupCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<GroupCommand> {
/**
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "externalId", "name", "officeId", "staffId",
"parentId", "clientMembers", "childGroups"));
private final FromJsonHelper fromApiJsonHelper;
@Autowired
public GroupCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromApiJsonHelper = fromApiJsonHelper;
}
@Override
public GroupCommand commandFromApiJson(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final String externalId = this.fromApiJsonHelper.extractStringNamed("externalId", element);
final String name = this.fromApiJsonHelper.extractStringNamed("name", element);
final Long officeId = this.fromApiJsonHelper.extractLongNamed("officeId", element);
final Long staffId = this.fromApiJsonHelper.extractLongNamed("staffId", element);
final Long parentId = this.fromApiJsonHelper.extractLongNamed("parentId", element);
final String[] clientMembers = this.fromApiJsonHelper.extractArrayNamed("clientMembers", element);
final String[] childGroups = this.fromApiJsonHelper.extractArrayNamed("childGroups", element);
return new GroupCommand(externalId, name, officeId, staffId, clientMembers, childGroups, parentId);
}
public void validateForCreate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, this.supportedParameters);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
final String externalIdParameterName = "externalId";
if (this.fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
}
final String officeIdParameterName = "officeId";
if (this.fromApiJsonHelper.parameterExists(officeIdParameterName, element)) {
final Long officeId = this.fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
}
final String parentIdParameterName = "parentId";
if (this.fromApiJsonHelper.parameterExists(parentIdParameterName, element)) {
final Long parentId = this.fromApiJsonHelper.extractLongNamed(parentIdParameterName, element);
baseDataValidator.reset().parameter(parentIdParameterName).value(parentId).notNull().integerGreaterThanZero();
}
final String staffIdParameterName = "stafftId";
if (this.fromApiJsonHelper.parameterExists(staffIdParameterName, element)) {
final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element);
baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUpdate(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
/*
* Office updated is not supported
*/
final Set<String> supportedParametersForupdate = new HashSet<String>(Arrays.asList("id", "externalId", "name", "staffId",
"parentId", "clientMembers", "childGroups"));
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParametersForupdate);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
final String externalIdParameterName = "externalId";
if (this.fromApiJsonHelper.parameterExists(externalIdParameterName, element)) {
final String externalId = this.fromApiJsonHelper.extractStringNamed(externalIdParameterName, element);
baseDataValidator.reset().parameter(externalIdParameterName).value(externalId).ignoreIfNull().notExceedingLengthOf(100);
}
final String parentIdParameterName = "parentId";
if (this.fromApiJsonHelper.parameterExists(parentIdParameterName, element)) {
final Long parentId = this.fromApiJsonHelper.extractLongNamed(parentIdParameterName, element);
baseDataValidator.reset().parameter(parentIdParameterName).value(parentId).notNull().integerGreaterThanZero();
}
final String staffIdParameterName = "stafftId";
if (this.fromApiJsonHelper.parameterExists(staffIdParameterName, element)) {
final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element);
baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUnassignStaff(final String json) {
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
/*
* Office updated is not supported
*/
final Set<String> supportedParametersUnassignStaff = new HashSet<String>(Arrays.asList("staffId"));
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, supportedParametersUnassignStaff);
final JsonElement element = this.fromApiJsonHelper.parse(json);
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("group");
final String staffIdParameterName = "stafftId";
if (this.fromApiJsonHelper.parameterExists(staffIdParameterName, element)) {
final Long staffId = this.fromApiJsonHelper.extractLongNamed(staffIdParameterName, element);
baseDataValidator.reset().parameter(staffIdParameterName).value(staffId).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
}
@@ -19,18 +19,18 @@ import org.mifosplatform.portfolio.group.data.GroupLookupData;
public interface GroupReadPlatformService {
Collection<GroupData> retrieveAllGroups(String extraCriteria);
GroupData retrieveGroup(Long groupId);
GroupData retrieveNewGroupDetails(Long officeId , Long levelId);
GroupData retrieveNewGroupDetails(Long officeId, Long levelId);
Collection<ClientLookup> retrieveClientMembers(Long groupId);
GroupAccountSummaryCollectionData retrieveGroupAccountDetails(Long groupId);
Collection<GroupAccountSummaryData> retrieveGroupLoanAccountsByLoanOfficerId(Long groupId, Long loanOfficerId);
Collection<GroupLookupData> retrieveAllGroupsbyOfficeIdAndLevelId(Long officeId , Long levelId);
Collection<GroupLookupData> retrieveAllGroupsbyOfficeIdAndLevelId(Long officeId, Long levelId);
GroupLevelData retrieveGroupLevelDetails(Long levelId);
@@ -20,7 +20,6 @@ import org.mifosplatform.organisation.monetary.data.MoneyData;
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.domain.Staff;
import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.data.ClientLookup;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
@@ -52,7 +51,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Autowired
public GroupReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
final ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
final GroupRepository groupRepository) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
@@ -66,7 +65,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.context.authenticatedUser();
GroupDataMapper rm = new GroupDataMapper();
final GroupDataMapper rm = new GroupDataMapper();
String sql = "select " + rm.groupSchema() + " where g.is_deleted=0";
@@ -83,12 +82,12 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
try {
this.context.authenticatedUser();
GroupDataMapper rm = new GroupDataMapper();
final GroupDataMapper rm = new GroupDataMapper();
String sql = "select " + rm.groupSchema() + " where g.id = ? and g.is_deleted=0";
final String sql = "select " + rm.groupSchema() + " where g.id = ? and g.is_deleted=0";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { groupId });
} catch (EmptyResultDataAccessException e) {
} catch (final EmptyResultDataAccessException e) {
throw new GroupNotFoundException(groupId);
}
}
@@ -97,19 +96,19 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
public Collection<GroupLookupData> retrieveAllGroupsbyOfficeIdAndLevelId(final Long officeId, final Long levelId) {
this.context.authenticatedUser();
GroupLookupMapper rm = new GroupLookupMapper();
String sql = "select " + rm.groupLookupSchema() + " from m_group g where g.office_id = ? and level_id = ? and g.is_deleted=0";
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 GroupLookupData retrieveGroupbyId(Long parentGroupId) {
private GroupLookupData retrieveGroupbyId(final Long parentGroupId) {
try {
this.context.authenticatedUser();
GroupLookupMapper rm = new GroupLookupMapper();
String sql = "select " + rm.groupLookupSchema() + " from m_group g where g.id = ? and g.is_deleted=0";
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 (EmptyResultDataAccessException e) {
} catch (final EmptyResultDataAccessException e) {
throw new GroupNotFoundException(parentGroupId);
}
}
@@ -118,8 +117,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
public Collection<GroupLookupData> retrieveChildGroupsbyGroupId(final Long groupId) {
this.context.authenticatedUser();
GroupLookupMapper rm = new GroupLookupMapper();
String sql = "select " + rm.groupLookupSchema()
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 });
@@ -131,11 +130,11 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
try {
this.context.authenticatedUser();
GroupLevelDataMapper rm = new GroupLevelDataMapper();
String sql = "select " + rm.groupLevelSchema() + " where gl.id = ? ";
final GroupLevelDataMapper rm = new GroupLevelDataMapper();
final String sql = "select " + rm.groupLevelSchema() + " where gl.id = ? ";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { levelId });
} catch (EmptyResultDataAccessException e) {
} catch (final EmptyResultDataAccessException e) {
throw new GroupLevelNotFoundException(levelId);
}
}
@@ -143,7 +142,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Override
public GroupData retrieveNewGroupDetails(final Long officeId, final Long levelId) {
GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(levelId);
final GroupLevelData groupLevelData = retrieveGroupLevelDetails(levelId);
if (groupLevelData == null) { throw new GroupLevelNotFoundException(levelId); }
@@ -154,27 +153,28 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId));
}
List<OfficeData> allowedOffices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOfficesForDropdown());
final List<OfficeData> allowedOffices = new ArrayList<OfficeData>(this.officeReadPlatformService.retrieveAllOfficesForDropdown());
List<GroupLookupData> allowedParentGroups = null;
if (groupLevelData.getParentLevelId() != null) {
allowedParentGroups = new ArrayList<GroupLookupData>(this.retrieveAllGroupsbyOfficeIdAndLevelId(officeId,
allowedParentGroups = new ArrayList<GroupLookupData>(retrieveAllGroupsbyOfficeIdAndLevelId(officeId,
groupLevelData.getParentLevelId()));
}
List<StaffData> allowedStaffs = new ArrayList<StaffData>(this.retrieveStaffsbyOfficeId(officeId));
final List<StaffData> allowedStaffs = new ArrayList<StaffData>(retrieveStaffsbyOfficeId(officeId));
return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs);
}
@Override
public GroupData retrieveNewChildGroupDetails(Long officeId, Long levelId, Long parentGroupId) {
GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(levelId);
public GroupData retrieveNewChildGroupDetails(Long officeId, final Long levelId, final Long parentGroupId) {
final GroupLevelData groupLevelData = retrieveGroupLevelDetails(levelId);
if (groupLevelData == null) { throw new GroupLevelNotFoundException(levelId); }
Group group = groupRepository.findOne(parentGroupId);
if (group == null) { throw new GroupNotFoundException(parentGroupId); }
final Group group = this.groupRepository.findOne(parentGroupId);
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(parentGroupId); }
if (officeId == null) {
officeId = group.getOfficeId();
@@ -187,19 +187,14 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId));
}
List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
allowedOffices.add(officeReadPlatformService.retrieveOffice(officeId));
final List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
allowedOffices.add(this.officeReadPlatformService.retrieveOffice(officeId));
List<GroupLookupData> allowedParentGroups = new ArrayList<GroupLookupData>();
allowedParentGroups.add(this.retrieveGroupbyId(parentGroupId));
final List<GroupLookupData> allowedParentGroups = new ArrayList<GroupLookupData>();
allowedParentGroups.add(retrieveGroupbyId(parentGroupId));
List<StaffData> allowedStaffs = new ArrayList<StaffData>();
final Staff staff = group.getStaff();
if (staff == null) {
allowedStaffs.addAll(this.retrieveStaffsbyOfficeId(officeId));
} else {
allowedStaffs.add(this.retrieveStaffsbyId(staff.getId()));
}
final List<StaffData> allowedStaffs = new ArrayList<StaffData>();
allowedStaffs.addAll(retrieveStaffsbyOfficeId(officeId));
return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs);
}
@@ -207,21 +202,21 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Override
public GroupData retrieveGroupDetails(final Long groupId, final boolean template) {
GroupData group = this.retrieveGroup(groupId);
final Collection<ClientLookup> clientMembers = this.retrieveClientMembers(groupId);
GroupData group = retrieveGroup(groupId);
final Collection<ClientLookup> clientMembers = retrieveClientMembers(groupId);
Collection<ClientLookup> availableClients = null;
Collection<OfficeData> allowedOffices = null;
Collection<GroupLookupData> allowedParentGroups = null;
GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(group.getGroupLevel());
final GroupLevelData groupLevelData = retrieveGroupLevelDetails(group.getGroupLevel());
;
Collection<StaffData> allowedStaffs = null;
Collection<GroupLookupData> childGroups = this.retrieveChildGroupsbyGroupId(groupId);
final Collection<GroupLookupData> childGroups = retrieveChildGroupsbyGroupId(groupId);
final Long totalActiveClients = this.retrieveTotalClients(group.getHierarchy());
final Long totalChildGroups = this.retrieveTotalNoOfChildGroups(groupId);
Collection<MoneyData> totalLoanPortfolio = this.retrieveGroupLoanPortfolio(group.getHierarchy());
final Long totalActiveClients = retrieveTotalClients(group.getHierarchy());
final Long totalChildGroups = retrieveTotalNoOfChildGroups(groupId);
final Collection<MoneyData> totalLoanPortfolio = retrieveGroupLoanPortfolio(group.getHierarchy());
GroupSummaryData groupSummaryData = new GroupSummaryData(totalActiveClients, totalChildGroups, totalLoanPortfolio, null);
final GroupSummaryData groupSummaryData = new GroupSummaryData(totalActiveClients, totalChildGroups, totalLoanPortfolio, null);
group = new GroupData(group, clientMembers, availableClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs,
childGroups, groupSummaryData);
@@ -232,12 +227,12 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(group.getOfficeId());
availableClients.removeAll(group.clientMembers());
}
allowedOffices = officeReadPlatformService.retrieveAllOfficesForDropdown();
allowedOffices = this.officeReadPlatformService.retrieveAllOfficesForDropdown();
if (groupLevelData.getParentLevelId() != null) {
allowedParentGroups = this.retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), groupLevelData.getParentLevelId());
allowedParentGroups = retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), groupLevelData.getParentLevelId());
}
allowedStaffs = this.retrieveStaffsbyOfficeId(group.getOfficeId());
allowedStaffs = retrieveStaffsbyOfficeId(group.getOfficeId());
group = new GroupData(group, group.clientMembers(), availableClients, allowedOffices, allowedParentGroups, groupLevelData,
allowedStaffs, childGroups, groupSummaryData);
@@ -250,8 +245,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
public Collection<StaffData> retrieveStaffsbyOfficeId(final Long officeId) {
this.context.authenticatedUser();
StaffDataMapper rm = new StaffDataMapper();
String sql = "select " + rm.staffDataSchema() + " where o.id = ?";
final StaffDataMapper rm = new StaffDataMapper();
final String sql = "select " + rm.staffDataSchema() + " where o.id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId });
}
@@ -261,11 +256,11 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
try {
this.context.authenticatedUser();
StaffDataMapper rm = new StaffDataMapper();
String sql = "select " + rm.staffDataSchema() + " where s.id = ?";
final StaffDataMapper rm = new StaffDataMapper();
final String sql = "select " + rm.staffDataSchema() + " where s.id = ?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { staffId });
} catch (EmptyResultDataAccessException e) {
} catch (final EmptyResultDataAccessException e) {
throw new StaffNotFoundException(staffId);
}
}
@@ -275,19 +270,18 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.context.authenticatedUser();
String groupHierarchy = hierarchy + "%";
String sqlTotalClients = "SELECT count(gc.client_id) FROM m_group_client gc JOIN m_group g "
final String groupHierarchy = hierarchy + "%";
final String sqlTotalClients = "SELECT count(gc.client_id) FROM m_group_client gc JOIN m_group g "
+ "ON gc.group_id = g.id WHERE g.hierarchy LIKE ? ";
return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupHierarchy });
// TODO to need catch EmptyResultDataAccessException ?
}
@Override
public Long retrieveTotalNoOfChildGroups(final Long groupId) {
this.context.authenticatedUser();
String sqlTotalClients = "SELECT count(gc.id) FROM m_group g JOIN m_group gc WHERE g.id = gc.parent_id and g.id = ?";
final String sqlTotalClients = "SELECT count(gc.id) FROM m_group g JOIN m_group gc WHERE g.id = gc.parent_id and g.id = ?";
return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupId });
}
@@ -297,10 +291,10 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.context.authenticatedUser();
MoneyDataMapper rm = new MoneyDataMapper();
final MoneyDataMapper rm = new MoneyDataMapper();
String groupHierarchy = hierarchy + "%";
String sql = "select " + rm.moneyDataSchema() + " FROM m_group_client gc JOIN m_group g ON gc.group_id = g.id "
final String groupHierarchy = hierarchy + "%";
final String sql = "select " + rm.moneyDataSchema() + " FROM m_group_client gc JOIN m_group g ON gc.group_id = g.id "
+ "JOIN m_loan l ON l.client_id = gc.client_id LEFT JOIN m_organisation_currency oc ON oc.code = l.currency_code "
+ " WHERE g.hierarchy LIKE ? GROUP BY l.currency_code ";
@@ -315,11 +309,11 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public MoneyData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
public MoneyData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
String currencyCode = rs.getString("currencyCode");
Integer decimalPlaces = rs.getInt("decimalPlaces");
BigDecimal amount = rs.getBigDecimal("amount");
final String currencyCode = rs.getString("currencyCode");
final Integer decimalPlaces = rs.getInt("decimalPlaces");
final BigDecimal amount = rs.getBigDecimal("amount");
return new MoneyData(currencyCode, amount, decimalPlaces);
}
@@ -336,19 +330,19 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public GroupData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
public GroupData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
String externalId = rs.getString("externalId");
Long officeId = rs.getLong("officeId");
String officeName = rs.getString("officeName");
Long groupLevel = rs.getLong("groupLevel");
Long parentId = rs.getLong("parentId");
String parentName = rs.getString("parentName");
Long staffId = rs.getLong("staffId");
String staffName = rs.getString("staffName");
String hierarchy = rs.getString("hierarchy");
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 groupLevel = rs.getLong("groupLevel");
final Long parentId = rs.getLong("parentId");
final String parentName = rs.getString("parentName");
final Long staffId = rs.getLong("staffId");
final String staffName = rs.getString("staffName");
final String hierarchy = rs.getString("hierarchy");
return new GroupData(id, officeId, officeName, name, externalId, groupLevel, parentId, parentName, staffId, staffName,
hierarchy);
@@ -363,10 +357,10 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public GroupLookupData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
public GroupLookupData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = rs.getLong("id");
String name = rs.getString("name");
final Long id = rs.getLong("id");
final String name = rs.getString("name");
return new GroupLookupData(id, name);
}
@@ -383,17 +377,17 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public GroupLevelData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
public GroupLevelData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long levelId = rs.getLong("id");
String levelName = rs.getString("levelName");
Long parentLevelId = rs.getLong("parentLevelId");
String parentLevelName = rs.getString("parentName");
Long childLevelId = rs.getLong("childLevelId");
String childLevelName = rs.getString("childLevelName");
boolean superParent = rs.getBoolean("superParent");
boolean recursable = rs.getBoolean("recursable");
boolean canHaveClients = rs.getBoolean("canHaveClients");
final Long levelId = rs.getLong("id");
final String levelName = rs.getString("levelName");
final Long parentLevelId = rs.getLong("parentLevelId");
final String parentLevelName = rs.getString("parentName");
final Long childLevelId = rs.getLong("childLevelId");
final String childLevelName = rs.getString("childLevelName");
final boolean superParent = rs.getBoolean("superParent");
final boolean recursable = rs.getBoolean("recursable");
final boolean canHaveClients = rs.getBoolean("canHaveClients");
return new GroupLevelData(levelId, levelName, parentLevelId, parentLevelName, childLevelId, childLevelName, superParent,
recursable, canHaveClients);
@@ -409,15 +403,15 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public StaffData mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
public StaffData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = rs.getLong("id");
String firstname = rs.getString("firstname");
String lastname = rs.getString("lastname");
String displayName = rs.getString("displayName");
Long officeId = rs.getLong("officeId");
String officeName = rs.getString("officeName");
boolean isLoanOfficer = rs.getBoolean("isLoanOfficer");
final Long id = rs.getLong("id");
final String firstname = rs.getString("firstname");
final String lastname = rs.getString("lastname");
final String displayName = rs.getString("displayName");
final Long officeId = rs.getLong("officeId");
final String officeName = rs.getString("officeName");
final boolean isLoanOfficer = rs.getBoolean("isLoanOfficer");
return StaffData.instance(id, firstname, lastname, displayName, officeId, officeName, isLoanOfficer);
}
@@ -425,13 +419,13 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public Collection<ClientLookup> retrieveClientMembers(Long groupId) {
public Collection<ClientLookup> retrieveClientMembers(final Long groupId) {
this.context.authenticatedUser();
ClientMemberSummaryDataMapper rm = new ClientMemberSummaryDataMapper();
final ClientMemberSummaryDataMapper rm = new ClientMemberSummaryDataMapper();
String sql = "select " + rm.clientMemberSummarySchema() + " where cm.is_deleted = 0 and pgc.group_id = ?";
final String sql = "select " + rm.clientMemberSummarySchema() + " where cm.is_deleted = 0 and pgc.group_id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
}
@@ -443,9 +437,9 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public ClientLookup mapRow(ResultSet rs, @SuppressWarnings("unused") int rowNum) throws SQLException {
Long id = rs.getLong("id");
String displayName = rs.getString("displayName");
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);
}
@@ -453,27 +447,27 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
@Override
public GroupAccountSummaryCollectionData retrieveGroupAccountDetails(Long groupId) {
public GroupAccountSummaryCollectionData retrieveGroupAccountDetails(final Long groupId) {
try {
this.context.authenticatedUser();
// Check if group exists
retrieveGroup(groupId);
List<GroupAccountSummaryData> pendingApprovalLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> awaitingDisbursalLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> openLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> closedLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> pendingApprovalLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> awaitingDisbursalLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> openLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> closedLoans = new ArrayList<GroupAccountSummaryData>();
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
final GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.client_id is null";
List<GroupAccountSummaryData> results = this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
if (results != null) {
for (GroupAccountSummaryData row : results) {
for (final GroupAccountSummaryData row : results) {
LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId());
final LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId());
if (statusMapper.isOpen()) {
openLoans.add(row);
@@ -487,18 +481,18 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
}
}
List<GroupAccountSummaryData> pendingApprovalIndividualLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> awaitingDisbursalIndividualLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> openIndividualLoans = new ArrayList<GroupAccountSummaryData>();
List<GroupAccountSummaryData> closedIndividualLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> pendingApprovalIndividualLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> awaitingDisbursalIndividualLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> openIndividualLoans = new ArrayList<GroupAccountSummaryData>();
final List<GroupAccountSummaryData> closedIndividualLoans = new ArrayList<GroupAccountSummaryData>();
sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.client_id is not null";
results = this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
if (results != null) {
for (GroupAccountSummaryData row : results) {
for (final GroupAccountSummaryData row : results) {
LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId());
final LoanStatusMapper statusMapper = new LoanStatusMapper(row.getAccountStatusId());
if (statusMapper.isOpen()) {
openIndividualLoans.add(row);
@@ -514,24 +508,25 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
return new GroupAccountSummaryCollectionData(pendingApprovalLoans, awaitingDisbursalLoans, openLoans, closedLoans,
pendingApprovalIndividualLoans, awaitingDisbursalIndividualLoans, openIndividualLoans, closedIndividualLoans);
} catch (EmptyResultDataAccessException e) {
} catch (final EmptyResultDataAccessException e) {
throw new GroupNotFoundException(groupId);
}
}
@Override
public Collection<GroupAccountSummaryData> retrieveGroupLoanAccountsByLoanOfficerId(Long groupId, Long loanOfficerId) {
public Collection<GroupAccountSummaryData> retrieveGroupLoanAccountsByLoanOfficerId(final Long groupId, final Long loanOfficerId) {
this.context.authenticatedUser();
// Check if group exists
retrieveGroup(groupId);
GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
final GroupLoanAccountSummaryDataMapper rm = new GroupLoanAccountSummaryDataMapper();
String sql = "select " + rm.loanAccountSummarySchema() + " where l.group_id = ? and l.client_id is null and l.loan_officer_id = ?";
final String sql = "select " + rm.loanAccountSummarySchema()
+ " where l.group_id = ? and l.client_id is null and l.loan_officer_id = ?";
List<GroupAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { groupId, loanOfficerId });
final List<GroupAccountSummaryData> loanAccounts = this.jdbcTemplate.query(sql, rm, new Object[] { groupId, loanOfficerId });
return loanAccounts;
}
@@ -540,7 +535,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
public String loanAccountSummarySchema() {
StringBuilder accountsSummary = new StringBuilder("l.id as id, l.external_id as externalId,");
final StringBuilder accountsSummary = new StringBuilder("l.id as id, l.external_id as externalId,");
accountsSummary.append("l.product_id as productId, lp.name as productName,").append("l.loan_status_id as statusId ")
.append("from m_loan l ").append("LEFT JOIN m_product_loan AS lp ON lp.id = l.product_id ");
@@ -550,11 +545,11 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Override
public GroupAccountSummaryData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException {
Long id = JdbcSupport.getLong(rs, "id");
String externalId = rs.getString("externalId");
Long productId = JdbcSupport.getLong(rs, "productId");
String loanProductName = rs.getString("productName");
Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId");
final Long id = JdbcSupport.getLong(rs, "id");
final String externalId = rs.getString("externalId");
final Long productId = JdbcSupport.getLong(rs, "productId");
final String loanProductName = rs.getString("productName");
final Integer loanStatusId = JdbcSupport.getInteger(rs, "statusId");
return new GroupAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId);
}
@@ -5,25 +5,22 @@
*/
package org.mifosplatform.portfolio.group.service;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.springframework.security.access.prepost.PreAuthorize;
public interface GroupWritePlatformService {
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'CREATE_GROUP')")
CommandProcessingResult createGroup(GroupCommand command);
CommandProcessingResult createGroup(JsonCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
CommandProcessingResult updateGroup(GroupCommand command);
CommandProcessingResult updateGroup(Long grouptId, JsonCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'DELETE_GROUP')")
CommandProcessingResult deleteGroup(Long groupId);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
CommandProcessingResult assignStaff(GroupCommand command);
CommandProcessingResult unassignStaff(Long grouptId, JsonCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
CommandProcessingResult unassignStaff(GroupCommand command);
}
@@ -6,9 +6,14 @@
package org.mifosplatform.portfolio.group.service;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.domain.Office;
@@ -21,16 +26,14 @@ import org.mifosplatform.organisation.staff.exception.StaffNotFoundException;
import org.mifosplatform.portfolio.client.domain.Client;
import org.mifosplatform.portfolio.client.domain.ClientRepository;
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.mifosplatform.portfolio.group.command.GroupCommandValidator;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupLevel;
import org.mifosplatform.portfolio.group.domain.GroupLevelRepository;
import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupLevelNotFoundException;
import org.mifosplatform.portfolio.group.exception.GroupHasNoStaffException;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException;
import org.mifosplatform.portfolio.group.exception.LoanOfficerNotFoundException;
import org.mifosplatform.portfolio.group.serialization.GroupCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,99 +48,107 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
private final static Logger logger = LoggerFactory.getLogger(GroupWritePlatformServiceJpaRepositoryImpl.class);
private final PlatformSecurityContext context;
private final GroupRepository groupRepository;
private final ClientRepository clientRepository;
private final OfficeRepository officeRepository;
private final StaffRepository staffRepository;
private final GroupLevelRepository groupLevelRepository;
private final GroupLevelRepository groupLevelRepository;
private final GroupCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired
public GroupWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepository groupRepository,
final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository,
final GroupLevelRepository groupLevelRepository) {
final GroupLevelRepository groupLevelRepository, final GroupCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context;
this.groupRepository = groupRepository;
this.clientRepository = clientRepository;
this.officeRepository = officeRepository;
this.staffRepository = staffRepository;
this.groupLevelRepository = groupLevelRepository;
this.groupLevelRepository = groupLevelRepository;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
@Transactional
@Override
public CommandProcessingResult createGroup(final GroupCommand command) {
public CommandProcessingResult createGroup(final JsonCommand command) {
try {
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForCreate();
this.fromApiJsonDeserializer.validateForCreate(command.json());
final Office groupOffice = this.officeRepository.findOne(command.getOfficeId());
final String name = command.stringValueOfParameterNamed("name");
final String externalId = command.stringValueOfParameterNamed("externalId");
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
final Long parentId = command.longValueOfParameterNamed("parentId");
Long officeId = null;
GroupLevel groupLevel = null;
Group parentGroup = null;
if (parentId == null) {
/*
* Scenario: Creating parent group [group with highest level]
* In-case of Centre/Groups, parent group with highest level is
* Centre. In-case of Federation/Cluster/SHG, parent group with
* highest level is Federation. In-case of
* Village/Centre/Groups, parent group with highest level is
* Village.
*/
officeId = command.longValueOfParameterNamed("officeId");
groupLevel = this.groupLevelRepository.findBySuperParent(true);
} else {
parentGroup = this.groupRepository.findOne(parentId);
if (parentGroup == null || parentGroup.isDeleted()) { throw new GroupNotFoundException(parentId); }
officeId = parentGroup.getOfficeId();
groupLevel = this.groupLevelRepository.findByParentId(parentGroup.getGroupLevel().getId());
}
final Office groupOffice = this.officeRepository.findOne(officeId);
if (groupOffice == null) { throw new OfficeNotFoundException(officeId); }
Staff staff = null;
final Long staffId = command.getStaffId();
final Long staffId = command.longValueOfParameterNamed("staffId");
/**
* Validate the staff is present in the given office or not
*/
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, command.getOfficeId());
staff = this.staffRepository.findByOffice(staffId, officeId);
if (staff == null) { throw new StaffNotFoundException(staffId); }
}
final Long parentId = command.getParentId();
Group parent = null;
/**
* Validate the parent group to check it is present.
*/
Long parentGroupLevelId = null;
if (parentId != null) {
parent = this.groupRepository.findOne(parentId);
if (parent == null) { throw new GroupNotFoundException(parentId); }
parentGroupLevelId = parent.getLevelId();
Set<Client> clientMembers = null;
if (groupLevel.canHaveClients()) {
clientMembers = assembleSetOfClients(officeId, command);
}
final Long levelId = command.getLevelId();
final GroupLevel groupLevel = groupLevelRepository.findOne(levelId);
if(groupLevel == null){throw new GroupLevelNotFoundException(levelId);}
final Long parentLevelId = groupLevel.getParentId();
/*
* If Group is not super parent then validate group level's parent level is same as group parent's level
* this check makes sure new group is added at immediate next level in hierarchy
*/
if(!groupLevel.isSuperParent()){
if (parentGroupLevelId != parentLevelId) {
final String errorMessage = "Parent group's level[" + parentLevelId + "] is not equal to child level's parent level ["
+ parentGroupLevelId + "]";
throw new InvalidGroupLevelException("add", "invalid.level", errorMessage, parentLevelId , parentGroupLevelId);
}
Set<Group> childGroups = null;
if (groupLevel.isRecursable()) {
childGroups = assembleSetOfChildGroups(officeId, command);
}
final Set<Client> clientMembers = assembleSetOfClients(command);
final Group newGroup = Group.newGroup(groupOffice, staff, parent , levelId , command.getName(), command.getExternalId(), clientMembers);
final Group newGroup = Group
.newGroup(groupOffice, staff, parentGroup, groupLevel, name, externalId, clientMembers, childGroups);
// pre save to generate id for use in group hierarchy
// pre-save to generate id for use in group hierarchy
this.groupRepository.save(newGroup);
newGroup.generateHierarchy();
this.groupRepository.saveAndFlush(newGroup);
return new CommandProcessingResult(newGroup.getId());
newGroup.generateHierarchy();
this.groupRepository.saveAndFlush(newGroup);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withOfficeId(groupOffice.getId()) //
.withGroupId(newGroup.getId()) //
.withEntityId(newGroup.getId()) //
.build();
} catch (final DataIntegrityViolationException dve) {
handleGroupDataIntegrityIssues(command, dve);
return new CommandProcessingResult(Long.valueOf(-1));
@@ -146,72 +157,108 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
@Transactional
@Override
public CommandProcessingResult updateGroup(final GroupCommand command) {
public CommandProcessingResult updateGroup(final Long grouptId, final JsonCommand command) {
try {
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForUpdate();
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
this.fromApiJsonDeserializer.validateForUpdate(command.json());
Office groupOffice = null;
final Long officeId = command.getOfficeId();
Staff staff = null;
final Long staffId = command.getStaffId();
final Group groupForUpdate = this.groupRepository.findOne(grouptId);
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(grouptId); }
if (command.isOfficeIdChanged() && command.isStaffChanged()) {
/**
* Scenario: Both Office and Staff are changed, check new
* staff is present in new office
*/
if (officeId != null) {
groupOffice = this.officeRepository.findOne(officeId);
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
}
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, officeId);
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
}
final Long officeId = groupForUpdate.getOfficeId();
} else if (command.isOfficeIdChanged()) {
/**
* Scenario: Only Office is changed, check new office has
* present staff, This situation is not practical as
* staff can't be present in two offices
*/
// TODO When office is changed need to make sure all the staff
// at loan level are also updated or verified
if (officeId != null) {
groupOffice = this.officeRepository.findOne(officeId);
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
}
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, groupForUpdate.getOfficeId());
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
}
final String nameParamName = "name";
if (command.isChangeInStringParameterNamed(nameParamName, groupForUpdate.getName())) {
final String newValue = command.stringValueOfParameterNamed(nameParamName);
actualChanges.put(nameParamName, newValue);
groupForUpdate.setName(StringUtils.defaultIfEmpty(newValue, null));
}
} else if (command.isStaffChanged()) {
/**
* Scenario: Only staff is changed, check new new loan
* officer is in present assigned office
*/
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, groupForUpdate.getOfficeId());
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, groupForUpdate.getExternalId())) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
groupForUpdate.setExternalId(StringUtils.defaultIfEmpty(newValue, null));
}
final Staff presentStaff = groupForUpdate.getStaff();
Long presentStaffId = null;
if (presentStaff != null) {
presentStaffId = presentStaff.getId();
}
final String staffIdParamName = "staffId";
if (command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) {
final Long newValue = command.longValueOfParameterNamed(staffIdParamName);
actualChanges.put(staffIdParamName, newValue);
final Staff newStaff = this.staffRepository.findByOffice(newValue, officeId);
if (newStaff == null) { throw new StaffNotFoundException(newValue); }
groupForUpdate.setStaff(newStaff);
}
final GroupLevel groupLevel = this.groupLevelRepository.findOne(groupForUpdate.getGroupLevel().getId());
/*
* Ignoring parentId param, if group for update is super parent.
* TODO Need to check: Ignoring is correct or need throw unsupported
* param
*/
if (!groupLevel.isSuperParent()) {
final String parentIdParamName = "parentId";
final Long parentId = groupForUpdate.getParent().getId();
if (command.isChangeInLongParameterNamed(parentIdParamName, parentId)) {
final Long newValue = command.longValueOfParameterNamed(parentIdParamName);
actualChanges.put(parentIdParamName, newValue);
final Group newParentGroup = this.groupRepository.findOne(newValue);
if (newParentGroup == null || newParentGroup.isDeleted()) { throw new StaffNotFoundException(newValue); }
if (!newParentGroup.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and parent group must have the same office";
throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage);
}
/*
* If Group is not super parent then validate group level's
* parent level is same as group parent's level this check
* makes sure new group is added at immediate next level in
* hierarchy
*/
if (!groupForUpdate.getGroupLevel().isIdentifiedByParentId(newParentGroup.getGroupLevel().getId())) {
final String errorMessage = "Parent group's level is not equal to child level's parent level ";
throw new InvalidGroupLevelException("add", "invalid.level", errorMessage);
}
groupForUpdate.setParent(newParentGroup);
}
}
final Set<Client> clientMembers = assembleSetOfClients(command);
final Set<Client> clientMembers = assembleSetOfClients(officeId, command);
final String clientMembersParamName = "clientMembers";
groupForUpdate.update(command, groupOffice, staff, clientMembers);
if (!clientMembers.equals(groupForUpdate.getClientMembers())) {
final String[] newValue = command.arrayValueOfParameterNamed(clientMembersParamName);
// TODO Use Guava's symmetricDifference
actualChanges.put(clientMembersParamName, newValue);
groupForUpdate.setClientMembers(clientMembers);
}
this.groupRepository.saveAndFlush(groupForUpdate);
return new CommandProcessingResult(groupForUpdate.getId());
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withOfficeId(groupForUpdate.getId()) //
.withGroupId(groupForUpdate.getOfficeId()) //
.withEntityId(groupForUpdate.getId()) //
.with(actualChanges) //
.build();
} catch (final DataIntegrityViolationException dve) {
handleGroupDataIntegrityIssues(command, dve);
return new CommandProcessingResult(Long.valueOf(-1));
@@ -220,55 +267,37 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
@Transactional
@Override
public CommandProcessingResult assignStaff(final GroupCommand command) {
public CommandProcessingResult unassignStaff(final Long grouptId, final JsonCommand command) {
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForStaffUpdate();
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(9);
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
this.fromApiJsonDeserializer.validateForUnassignStaff(command.json());
Staff staff = null;
final Long staffId = command.getStaffId();
if (command.isStaffChanged() && staffId != null) {
staff = this.staffRepository.findByOffice(staffId, groupForUpdate.getOfficeId());
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
final Group groupForUpdate = this.groupRepository.findOne(grouptId);
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(grouptId); }
final Staff presentStaff = groupForUpdate.getStaff();
Long presentStaffId = null;
if (presentStaff == null) { throw new GroupHasNoStaffException(grouptId); }
presentStaffId = presentStaff.getId();
final String staffIdParamName = "staffId";
if (!command.isChangeInLongParameterNamed(staffIdParamName, presentStaffId)) {
groupForUpdate.unassigStaff();
}
groupForUpdate.assigStaff(command, staff);
this.groupRepository.saveAndFlush(groupForUpdate);
return new CommandProcessingResult(groupForUpdate.getId());
}
actualChanges.put(staffIdParamName, null);
@Transactional
@Override
public CommandProcessingResult unassignStaff(final GroupCommand command) {
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withOfficeId(groupForUpdate.getId()) //
.withGroupId(groupForUpdate.getOfficeId()) //
.withEntityId(groupForUpdate.getId()) //
.with(actualChanges) //
.build();
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForStaffUpdate();
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
final Long staffId = command.getStaffId();
final Long presentStaffId = groupForUpdate.getStaffId();
if (command.isStaffChanged() && staffId != null) {
if (!staffId.equals(presentStaffId)) { throw new LoanOfficerNotFoundException(staffId); }
}
groupForUpdate.unassigStaff(command);
this.groupRepository.saveAndFlush(groupForUpdate);
return new CommandProcessingResult(groupForUpdate.getId());
}
@Transactional
@@ -277,25 +306,31 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
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);
return new CommandProcessingResult(groupId);
return new CommandProcessingResultBuilder() //
.withOfficeId(groupForDelete.getId()) //
.withGroupId(groupForDelete.getOfficeId()) //
.withEntityId(groupForDelete.getId()) //
.build();
}
private Set<Client> assembleSetOfClients(final GroupCommand command) {
private Set<Client> assembleSetOfClients(final Long officeId, final JsonCommand command) {
final Set<Client> clientMembers = new HashSet<Client>();
final String[] clientMembersArray = command.getClientMembers();
final String[] clientMembersArray = command.arrayValueOfParameterNamed("clientMembers");
if (command.isClientMembersChanged() && !ObjectUtils.isEmpty(clientMembersArray)) {
if (!ObjectUtils.isEmpty(clientMembersArray)) {
for (final String clientId : clientMembersArray) {
final Long id = Long.valueOf(clientId);
final Client client = this.clientRepository.findOne(id);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(id); }
if (!client.isOfficeIdentifiedBy(command.getOfficeId())) {
if (!client.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and Client must have the same office.";
throw new InvalidOfficeException("client", "attach.to.group", errorMessage);
}
@@ -306,18 +341,39 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
return clientMembers;
}
private Set<Group> assembleSetOfChildGroups(final Long officeId, final JsonCommand command) {
final Set<Group> childGroups = new HashSet<Group>();
final String[] childGroupsArray = command.arrayValueOfParameterNamed("childGroups");
if (!ObjectUtils.isEmpty(childGroupsArray)) {
for (final String groupId : childGroupsArray) {
final Long id = Long.valueOf(groupId);
final Group group = this.groupRepository.findOne(id);
if (group == null || group.isDeleted()) { throw new GroupNotFoundException(id); }
if (!group.isOfficeIdentifiedBy(officeId)) {
final String errorMessage = "Group and child groups must have the same office.";
throw new InvalidOfficeException("group", "attach.to.parent.group", errorMessage);
}
childGroups.add(group);
}
}
return childGroups;
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleGroupDataIntegrityIssues(final GroupCommand command, final DataIntegrityViolationException dve) {
private void handleGroupDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
final Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("external_id")) {
throw new PlatformDataIntegrityException("error.msg.group.duplicate.externalId", "Group with externalId {0} already exists",
"externalId", command.getExternalId());
"externalId", command.stringValueOfParameterNamed("externalId"));
} else if (realCause.getMessage().contains("name")) { throw new PlatformDataIntegrityException("error.msg.group.duplicate.name",
"Group with name {0} already exists", "name", command.getName()); }
"Group with name {0} already exists", "name", command.stringValueOfParameterNamed("name")); }
logger.error(dve.getMessage(), dve);
throw new PlatformDataIntegrityException("error.msg.group.unknown.data.integrity.issue",