MIFOSX-26 Added Office to Group.

This commit is contained in:
Michal Dudzinski
2012-09-26 15:24:45 +02:00
parent 3617197f5f
commit f53e662b6d
10 changed files with 122 additions and 34 deletions
@@ -0,0 +1,3 @@
alter table m_group add column office_id bigint(20) NOT NULL AFTER id;
update m_group set office_id = 1 WHERE office_id = 0;
alter table m_group add constraint foreign key (`office_id`) references `m_office` (`id`);
@@ -1,5 +1,6 @@
package org.mifosng.platform.api; package org.mifosng.platform.api;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -22,12 +23,14 @@ import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.api.data.ClientLookup; import org.mifosng.platform.api.data.ClientLookup;
import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.api.data.GroupData; import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.api.data.OfficeLookup;
import org.mifosng.platform.api.infrastructure.ApiDataConversionService; import org.mifosng.platform.api.infrastructure.ApiDataConversionService;
import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService; import org.mifosng.platform.api.infrastructure.ApiJsonSerializerService;
import org.mifosng.platform.api.infrastructure.ApiParameterHelper; import org.mifosng.platform.api.infrastructure.ApiParameterHelper;
import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.ClientReadPlatformService;
import org.mifosng.platform.group.service.GroupReadPlatformService; import org.mifosng.platform.group.service.GroupReadPlatformService;
import org.mifosng.platform.group.service.GroupWritePlatformService; import org.mifosng.platform.group.service.GroupWritePlatformService;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@@ -49,18 +52,21 @@ public class GroupsApiResource {
@Autowired @Autowired
private ApiDataConversionService apiDataConversionService; private ApiDataConversionService apiDataConversionService;
@Autowired
private OfficeReadPlatformService officeReadPlatformService;
@Autowired @Autowired
private ApiJsonSerializerService apiJsonSerializerService; private ApiJsonSerializerService apiJsonSerializerService;
private static final Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "officeId", "name", "externalId", "clientMembers")
);
@GET @GET
@Consumes({ MediaType.APPLICATION_JSON }) @Consumes({ MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAllGroups(@Context final UriInfo uriInfo){ public String retrieveAllGroups(@Context final UriInfo uriInfo){
Set<String> typicalResponseParameters = new HashSet<String>(
Arrays.asList("id", "name", "externalId")
);
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters); responseParameters.addAll(typicalResponseParameters);
@@ -79,8 +85,6 @@ public class GroupsApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveGroupData(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) { public String retrieveGroupData(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "externalId", "clientMembers"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo
.getQueryParameters()); .getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
@@ -101,6 +105,9 @@ public class GroupsApiResource {
group.setAllowedClients(availableClients); group.setAllowedClients(availableClients);
responseParameters.add("allowedClients"); responseParameters.add("allowedClients");
group.setAllowedOffices(new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup()));
responseParameters.add("allowedOffices");
} }
return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, group); return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, group);
@@ -112,14 +119,14 @@ public class GroupsApiResource {
@Produces({MediaType.APPLICATION_JSON}) @Produces({MediaType.APPLICATION_JSON})
public String newGroupDetails(@Context final UriInfo uriInfo) { public String newGroupDetails(@Context final UriInfo uriInfo) {
Set<String> typicalResponseParameters = new HashSet<String>(Arrays.asList("id", "name", "externalId", "allowedClients"));
Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters()); Set<String> responseParameters = ApiParameterHelper.extractFieldsForResponseIfProvided(uriInfo.getQueryParameters());
if (responseParameters.isEmpty()) { if (responseParameters.isEmpty()) {
responseParameters.addAll(typicalResponseParameters); responseParameters.addAll(typicalResponseParameters);
} }
boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters()); boolean prettyPrint = ApiParameterHelper.prettyPrint(uriInfo.getQueryParameters());
responseParameters.addAll(Arrays.asList("allowedClients", "allowedOffices"));
GroupData groupData = this.groupReadPlatformService.retrieveNewGroupDetails(); GroupData groupData = this.groupReadPlatformService.retrieveNewGroupDetails();
return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, groupData); return this.apiJsonSerializerService.serializeGroupDataToJson(prettyPrint, responseParameters, groupData);
@@ -7,18 +7,26 @@ public class GroupCommand {
private final Long id; private final Long id;
private final String externalId; private final String externalId;
private final String name; private final String name;
private final Long officeId;
private final String[] clientMembers; private final String[] clientMembers;
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
public GroupCommand(Set<String> modifiedParameters, final Long id, String externalId, String name, String[] clientMembers) { public GroupCommand(Set<String> modifiedParameters, final Long id, final String externalId, final String name,
final Long officeId, String[] clientMembers) {
this.id = id; this.id = id;
this.officeId = officeId;
this.externalId = externalId; this.externalId = externalId;
this.name = name; this.name = name;
this.clientMembers = clientMembers; this.clientMembers = clientMembers;
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
} }
public Long getOfficeId() {
return officeId;
}
public String getExternalId() { public String getExternalId() {
return externalId; return externalId;
} }
@@ -35,6 +43,10 @@ public class GroupCommand {
return clientMembers; return clientMembers;
} }
public boolean isOfficeIdChanged() {
return this.modifiedParameters.contains("officeId");
}
public boolean isNameChanged() { public boolean isNameChanged() {
return this.modifiedParameters.contains("name"); return this.modifiedParameters.contains("name");
} }
@@ -2,27 +2,36 @@ package org.mifosng.platform.api.data;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
public class GroupData { public class GroupData {
private final Long id; private final Long id;
private final String name; private final String name;
private final String externalId; private final String externalId;
private final Long officeId;
private final String officeName;
private Collection<ClientLookup> clientMembers = new ArrayList<ClientLookup>(); private Collection<ClientLookup> clientMembers = new ArrayList<ClientLookup>();
private Collection<ClientLookup> allowedClients = new ArrayList<ClientLookup>(); private Collection<ClientLookup> allowedClients = new ArrayList<ClientLookup>();
private Collection<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>();
public GroupData(Long id, String name, String externalId) { public GroupData(Long id, Long officeId, String officeName, String name, String externalId) {
this.id = id; this.id = id;
this.name = name; this.name = name;
this.externalId = externalId; this.externalId = externalId;
this.officeId = officeId;
this.officeName = officeName;
} }
public GroupData(Collection<ClientLookup> allowedClients) { public GroupData(Collection<ClientLookup> allowedClients, Collection<OfficeLookup> allowedOffices){
this.id = null; this.id = null;
this.name = null; this.name = null;
this.externalId = null; this.externalId = null;
this.officeId = null;
this.officeName = null;
this.allowedClients = allowedClients; this.allowedClients = allowedClients;
this.allowedOffices = allowedOffices;
} }
public Long getId() { public Long getId() {
@@ -52,4 +61,12 @@ public class GroupData {
public void setAllowedClients(Collection<ClientLookup> allowedClients) { public void setAllowedClients(Collection<ClientLookup> allowedClients) {
this.allowedClients = allowedClients; this.allowedClients = allowedClients;
} }
public Collection<OfficeLookup> getAllowedOffices() {
return allowedOffices;
}
public void setAllowedOffices(Collection<OfficeLookup> allowedOffices) {
this.allowedOffices = allowedOffices;
}
} }
@@ -338,13 +338,14 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap); Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>( Set<String> supportedParams = new HashSet<String>(
Arrays.asList("name", "externalId", "clientMembers") Arrays.asList("name", "officeId", "externalId", "clientMembers")
); );
checkForUnsupportedParameters(requestMap, supportedParams); checkForUnsupportedParameters(requestMap, supportedParams);
Set<String> modifiedParameters = new HashSet<String>(); Set<String> modifiedParameters = new HashSet<String>();
Long officeId = extractLongParameter("officeId", requestMap, modifiedParameters);
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters); String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
String name = extractStringParameter("name", requestMap, modifiedParameters); String name = extractStringParameter("name", requestMap, modifiedParameters);
@@ -366,7 +367,7 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
} }
// //
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, clientMembers); return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name, officeId, clientMembers);
} }
@Override @Override
@@ -132,8 +132,8 @@ public class GoogleGsonApiJsonSerializerService implements ApiJsonSerializerServ
"preclosedDepositAccountsCount","preclosedDepositAccounts")); "preclosedDepositAccountsCount","preclosedDepositAccounts"));
private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>( private static final Set<String> GROUP_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "name", "externalId", "clientMembers", Arrays.asList("id", "officeId", "name", "externalId", "clientMembers",
"allowedClients")); "allowedClients", "allowedOffices"));
private static final Set<String> NOTE_DATA_PARAMETERS = new HashSet<String>( private static final Set<String> NOTE_DATA_PARAMETERS = new HashSet<String>(
Arrays.asList("id", "clientId", "loanId", "loanTransactionId", Arrays.asList("id", "clientId", "loanId", "loanTransactionId",
@@ -8,18 +8,24 @@ import javax.persistence.Entity;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.client.domain.Client; import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@Entity @Entity
@Table(name = "m_group") @Table(name = "m_group")
public class Group extends AbstractAuditableCustom<AppUser, Long> { public class Group extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@JoinColumn(name = "office_id", nullable = false)
private Office office;
@Column(name = "name", length = 100, unique = true) @Column(name = "name", length = 100, unique = true)
private String name; private String name;
@@ -41,11 +47,12 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
this.clientMembers = new HashSet<Client>(); this.clientMembers = new HashSet<Client>();
} }
public static Group newGroup(String name, String externalId, Set<Client> clientMembers){ public static Group newGroup(Office office, String name, String externalId, Set<Client> clientMembers){
return new Group(name, externalId, clientMembers); return new Group(office, name, externalId, clientMembers);
} }
public Group(String name, String externalId, Set<Client> clientMembers) { public Group(Office office, String name, String externalId, Set<Client> clientMembers) {
this.office = office;
if (StringUtils.isNotBlank(name)) { if (StringUtils.isNotBlank(name)) {
this.name = name.trim(); this.name = name.trim();
} else { } else {
@@ -61,11 +68,15 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
} }
} }
public void update(final GroupCommand command, final Set<Client> clientMembers) { public void update(final GroupCommand command, final Office groupOffice, final Set<Client> clientMembers) {
if (command.isExternalIdChanged()) { if (command.isExternalIdChanged()) {
this.externalId = command.getExternalId(); this.externalId = command.getExternalId();
} }
if (command.isOfficeIdChanged()) {
this.office = groupOffice;
}
if (command.isNameChanged()) { if (command.isNameChanged()) {
this.name = command.getName(); this.name = command.getName();
} }
@@ -27,6 +27,8 @@ public class GroupCommandValidator {
baseDataValidator.reset().parameter("clientMembers").value(command.getClientMembers()).arrayNotEmpty(); baseDataValidator.reset().parameter("clientMembers").value(command.getClientMembers()).arrayNotEmpty();
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
} }
@@ -44,6 +46,10 @@ public class GroupCommandValidator {
baseDataValidator.reset().parameter("clientMembers").value(command.getClientMembers()).arrayNotEmpty(); baseDataValidator.reset().parameter("clientMembers").value(command.getClientMembers()).arrayNotEmpty();
if (command.isOfficeIdChanged()) {
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
}
if (!dataValidationErrors.isEmpty()) { if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
} }
@@ -9,9 +9,11 @@ import java.util.List;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.data.ClientLookup; import org.mifosng.platform.api.data.ClientLookup;
import org.mifosng.platform.api.data.GroupData; import org.mifosng.platform.api.data.GroupData;
import org.mifosng.platform.api.data.OfficeLookup;
import org.mifosng.platform.client.service.ClientReadPlatformService; import org.mifosng.platform.client.service.ClientReadPlatformService;
import org.mifosng.platform.exceptions.GroupNotFoundException; import org.mifosng.platform.exceptions.GroupNotFoundException;
import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource; import org.mifosng.platform.infrastructure.TenantAwareRoutingDataSource;
import org.mifosng.platform.organisation.service.OfficeReadPlatformService;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.dao.EmptyResultDataAccessException;
@@ -25,13 +27,16 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
@Autowired @Autowired
public GroupReadPlatformServiceImpl(final PlatformSecurityContext context, public GroupReadPlatformServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource, ClientReadPlatformService clientReadPlatformService) { final TenantAwareRoutingDataSource dataSource, ClientReadPlatformService clientReadPlatformService,
final OfficeReadPlatformService officeReadPlatformService) {
this.context = context; this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.clientReadPlatformService = clientReadPlatformService; this.clientReadPlatformService = clientReadPlatformService;
this.officeReadPlatformService = officeReadPlatformService;
} }
@Override @Override
@@ -70,13 +75,16 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
List<ClientLookup> allowedClients = new ArrayList<ClientLookup>( List<ClientLookup> allowedClients = new ArrayList<ClientLookup>(
this.clientReadPlatformService.retrieveAllIndividualClientsForLookup()); this.clientReadPlatformService.retrieveAllIndividualClientsForLookup());
return new GroupData(allowedClients); List<OfficeLookup> allowedOffices = new ArrayList<OfficeLookup>(officeReadPlatformService.retrieveAllOfficesForLookup());
return new GroupData(allowedClients, allowedOffices);
} }
private static final class GroupMapper implements RowMapper<GroupData> { private static final class GroupMapper implements RowMapper<GroupData> {
public String groupSchema() { public String groupSchema() {
return "g.id as id, g.external_id as externalId, g.name as name from m_group g"; return "g.office_id as officeId, o.name as officeName, g.id as id, g.external_id as externalId, " +
"g.name as name from m_group g join m_office o on o.id = g.office_id";
} }
@Override @Override
@@ -86,7 +94,10 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService {
String name = rs.getString("name"); String name = rs.getString("name");
String externalId = rs.getString("externalId"); String externalId = rs.getString("externalId");
return new GroupData(id, name, externalId); Long officeId = rs.getLong("officeId");
String officeName = rs.getString("officeName");
return new GroupData(id, officeId, officeName, name, externalId);
} }
} }
@@ -9,9 +9,12 @@ import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository; import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.exceptions.ClientNotFoundException; import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.GroupNotFoundException; import org.mifosng.platform.exceptions.GroupNotFoundException;
import org.mifosng.platform.exceptions.OfficeNotFoundException;
import org.mifosng.platform.exceptions.PlatformDataIntegrityException; import org.mifosng.platform.exceptions.PlatformDataIntegrityException;
import org.mifosng.platform.group.domain.Group; import org.mifosng.platform.group.domain.Group;
import org.mifosng.platform.group.domain.GroupRepository; import org.mifosng.platform.group.domain.GroupRepository;
import org.mifosng.platform.organisation.domain.Office;
import org.mifosng.platform.organisation.domain.OfficeRepository;
import org.mifosng.platform.security.PlatformSecurityContext; import org.mifosng.platform.security.PlatformSecurityContext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -32,12 +35,15 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
private final ClientRepository clientRepository; private final ClientRepository clientRepository;
private final OfficeRepository officeRepository;
@Autowired @Autowired
public GroupWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context, GroupRepository groupRepository, public GroupWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context, GroupRepository groupRepository,
ClientRepository clientRepository) { ClientRepository clientRepository, OfficeRepository officeRepository) {
this.context = context; this.context = context;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.officeRepository = officeRepository;
} }
@Transactional @Transactional
@@ -49,9 +55,14 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
GroupCommandValidator validator = new GroupCommandValidator(command); GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
Office groupOffice = this.officeRepository.findOne(command.getOfficeId());
if (groupOffice == null) {
throw new OfficeNotFoundException(command.getOfficeId());
}
final Set<Client> clientMembers = assembleSetOfClients(command); final Set<Client> clientMembers = assembleSetOfClients(command);
Group newGroup = Group.newGroup(command.getName(), command.getExternalId(), clientMembers); Group newGroup = Group.newGroup(groupOffice, command.getName(), command.getExternalId(), clientMembers);
this.groupRepository.saveAndFlush(newGroup); this.groupRepository.saveAndFlush(newGroup);
@@ -77,9 +88,18 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla
throw new GroupNotFoundException(command.getId()); throw new GroupNotFoundException(command.getId());
} }
Office groupOffice = null;
Long officeId = command.getOfficeId();
if (command.isOfficeIdChanged() && officeId != null) {
groupOffice = this.officeRepository.findOne(officeId);
if (groupOffice == null) {
throw new OfficeNotFoundException(command.getOfficeId());
}
}
final Set<Client> clientMembers = assembleSetOfClients(command); final Set<Client> clientMembers = assembleSetOfClients(command);
groupForUpdate.update(command, clientMembers); groupForUpdate.update(command, groupOffice, clientMembers);
groupRepository.saveAndFlush(groupForUpdate); groupRepository.saveAndFlush(groupForUpdate);