FIXED MIFOSX-19: Group formation
This commit is contained in:
@@ -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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-3
@@ -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.
|
||||||
*
|
*
|
||||||
|
|||||||
+2
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
+51
-19
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user