Add client within a group, add new group within a parent group

This commit is contained in:
Nayan Ambali
2013-03-06 17:32:43 +05:30
parent fed9f6dc68
commit 63da11993d
15 changed files with 293 additions and 141 deletions
@@ -7,13 +7,17 @@ package org.mifosplatform.portfolio.client.domain;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
@@ -29,6 +33,7 @@ import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.portfolio.group.domain.Group;
import org.springframework.data.jpa.domain.AbstractPersistable;
@Entity
@@ -71,10 +76,14 @@ public class Client extends AbstractPersistable<Long> {
@Column(name = "image_key", length = 500)
private String imageKey;
@ManyToMany
@JoinTable(name = "m_group_client", joinColumns = @JoinColumn(name = "client_id"), inverseJoinColumns = @JoinColumn(name = "group_id"))
private Set<Group> parentGroups;
@Transient
private boolean accountNumberRequiresAutoGeneration = false;
public static Client fromJson(final Office clientOffice, final JsonCommand command) {
public static Client fromJson(final Office clientOffice, final Group clientParentGroup , final JsonCommand command) {
final String accountNo = command.stringValueOfParameterNamed("accountNo");
final String firstname = command.stringValueOfParameterNamed("firstname");
@@ -84,14 +93,14 @@ public class Client extends AbstractPersistable<Long> {
final LocalDate joiningDate = command.localDateValueOfParameterNamed("joinedDate");
final String externalId = command.stringValueOfParameterNamed("externalId");
return new Client(clientOffice, accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
return new Client(clientOffice, clientParentGroup ,accountNo, firstname, middlename, lastname, fullname, joiningDate, externalId);
}
protected Client() {
//
}
private Client(final Office office, final String accountNo, final String firstname, final String middlename, final String lastname,
private Client(final Office office, final Group clientParentGroup, final String accountNo, final String firstname, final String middlename, final String lastname,
final String fullname, final LocalDate openingDate, final String externalId) {
if (StringUtils.isBlank(accountNo)) {
this.accountNumber = new RandomPasswordGenerator(19).generate();
@@ -130,6 +139,11 @@ public class Client extends AbstractPersistable<Long> {
this.fullname = null;
}
if(clientParentGroup != null){
this.parentGroups = new HashSet<Group>();
this.parentGroups.add(clientParentGroup);
}
deriveDisplayName();
validateNameParts();
}
@@ -40,7 +40,7 @@ public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJ
* The parameters supported for this command.
*/
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "accountNo", "externalId", "firstname",
"middlename", "lastname", "fullname", "officeId", "joinedDate", "locale", "dateFormat"));
"middlename", "lastname", "fullname", "officeId", "joinedDate", "locale", "dateFormat", "groupId"));
private final FromJsonHelper fromApiJsonHelper;
@@ -173,6 +173,12 @@ public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJ
final Long officeId = fromApiJsonHelper.extractLongNamed(officeIdParameterName, element);
baseDataValidator.reset().parameter(officeIdParameterName).value(officeId).notNull().integerGreaterThanZero();
}
final String groupIdParameterName = "groupId";
if (fromApiJsonHelper.parameterExists(groupIdParameterName, element)) {
final Long groupId = fromApiJsonHelper.extractLongNamed(groupIdParameterName, element);
baseDataValidator.reset().parameter(groupIdParameterName).value(groupId).notNull().integerGreaterThanZero();
}
final String joinedDateParameterName = "joinedDate";
if (fromApiJsonHelper.parameterExists(joinedDateParameterName, element)) {
@@ -42,6 +42,9 @@ import org.mifosplatform.portfolio.client.exception.NoteNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.serialization.ClientNoteCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -58,6 +61,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final ClientRepository clientRepository;
private final ClientIdentifierRepository clientIdentifierRepository;
private final OfficeRepository officeRepository;
private final GroupRepository groupRepository;
private final NoteRepository noteRepository;
private final CodeValueRepositoryWrapper codeValueRepository;
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@@ -72,7 +76,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final ClientNoteCommandFromApiJsonDeserializer clientNoteFromApiJsonDeserializer,
final ClientIdentifierCommandFromApiJsonDeserializer clientIdentifierCommandFromApiJsonDeserializer,
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory) {
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory,
final GroupRepository groupRepository) {
this.context = context;
this.clientRepository = clientRepository;
this.clientIdentifierRepository = clientIdentifierRepository;
@@ -83,6 +88,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.clientNoteFromApiJsonDeserializer = clientNoteFromApiJsonDeserializer;
this.clientIdentifierCommandFromApiJsonDeserializer = clientIdentifierCommandFromApiJsonDeserializer;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
this.groupRepository = groupRepository;
}
@Transactional
@@ -136,8 +142,17 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final Office clientOffice = this.officeRepository.findOne(officeId);
if (clientOffice == null) { throw new OfficeNotFoundException(officeId); }
final Client newClient = Client.fromJson(clientOffice, command);
final Long groupId = command.longValueOfParameterNamed("groupId");
Group clientParentGroup = null;
if(groupId != null){
clientParentGroup = this.groupRepository.findOne(groupId);
if (clientParentGroup == null) { throw new GroupNotFoundException(groupId); }
}
final Client newClient = Client.fromJson(clientOffice, clientParentGroup , command);
this.clientRepository.save(newClient);
if (newClient.isAccountNumberRequiresAutoGeneration()) {
@@ -45,7 +45,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
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", "loanOfficerId",
final Set<String> supportedParams = new HashSet<String>(Arrays.asList("name", "officeId", "levelId", "parentId", "staffId",
"externalId", "clientMembers"));
checkForUnsupportedParameters(requestMap, supportedParams);
@@ -56,7 +56,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
final Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters);
final Long levelId = extractLongParameter("levelId", requestMap, modifiedParameters);
final Long parentId = extractLongParameter("parentId", requestMap, modifiedParameters);
final Long loanOfficerId = extractLongParameter("loanOfficerId", requestMap, modifiedParameters);
final Long staffId = extractLongParameter("staffId", requestMap, modifiedParameters);
final String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
final JsonParser parser = new JsonParser();
@@ -75,7 +75,7 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
}
}
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, loanOfficerId, clientMembers, parentId,
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, staffId, clientMembers, parentId,
levelId);
}
@@ -110,15 +110,18 @@ public class GroupsApiResource {
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String newGroupDetails(@Context final UriInfo uriInfo, @QueryParam("officeId") final Long officeId,
@QueryParam("levelId") final Long levelId) {
@QueryParam("levelId") final Long levelId, @QueryParam("parentGroupId") final Long parentGroupId) {
context.authenticatedUser().validateHasReadPermission("GROUP");
GroupData groupTemplateData = null;
if (officeId != null && levelId != null) {
if (levelId != null && parentGroupId != null) {
groupTemplateData = this.groupReadPlatformService.retrieveNewChildGroupDetails(officeId, levelId, parentGroupId);
} else if (officeId != null && levelId != null) {
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(officeId, levelId);
} else if (levelId != null) {
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId(), levelId);
groupTemplateData = this.groupReadPlatformService.retrieveNewGroupDetails(context.authenticatedUser().getOffice().getId(),
levelId);
}
final ApiRequestJsonSerializationSettings settings = apiRequestParameterHelper.process(uriInfo.getQueryParameters());
@@ -138,27 +141,27 @@ public class GroupsApiResource {
}
@POST
@Path("{groupId}/command/assign_loanofficer")
@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.assignLoanOfficer(command);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.assignStaff(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@POST
@Path("{groupId}/command/unassign_loanofficer")
@Path("{groupId}/command/unassign_staff")
@Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON })
public String unassignLoanOfficer(@PathParam("groupId") final Long groupId, final String jsonRequestBody) {
final GroupCommand command = this.apiDataConversionService.convertJsonToGroupCommand(groupId, jsonRequestBody);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.unassignLoanOfficer(command);
CommandProcessingResult entityIdentifier = this.groupWritePlatformService.unassignStaff(command);
return this.toApiJsonSerializer.serialize(entityIdentifier);
}
@@ -13,7 +13,7 @@ public class GroupCommand {
private final String externalId;
private final String name;
private final Long officeId;
private final Long loanOfficerId;
private final Long staffId;
private final Long parentId;
private final Long levelId;
@@ -22,10 +22,10 @@ public class GroupCommand {
private final Set<String> modifiedParameters;
public GroupCommand(Set<String> modifiedParameters, final Long id, final String externalId, final String name,
final Long officeId, final Long loanOfficerId, String[] clientMembers , final Long parentId ,final Long levelId) {
final Long officeId, final Long staffId, String[] clientMembers , final Long parentId ,final Long levelId) {
this.id = id;
this.officeId = officeId;
this.loanOfficerId = loanOfficerId;
this.staffId = staffId;
this.parentId = parentId;
this.levelId = levelId;
this.externalId = externalId;
@@ -47,8 +47,8 @@ public class GroupCommand {
return levelId;
}
public Long getLoanOfficeId() {
return loanOfficerId;
public Long getStaffId() {
return staffId;
}
public String getExternalId() {
@@ -79,8 +79,8 @@ public class GroupCommand {
return this.modifiedParameters.contains("levelId");
}
public boolean isLoanOfficerChanged() {
return this.modifiedParameters.contains("loanOfficerId");
public boolean isStaffChanged() {
return this.modifiedParameters.contains("staffId");
}
public boolean isNameChanged() {
@@ -55,7 +55,7 @@ public class GroupCommandValidator {
}
}
public void validateForLoanOfficerUpdate() {
public void validateForStaffUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
@@ -63,8 +63,8 @@ public class GroupCommandValidator {
baseDataValidator.reset().parameter("id").value(command.getId()).notNull();
if (command.isLoanOfficerChanged()) {
baseDataValidator.reset().parameter("loanOfficerId").value(command.getLoanOfficeId()).notNull().integerGreaterThanZero();
if (command.isStaffChanged()) {
baseDataValidator.reset().parameter("staffId").value(command.getStaffId()).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) {
@@ -7,7 +7,7 @@ package org.mifosplatform.portfolio.group.data;
import java.util.Collection;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.data.OfficeData;
import org.mifosplatform.organisation.staff.data.StaffData;
import org.mifosplatform.portfolio.client.data.ClientLookup;
@@ -35,7 +35,7 @@ public class GroupData {
@SuppressWarnings("unused")
private final Collection<ClientLookup> allowedClients;
@SuppressWarnings("unused")
private final Collection<OfficeLookup> allowedOffices;
private final Collection<OfficeData> allowedOffices;
@SuppressWarnings("unused")
private final Collection<GroupLookupData> allowedParentGroups;
@SuppressWarnings("unused")
@@ -67,7 +67,7 @@ public class GroupData {
}
public GroupData(final GroupData group, final Collection<ClientLookup> clientMembers, final Collection<ClientLookup> allowedClients,
final Collection<OfficeLookup> allowedOffices, final Collection<GroupLookupData> allowedParentGroups,
final Collection<OfficeData> allowedOffices, final Collection<GroupLookupData> allowedParentGroups,
final GroupLevelData groupLevelData, final Collection<StaffData> allowedStaffs, final Collection<GroupLookupData> childGroups , final GroupSummaryData groupSummaryData) {
this.id = group.getId();
this.officeId = group.getOfficeId();
@@ -91,7 +91,7 @@ public class GroupData {
this.childGroups = childGroups;
}
public GroupData(final Long officeId, final Collection<ClientLookup> allowedClients, final Collection<OfficeLookup> allowedOffices,
public GroupData(final Long officeId, final Collection<ClientLookup> allowedClients, final Collection<OfficeData> allowedOffices,
final Collection<GroupLookupData> allowedParentGroups, final GroupLevelData groupLevelData,
final Collection<StaffData> allowedStaffs) {
this.id = null;
@@ -45,7 +45,7 @@ public class Group extends AbstractPersistable<Long> {
@ManyToOne
@JoinColumn(name = "staff_id", nullable = true)
private Staff loanOfficer;
private Staff staff;
@SuppressWarnings("unused")
@Column(name = "level_id", nullable = false)
@@ -73,13 +73,13 @@ public class Group extends AbstractPersistable<Long> {
this.clientMembers = new HashSet<Client>();
}
public static Group newGroup(final Office office, final Staff loanOfficer , final Group parent ,final long levelId , final String name, final String externalId, final Set<Client> clientMembers) {
return new Group(office, loanOfficer , parent , levelId , name, externalId, clientMembers);
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 Group(final Office office, final Staff loanOfficer , 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 long levelId , final String name, final String externalId, final Set<Client> clientMembers) {
this.office = office;
this.loanOfficer = loanOfficer;
this.staff = staff;
this.levelId =levelId;
this.parent = parent;
@@ -110,11 +110,31 @@ public class Group extends AbstractPersistable<Long> {
return this.office.getId();
}
public Long getLoanOfficerId() {
return this.loanOfficer.getId();
public Staff getStaff() {
return this.staff;
}
public void update(final GroupCommand command, final Office groupOffice, final Staff newLoanOfficer, final Set<Client> clientMembers) {
public void setStaff(Staff staff) {
this.staff = staff;
}
public Long getStaffId() {
return this.staff.getId();
}
public Long getLevelId() {
return this.levelId;
}
public void setLevelId(Long levelId) {
this.levelId = levelId;
}
public void update(final GroupCommand command, final Office groupOffice, final Staff staff, final Set<Client> clientMembers) {
if (command.isExternalIdChanged()) {
this.externalId = command.getExternalId();
}
@@ -123,8 +143,8 @@ public class Group extends AbstractPersistable<Long> {
this.office = groupOffice;
}
if (command.isLoanOfficerChanged()) {
this.loanOfficer = newLoanOfficer;
if (command.isStaffChanged()) {
this.staff = staff;
}
if (command.isNameChanged()) {
@@ -136,15 +156,15 @@ public class Group extends AbstractPersistable<Long> {
}
}
public void assigLoanOfficer(final GroupCommand command , final Staff newLoanOfficer){
if (command.isLoanOfficerChanged()) {
this.loanOfficer = newLoanOfficer;
public void assigStaff(final GroupCommand command , final Staff newStaff){
if (command.isStaffChanged()) {
this.staff = newStaff;
}
}
public void unassigLoanOfficer(final GroupCommand command) {
if (command.isLoanOfficerChanged()) {
this.loanOfficer = null;
public void unassigStaff(final GroupCommand command) {
if (command.isStaffChanged()) {
this.staff = null;
}
}
@@ -19,7 +19,7 @@ public class GroupLevel extends AbstractPersistable<Long> {
private final Long parentId;
@Column(name = "super_parent", nullable = false)
private final boolean isSuperParent;
private final boolean superParent;
@Column(name = "level_name", nullable = false, length = 100, unique = true)
private final String levelName;
@@ -33,7 +33,7 @@ public class GroupLevel extends AbstractPersistable<Long> {
public GroupLevel() {
this.parentId = null;
this.isSuperParent = false;
this.superParent = false;
this.levelName = null;
this.recursable = false;
this.canHaveClients = false;
@@ -43,7 +43,7 @@ public class GroupLevel extends AbstractPersistable<Long> {
public GroupLevel(final Long parentId, final boolean isSuperParent, final String levelName, final boolean recursable,
final boolean canHaveClients) {
this.isSuperParent = isSuperParent;
this.superParent = isSuperParent;
this.parentId = parentId;
this.levelName = levelName;
this.recursable = recursable;
@@ -56,7 +56,7 @@ public class GroupLevel extends AbstractPersistable<Long> {
}
public boolean getIsSuperParent() {
return this.isSuperParent;
return this.superParent;
}
public String getLevelName() {
@@ -71,4 +71,9 @@ public class GroupLevel extends AbstractPersistable<Long> {
return this.canHaveClients;
}
public boolean isSuperParent() {
return this.superParent;
}
}
@@ -0,0 +1,19 @@
/**
* 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.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,.
*/
public class InvalidGroupLevelException extends AbstractPlatformDomainRuleException {
public InvalidGroupLevelException(final String action, String postFix, String defaultUserMessage, Object... defaultUserMessageArgs) {
super("error.msg.group." + action + "." + postFix, defaultUserMessage, defaultUserMessageArgs);
}
}
@@ -45,4 +45,8 @@ public interface GroupReadPlatformService {
Long retrieveTotalClients(String hierarchy);
Collection<MoneyData> retrieveGroupLoanPortfolio(String hierarchy);
GroupData retrieveNewChildGroupDetails(Long officeId, Long levelId, Long parentGroupId);
StaffData retrieveStaffsbyId(Long staffId);
}
@@ -17,9 +17,10 @@ import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.data.MoneyData;
import org.mifosplatform.organisation.office.data.OfficeLookup;
import org.mifosplatform.organisation.office.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;
@@ -30,6 +31,8 @@ import org.mifosplatform.portfolio.group.data.GroupData;
import org.mifosplatform.portfolio.group.data.GroupLevelData;
import org.mifosplatform.portfolio.group.data.GroupLookupData;
import org.mifosplatform.portfolio.group.data.GroupSummaryData;
import org.mifosplatform.portfolio.group.domain.Group;
import org.mifosplatform.portfolio.group.domain.GroupRepository;
import org.mifosplatform.portfolio.group.exception.GroupLevelNotFoundException;
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,14 +48,17 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final GroupRepository groupRepository;
@Autowired
public GroupReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource,
ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService) {
ClientReadPlatformService clientReadPlatformService, final OfficeReadPlatformService officeReadPlatformService,
final GroupRepository groupRepository) {
this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource);
this.clientReadPlatformService = clientReadPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.groupRepository = groupRepository;
}
@Override
@@ -90,38 +96,34 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Override
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";
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId, levelId });
}
private GroupLookupData retrieveGroupbyId(Long parentGroupId) {
try {
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";
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId, levelId });
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) {
// TODO need throw proper exception
throw new GroupNotFoundException(officeId);
throw new GroupNotFoundException(parentGroupId);
}
}
@Override
public Collection<GroupLookupData> retrieveChildGroupsbyGroupId(final Long groupId) {
try {
this.context.authenticatedUser();
this.context.authenticatedUser();
GroupLookupMapper rm = new GroupLookupMapper();
String sql = "select " + rm.groupLookupSchema()
+ " from m_group pg join m_group g where pg.id = g.parent_id and pg.id = ? and g.is_deleted=0";
GroupLookupMapper rm = new GroupLookupMapper();
return this.jdbcTemplate.query(sql, rm, new Object[] { groupId });
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 });
} catch (EmptyResultDataAccessException e) {
throw new GroupNotFoundException(groupId);
}
}
@Override
@@ -129,11 +131,8 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
try {
this.context.authenticatedUser();
GroupLevelDataMapper rm = new GroupLevelDataMapper();
String sql = "select " + rm.groupLevelSchema() + " where gl.id = ? ";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { levelId });
} catch (EmptyResultDataAccessException e) {
@@ -155,7 +154,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId));
}
List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
List<OfficeData> allowedOffices = new ArrayList<OfficeData>(officeReadPlatformService.retrieveAllOfficesForDropdown());
List<GroupLookupData> allowedParentGroups = null;
@@ -169,13 +168,49 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs);
}
@Override
public GroupData retrieveNewChildGroupDetails(Long officeId, Long levelId, Long parentGroupId) {
GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(levelId);
if (groupLevelData == null) { throw new GroupLevelNotFoundException(levelId); }
Group group = groupRepository.findOne(parentGroupId);
if (group == null) { throw new GroupNotFoundException(parentGroupId); }
if (officeId == null) {
officeId = group.getOfficeId();
}
List<ClientLookup> allowedClients = null;
if (groupLevelData.isCanHaveClients()) {
allowedClients = new ArrayList<ClientLookup>(
this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(officeId));
}
List<OfficeData> allowedOffices = new ArrayList<OfficeData>();
allowedOffices.add(officeReadPlatformService.retrieveOffice(officeId));
List<GroupLookupData> allowedParentGroups = new ArrayList<GroupLookupData>();
allowedParentGroups.add(this.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()));
}
return new GroupData(officeId, allowedClients, allowedOffices, allowedParentGroups, groupLevelData, allowedStaffs);
}
@Override
public GroupData retrieveGroupDetails(final Long groupId, final boolean template) {
GroupData group = this.retrieveGroup(groupId);
final Collection<ClientLookup> clientMembers = this.retrieveClientMembers(groupId);
Collection<ClientLookup> availableClients = null;
Collection<OfficeLookup> allowedOffices = null;
Collection<OfficeData> allowedOffices = null;
Collection<GroupLookupData> allowedParentGroups = null;
GroupLevelData groupLevelData = this.retrieveGroupLevelDetails(group.getGroupLevel());
;
@@ -197,7 +232,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
availableClients = this.clientReadPlatformService.retrieveAllIndividualClientsForLookupByOfficeId(group.getOfficeId());
availableClients.removeAll(group.clientMembers());
}
allowedOffices = officeReadPlatformService.retrieveAllOfficesForLookup();
allowedOffices = officeReadPlatformService.retrieveAllOfficesForDropdown();
if (groupLevelData.getParentLevelId() != null) {
allowedParentGroups = this.retrieveAllGroupsbyOfficeIdAndLevelId(group.getOfficeId(), groupLevelData.getParentLevelId());
}
@@ -214,23 +249,29 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
@Override
public Collection<StaffData> retrieveStaffsbyOfficeId(final Long officeId) {
this.context.authenticatedUser();
StaffDataMapper rm = new StaffDataMapper();
String sql = "select " + rm.staffDataSchema() + " where o.id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId });
}
@Override
public StaffData retrieveStaffsbyId(final Long staffId) {
try {
this.context.authenticatedUser();
StaffDataMapper rm = new StaffDataMapper();
String sql = "select " + rm.staffDataSchema() + " where o.id = ?";
return this.jdbcTemplate.query(sql, rm, new Object[] { officeId });
String sql = "select " + rm.staffDataSchema() + " where s.id = ?";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { staffId });
} catch (EmptyResultDataAccessException e) {
// TODO throw Staff not found in given office
throw new StaffNotFoundException(officeId);
throw new StaffNotFoundException(staffId);
}
}
@Override
public Long retrieveTotalClients(final String hierarchy) {
public Long retrieveTotalClients(final String hierarchy) {
this.context.authenticatedUser();
@@ -239,6 +280,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
+ "ON gc.group_id = g.id WHERE g.hierarchy LIKE ? ";
return this.jdbcTemplate.queryForLong(sqlTotalClients, new Object[] { groupHierarchy });
// TODO to need catch EmptyResultDataAccessException ?
}
@Override
@@ -306,9 +348,10 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
String parentName = rs.getString("parentName");
Long staffId = rs.getLong("staffId");
String staffName = rs.getString("staffName");
String hierarchy =rs.getString("hierarchy");
String hierarchy = rs.getString("hierarchy");
return new GroupData(id, officeId, officeName, name, externalId, groupLevel, parentId, parentName, staffId, staffName , hierarchy);
return new GroupData(id, officeId, officeName, name, externalId, groupLevel, parentId, parentName, staffId, staffName,
hierarchy);
}
}
@@ -516,4 +559,5 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
return new GroupAccountSummaryData(id, externalId, productId, loanProductName, loanStatusId);
}
}
}
@@ -21,9 +21,9 @@ public interface GroupWritePlatformService {
CommandProcessingResult deleteGroup(Long groupId);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
CommandProcessingResult assignLoanOfficer(GroupCommand command);
CommandProcessingResult assignStaff(GroupCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'UPDATE_GROUP')")
CommandProcessingResult unassignLoanOfficer(GroupCommand command);
CommandProcessingResult unassignStaff(GroupCommand command);
}
@@ -24,8 +24,12 @@ 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.GroupNotFoundException;
import org.mifosplatform.portfolio.group.exception.InvalidGroupLevelException;
import org.mifosplatform.portfolio.group.exception.LoanOfficerNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,15 +53,19 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
private final OfficeRepository officeRepository;
private final StaffRepository staffRepository;
private final GroupLevelRepository groupLevelRepository;
@Autowired
public GroupWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final GroupRepository groupRepository,
final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository) {
final ClientRepository clientRepository, final OfficeRepository officeRepository, final StaffRepository staffRepository,
final GroupLevelRepository groupLevelRepository) {
this.context = context;
this.groupRepository = groupRepository;
this.clientRepository = clientRepository;
this.officeRepository = officeRepository;
this.staffRepository = staffRepository;
this.groupLevelRepository = groupLevelRepository;
}
@Transactional
@@ -73,15 +81,15 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
if (groupOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
Staff loanOfficer = null;
final Long loanOfficerId = command.getLoanOfficeId();
Staff staff = null;
final Long staffId = command.getStaffId();
/**
* Validate the loan officer is present in the given office or not
* Validate the staff is present in the given office or not
*/
if (loanOfficerId != null) {
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, command.getOfficeId());
if (loanOfficer == null) { throw new StaffNotFoundException(loanOfficerId); }
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, command.getOfficeId());
if (staff == null) { throw new StaffNotFoundException(staffId); }
}
final Long parentId = command.getParentId();
@@ -90,22 +98,36 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
/**
* 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();
}
/**
* Need to validate level is immediate child level of the Parent group's level
*/
// TODO level validation
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);
}
}
final Set<Client> clientMembers = assembleSetOfClients(command);
final Group newGroup = Group.newGroup(groupOffice, loanOfficer, parent , levelId , command.getName(), command.getExternalId(), clientMembers);
final Group newGroup = Group.newGroup(groupOffice, staff, parent , levelId , command.getName(), command.getExternalId(), clientMembers);
// pre save to generate id for use in group hierarchy
this.groupRepository.save(newGroup);
@@ -137,55 +159,55 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
Office groupOffice = null;
final Long officeId = command.getOfficeId();
Staff loanOfficer = null;
final Long loanOfficerId = command.getLoanOfficeId();
Staff staff = null;
final Long staffId = command.getStaffId();
if (command.isOfficeIdChanged() && command.isLoanOfficerChanged()) {
if (command.isOfficeIdChanged() && command.isStaffChanged()) {
/**
* Scenario: Both Office and loan officer are changed, check new
* loan officer is present in new office
* 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 (loanOfficerId != null) {
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, officeId);
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, officeId);
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
}
} else if (command.isOfficeIdChanged()) {
/**
* Scenario: Only Office is changed, check new office has
* present loan officer, This situation is not practical as loan
* officer can't be present in two offices
* 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 loan
// officer at loan level are also updated or verified
// 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 (loanOfficerId != null) {
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, groupForUpdate.getOfficeId());
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
}
} else if (command.isLoanOfficerChanged()) {
} else if (command.isStaffChanged()) {
/**
* Scenario: Only Loan Officer is changed, check new new loan
* Scenario: Only staff is changed, check new new loan
* officer is in present assigned office
*/
if (loanOfficerId != null) {
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
if (staffId != null) {
staff = this.staffRepository.findByOffice(staffId, groupForUpdate.getOfficeId());
if (staff == null) { throw new LoanOfficerNotFoundException(staffId); }
}
}
final Set<Client> clientMembers = assembleSetOfClients(command);
groupForUpdate.update(command, groupOffice, loanOfficer, clientMembers);
groupForUpdate.update(command, groupOffice, staff, clientMembers);
this.groupRepository.saveAndFlush(groupForUpdate);
@@ -199,24 +221,24 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
@Transactional
@Override
public CommandProcessingResult assignLoanOfficer(final GroupCommand command) {
public CommandProcessingResult assignStaff(final GroupCommand command) {
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForLoanOfficerUpdate();
validator.validateForStaffUpdate();
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
Staff loanOfficer = null;
final Long loanOfficerId = command.getLoanOfficeId();
if (command.isLoanOfficerChanged() && loanOfficerId != null) {
loanOfficer = this.staffRepository.findByOffice(loanOfficerId, groupForUpdate.getOfficeId());
if (loanOfficer == null) { throw new LoanOfficerNotFoundException(loanOfficerId); }
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); }
}
groupForUpdate.assigLoanOfficer(command, loanOfficer);
groupForUpdate.assigStaff(command, staff);
this.groupRepository.saveAndFlush(groupForUpdate);
@@ -225,24 +247,24 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
@Transactional
@Override
public CommandProcessingResult unassignLoanOfficer(final GroupCommand command) {
public CommandProcessingResult unassignStaff(final GroupCommand command) {
this.context.authenticatedUser();
final GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForLoanOfficerUpdate();
validator.validateForStaffUpdate();
final Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()) { throw new GroupNotFoundException(command.getId()); }
final Long loanOfficerId = command.getLoanOfficeId();
final Long presentLoanOfficerId = groupForUpdate.getLoanOfficerId();
final Long staffId = command.getStaffId();
final Long presentStaffId = groupForUpdate.getStaffId();
if (command.isLoanOfficerChanged() && loanOfficerId != null) {
if (!loanOfficerId.equals(presentLoanOfficerId)) { throw new LoanOfficerNotFoundException(loanOfficerId); }
if (command.isStaffChanged() && staffId != null) {
if (!staffId.equals(presentStaffId)) { throw new LoanOfficerNotFoundException(staffId); }
}
groupForUpdate.unassigLoanOfficer(command);
groupForUpdate.unassigStaff(command);
this.groupRepository.saveAndFlush(groupForUpdate);