FIXED MIFOSX-19: Group formation

This commit is contained in:
Michal Dudzinski
2012-08-08 11:02:49 +02:00
parent c6dd2f55f8
commit eff8838f5b
6 changed files with 117 additions and 27 deletions
@@ -0,0 +1,8 @@
CREATE TABLE `portfolio_group_client` (
`group_id` bigint(20) NOT NULL,
`client_id` bigint(20) NOT NULL,
PRIMARY KEY (`group_id`,`client_id`),
FOREIGN KEY (`group_id`) REFERENCES `portfolio_group` (`id`),
FOREIGN KEY (`client_id`) REFERENCES `portfolio_client` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
@@ -7,13 +7,15 @@ 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 String[] clientMembers;
private final Set<String> modifiedParameters; private final Set<String> modifiedParameters;
public GroupCommand(Set<String> modifiedParameters, final Long id, String externalId, String name) { public GroupCommand(Set<String> modifiedParameters, final Long id, String externalId, String name, String[] clientMembers) {
this.id = id; this.id = id;
this.externalId = externalId; this.externalId = externalId;
this.name = name; this.name = name;
this.clientMembers = clientMembers;
this.modifiedParameters = modifiedParameters; this.modifiedParameters = modifiedParameters;
} }
@@ -29,6 +31,10 @@ public class GroupCommand {
return id; return id;
} }
public String[] getClientMembers() {
return clientMembers;
}
public boolean isNameChanged() { public boolean isNameChanged() {
return this.modifiedParameters.contains("name"); return this.modifiedParameters.contains("name");
} }
@@ -37,4 +43,8 @@ public class GroupCommand {
return this.modifiedParameters.contains("externalId"); return this.modifiedParameters.contains("externalId");
} }
public boolean isClientMembersChanged() {
return this.modifiedParameters.contains("clientMembers");
}
} }
@@ -859,11 +859,11 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
throw new InvalidJsonException(); throw new InvalidJsonException();
} }
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType(); Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
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") Arrays.asList("name", "externalId", "clientMembers")
); );
checkForUnsupportedParameters(requestMap, supportedParams); checkForUnsupportedParameters(requestMap, supportedParams);
@@ -873,7 +873,25 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
String externalId = extractStringParameter("externalId", requestMap, modifiedParameters); String externalId = extractStringParameter("externalId", requestMap, modifiedParameters);
String name = extractStringParameter("name", requestMap, modifiedParameters); String name = extractStringParameter("name", requestMap, modifiedParameters);
return new GroupCommand(modifiedParameters, resourceIdentifier, externalId, name); // check array
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, clientMembers);
} }
@Override @Override
@@ -1,11 +1,18 @@
package org.mifosng.platform.group.domain; package org.mifosng.platform.group.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
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.infrastructure.AbstractAuditableCustom; import org.mifosng.platform.infrastructure.AbstractAuditableCustom;
import org.mifosng.platform.user.domain.AppUser; import org.mifosng.platform.user.domain.AppUser;
@@ -13,7 +20,6 @@ import org.mifosng.platform.user.domain.AppUser;
@Table(name = "portfolio_group") @Table(name = "portfolio_group")
public class Group extends AbstractAuditableCustom<AppUser, Long> { public class Group extends AbstractAuditableCustom<AppUser, Long> {
@SuppressWarnings("unused")
@Column(name = "name", length = 100) @Column(name = "name", length = 100)
private String name; private String name;
@@ -23,16 +29,23 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "is_deleted", nullable=false) @Column(name = "is_deleted", nullable=false)
private boolean deleted = false; private boolean deleted = false;
@ManyToMany
@JoinTable(name = "portfolio_group_client",
joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "client_id"))
private Set<Client> clientMembers;
public Group() { public Group() {
this.name = null; this.name = null;
this.externalId = null; this.externalId = null;
this.clientMembers = new HashSet<Client>();
} }
public static Group newGroup(String name, String externalId){ public static Group newGroup(String name, String externalId, Set<Client> clientMembers){
return new Group(name, externalId); return new Group(name, externalId, clientMembers);
} }
public Group(String name, String externalId) { public Group(String name, String externalId, Set<Client> clientMembers) {
if (StringUtils.isNotBlank(name)) { if (StringUtils.isNotBlank(name)) {
this.name = name.trim(); this.name = name.trim();
} else { } else {
@@ -43,6 +56,9 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
} else { } else {
this.externalId = null; this.externalId = null;
} }
if (clientMembers != null){
this.clientMembers = clientMembers;
}
} }
public void update(GroupCommand command) { public void update(GroupCommand command) {
@@ -55,6 +71,10 @@ public class Group extends AbstractAuditableCustom<AppUser, Long> {
} }
} }
public void addClientMember(final Client member){
this.clientMembers.add(member);
}
/** /**
* Delete is a <i>soft delete</i>. Updates flag on group so it wont appear in query/report results. * Delete is a <i>soft delete</i>. Updates flag on group so it wont appear in query/report results.
* *
@@ -25,6 +25,8 @@ public class GroupCommandValidator {
baseDataValidator.reset().parameter("name").value(command.getName()).notBlank(); baseDataValidator.reset().parameter("name").value(command.getName()).notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100); baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().parameter("clientMembers").value(command.getClientMembers()).ignoreIfNull().arrayNotEmpty();
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);
} }
@@ -1,7 +1,13 @@
package org.mifosng.platform.group.service; package org.mifosng.platform.group.service;
import java.util.HashSet;
import java.util.Set;
import org.mifosng.platform.api.commands.GroupCommand; import org.mifosng.platform.api.commands.GroupCommand;
import org.mifosng.platform.api.data.EntityIdentifier; import org.mifosng.platform.api.data.EntityIdentifier;
import org.mifosng.platform.client.domain.Client;
import org.mifosng.platform.client.domain.ClientRepository;
import org.mifosng.platform.exceptions.ClientNotFoundException;
import org.mifosng.platform.exceptions.GroupNotFoundException; import org.mifosng.platform.exceptions.GroupNotFoundException;
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;
@@ -9,70 +15,96 @@ import org.mifosng.platform.security.PlatformSecurityContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
@Service @Service
public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePlatformService { public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePlatformService {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final GroupRepository groupRepository; private final GroupRepository groupRepository;
private final ClientRepository clientRepository;
@Autowired @Autowired
public GroupWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context, GroupRepository groupRepository) { public GroupWritePlatformServiceJpaRepositoryImpl(PlatformSecurityContext context, GroupRepository groupRepository,
ClientRepository clientRepository) {
this.context = context; this.context = context;
this.groupRepository = groupRepository; this.groupRepository = groupRepository;
this.clientRepository = clientRepository;
} }
@Transactional @Transactional
@Override @Override
public EntityIdentifier createGroup(GroupCommand command) { public EntityIdentifier createGroup(GroupCommand command) {
this.context.authenticatedUser(); this.context.authenticatedUser();
GroupCommandValidator validator = new GroupCommandValidator(command); GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForCreate(); validator.validateForCreate();
Group newGroup = Group.newGroup(command.getName(), command.getExternalId()); final Set<Client> clientMembers = assembleSetOfClients(command);
Group newGroup = Group.newGroup(command.getName(), command.getExternalId(), clientMembers);
this.groupRepository.save(newGroup); this.groupRepository.save(newGroup);
return new EntityIdentifier(newGroup.getId()); return new EntityIdentifier(newGroup.getId());
} }
@Transactional @Transactional
@Override @Override
public EntityIdentifier updateGroup(GroupCommand command) { public EntityIdentifier updateGroup(GroupCommand command) {
context.authenticatedUser(); context.authenticatedUser();
GroupCommandValidator validator = new GroupCommandValidator(command); GroupCommandValidator validator = new GroupCommandValidator(command);
validator.validateForUpdate(); validator.validateForUpdate();
Group groupForUpdate = this.groupRepository.findOne(command.getId()); Group groupForUpdate = this.groupRepository.findOne(command.getId());
if (groupForUpdate == null || groupForUpdate.isDeleted()){ if (groupForUpdate == null || groupForUpdate.isDeleted()) {
throw new GroupNotFoundException(command.getId()); throw new GroupNotFoundException(command.getId());
} }
groupForUpdate.update(command); groupForUpdate.update(command);
groupRepository.save(groupForUpdate); groupRepository.save(groupForUpdate);
return new EntityIdentifier(groupForUpdate.getId()); return new EntityIdentifier(groupForUpdate.getId());
} }
@Transactional @Transactional
@Override @Override
public EntityIdentifier deleteGroup(Long groupId) { public EntityIdentifier deleteGroup(Long groupId) {
context.authenticatedUser(); context.authenticatedUser();
Group groupForDelete = this.groupRepository.findOne(groupId); Group groupForDelete = this.groupRepository.findOne(groupId);
if (groupForDelete == null || groupForDelete.isDeleted()){ if (groupForDelete == null || groupForDelete.isDeleted()) {
throw new GroupNotFoundException(groupId); throw new GroupNotFoundException(groupId);
} }
groupForDelete.delete(); groupForDelete.delete();
this.groupRepository.save(groupForDelete); this.groupRepository.save(groupForDelete);
return new EntityIdentifier(groupId); return new EntityIdentifier(groupId);
} }
private Set<Client> assembleSetOfClients(final GroupCommand command) {
Set<Client> clientMembers = new HashSet<Client>();
String[] clientMembersArray = command.getClientMembers();
if (command.isClientMembersChanged() && !ObjectUtils.isEmpty(clientMembersArray)) {
for (String clientId : clientMembersArray) {
Long id = Long.valueOf(clientId);
Client client = this.clientRepository.findOne(id);
if (client == null) {
throw new ClientNotFoundException(id);
}
clientMembers.add(client);
}
}
return clientMembers;
}
} }