support soft delete of clients (includes database upgrade patch)

This commit is contained in:
Keith Woodlock
2012-07-24 16:12:19 +01:00
parent 2527563841
commit b5a4f9a206
7 changed files with 54 additions and 21 deletions
@@ -196,6 +196,7 @@ CREATE TABLE `admin_appuser_role` (
-- DDL for portfolio tables
CREATE TABLE `portfolio_client` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`is_deleted` tinyint(1) NOT NULL DEFAULT 0,
`office_id` bigint(20) NOT NULL,
`external_id` varchar(100) DEFAULT NULL,
`firstname` varchar(50) DEFAULT NULL,
@@ -0,0 +1,3 @@
-- add soft delete flag for clients
ALTER TABLE `portfolio_client` ADD COLUMN `is_deleted` tinyint(1) NOT NULL DEFAULT 0;
@@ -708,8 +708,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("username", "firstname", "lastname", "password", "repeatPassword", "email", "officeId", "notSelectedRoles", "roles")
@@ -765,8 +765,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("fromOfficeId", "toOfficeId", "transactionDate", "currencyCode", "transactionAmount", "description", "locale", "dateFormat")
@@ -792,8 +792,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("externalId", "firstname", "lastname", "clientOrBusinessName", "officeId", "joiningDate", "dateFormat")
@@ -863,8 +863,8 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
throw new InvalidJsonException();
}
Type typeOfMap = new TypeToken<Map<String, Object>>(){}.getType();
Map<String, Object> requestMap = gsonConverter.fromJson(json, typeOfMap);
Type typeOfMap = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> requestMap = gsonConverter.fromJson(json, typeOfMap);
Set<String> supportedParams = new HashSet<String>(
Arrays.asList("clientId", "productId", "externalId", "fundId",
@@ -1089,12 +1089,12 @@ public class ApiDataConversionServiceImpl implements ApiDataConversionService {
return paramValue;
}
private Long extractLongParameter(final String paramName, final Map<String, ?> requestMap, final Set<String> modifiedParameters) {
private Long extractLongParameter(final String paramName, final Map<String, String> requestMap, final Set<String> modifiedParameters) {
Long paramValue = null;
if (requestMap.containsKey(paramName)) {
String valueAsString = (String) requestMap.get(paramName);
String valueAsString = requestMap.get(paramName);
if (StringUtils.isNotBlank(valueAsString)) {
paramValue = Long.valueOf(valueAsString);
paramValue = Long.valueOf(Double.valueOf(valueAsString).longValue());
}
modifiedParameters.add(paramName);
}
@@ -42,6 +42,9 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
@Column(name = "external_id", length=100, unique=true)
private String externalId;
@Column(name = "is_deleted", nullable=false)
private boolean deleted = false;
public static Client newClient(Office clientOffice, String firstname, String lastname, LocalDate joiningDate, String externalId) {
return new Client(clientOffice, firstname, lastname, joiningDate, externalId);
}
@@ -112,4 +115,18 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
this.externalId = externalId.trim();
}
}
/**
* Delete is a <i>soft delete</i>. Updates flag on client 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;
}
}
@@ -74,7 +74,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
ClientMapper rm = new ClientMapper(offices);
String sql = "select " + rm.clientSchema() + " where c.office_id in (" + officeIdsList + ") ";
String sql = "select " + rm.clientSchema() + " where c.office_id in (" + officeIdsList + ") and c.is_deleted=0";
if (StringUtils.isNotBlank(extraCriteria))
sql += " and " + extraCriteria;
@@ -95,7 +95,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
officeReadPlatformService.retrieveAllOffices());
ClientMapper rm = new ClientMapper(offices);
String sql = "select " + rm.clientSchema() + " where c.id = ? ";
String sql = "select " + rm.clientSchema() + " where c.id = ? and c.is_deleted=0";
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {clientId});
} catch (EmptyResultDataAccessException e) {
@@ -166,6 +166,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
try {
this.context.authenticatedUser();
// Check if client exists
retrieveIndividualClient(clientId);
List<ClientLoanAccountSummaryData> pendingApprovalLoans = new ArrayList<ClientLoanAccountSummaryData>();
List<ClientLoanAccountSummaryData> awaitingDisbursalLoans = new ArrayList<ClientLoanAccountSummaryData>();
@@ -241,6 +244,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
try {
context.authenticatedUser();
// Check if client exists
retrieveIndividualClient(clientId);
// FIXME - use join on sql query to fetch user information for note
// rather than fetching users?
@@ -262,6 +268,9 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public Collection<NoteData> retrieveAllClientNotes(Long clientId) {
context.authenticatedUser();
// Check if client exists
retrieveIndividualClient(clientId);
// FIXME - use join on sql query to fetch user information for note
// rather than fetching users?
@@ -20,5 +20,5 @@ public interface ClientWritePlatformService {
EntityIdentifier updateNote(NoteCommand command);
@PreAuthorize(value = "hasAnyRole('PORTFOLIO_MANAGEMENT_SUPER_USER_ROLE', 'CAN_DELETE_CLIENT_ROLE')")
void deleteClient(Long clientId);
EntityIdentifier deleteClient(Long clientId);
}
@@ -1,7 +1,5 @@
package org.mifosng.platform.client.service;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.mifosng.platform.api.commands.ClientCommand;
import org.mifosng.platform.api.commands.NoteCommand;
@@ -39,12 +37,17 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public void deleteClient(final Long clientId) {
public EntityIdentifier deleteClient(final Long clientId) {
List<Note> relatedNotes = this.noteRepository.findByClientId(clientId);
this.noteRepository.deleteInBatch(relatedNotes);
Client client = this.clientRepository.findOne(clientId);
if (client == null || client.isDeleted()) {
throw new ClientNotFoundException(clientId);
}
this.clientRepository.delete(clientId);
client.delete();
this.clientRepository.save(client);
return new EntityIdentifier(client.getId());
}
@Transactional
@@ -101,7 +104,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
}
Client clientForUpdate = this.clientRepository.findOne(command.getId());
if (clientForUpdate == null) {
if (clientForUpdate == null || clientForUpdate.isDeleted()) {
throw new ClientNotFoundException(command.getId());
}
clientForUpdate.update(clientOffice, firstname, lastname, command.getExternalId(), command.getJoiningDate());