diff --git a/mifosng-db/patches/patch-0004_Add_soft_deleted_flag_for_group.sql b/mifosng-db/patches/patch-0004_Add_soft_deleted_flag_for_group.sql new file mode 100644 index 000000000..1c616ebc8 --- /dev/null +++ b/mifosng-db/patches/patch-0004_Add_soft_deleted_flag_for_group.sql @@ -0,0 +1 @@ +ALTER TABLE `portfolio_group` ADD COLUMN `is_deleted` tinyint(1) NOT NULL DEFAULT 0 AFTER `external_id`; diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java b/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java index 3b51f7dff..05a0cdc5b 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/api/GroupsApiResource.java @@ -6,6 +6,7 @@ import java.util.HashSet; import java.util.Set; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -108,5 +109,16 @@ public class GroupsApiResource { return Response.ok().entity(entityIdentifier).build(); } + + @DELETE + @Path("{groupId}") + @Consumes({ MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON }) + public Response deleteGroup(@PathParam("groupId") final Long groupId, @Context final UriInfo uriInfo){ + + EntityIdentifier entityIdentifier = this.groupWritePlatformService.deleteGroup(groupId); + + return Response.ok().entity(entityIdentifier).build(); + } } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java index 2c5e63554..3a38a4cb4 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/domain/Group.java @@ -20,6 +20,9 @@ public class Group extends AbstractAuditableCustom { @Column(name = "external_id", length = 100, unique = true) private String externalId; + @Column(name = "is_deleted", nullable=false) + private boolean deleted = false; + public Group() { this.name = null; this.externalId = null; @@ -51,4 +54,18 @@ public class Group extends AbstractAuditableCustom { this.name = command.getName(); } } + + /** + * Delete is a soft delete. Updates flag on group so it wont appear in query/report results. + * + * Any fields with unique constraints and prepended with id of record. + */ + public void delete() { + this.deleted = true; + this.externalId = this.getId() + "_" + this.externalId; + } + + public boolean isDeleted() { + return deleted; + } } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java index 448de8726..bb43e610d 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupReadPlatformServiceImpl.java @@ -34,7 +34,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { GroupMapper rm = new GroupMapper(); - String sql = "select " + rm.groupSchema(); + String sql = "select " + rm.groupSchema() + " where g.is_deleted=0"; return this.jdbcTemplate.query(sql, rm, new Object[] {}); } @@ -47,7 +47,7 @@ public class GroupReadPlatformServiceImpl implements GroupReadPlatformService { GroupMapper rm = new GroupMapper(); - String sql = "select " + rm.groupSchema() + " where g.id = ?"; + String sql = "select " + rm.groupSchema() + " where g.id = ? and g.is_deleted=0"; return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {groupId}); } catch (EmptyResultDataAccessException e){ diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformService.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformService.java index b489af5b9..ba0367cfe 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformService.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformService.java @@ -12,4 +12,7 @@ public interface GroupWritePlatformService { @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')") EntityIdentifier updateGroup(GroupCommand command); + @PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE')") + EntityIdentifier deleteGroup(Long groupId); + } diff --git a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java index 9025052e4..d7f8a0f1e 100644 --- a/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosng/platform/group/service/GroupWritePlatformServiceJpaRepositoryImpl.java @@ -7,6 +7,7 @@ import org.mifosng.platform.group.domain.Group; import org.mifosng.platform.group.domain.GroupRepository; import org.mifosng.platform.security.PlatformSecurityContext; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -49,7 +50,7 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla validator.validateForUpdate(); Group groupForUpdate = this.groupRepository.findOne(command.getId()); - if (groupForUpdate == null){ + if (groupForUpdate == null || groupForUpdate.isDeleted()){ throw new GroupNotFoundException(command.getId()); } groupForUpdate.update(command); @@ -59,4 +60,20 @@ public class GroupWritePlatformServiceJpaRepositoryImpl implements GroupWritePla return new EntityIdentifier(groupForUpdate.getId()); } + @Transactional + @Override + public EntityIdentifier deleteGroup(Long groupId) { + + context.authenticatedUser(); + + Group groupForDelete = this.groupRepository.findOne(groupId); + if (groupForDelete == null || groupForDelete.isDeleted()){ + throw new GroupNotFoundException(groupId); + } + groupForDelete.delete(); + this.groupRepository.save(groupForDelete); + + return new EntityIdentifier(groupId); + } + }