MIFOSX-97: about turn on implementation of command pattern to support audit.

This commit is contained in:
Keith Woodlock
2012-12-06 14:20:44 +00:00
parent add6708ab0
commit cb6ea0ae63
31 changed files with 551 additions and 769 deletions
@@ -0,0 +1,2 @@
ALTER TABLE `m_client`
CHANGE COLUMN `joining_date` `joined_date` DATE NULL DEFAULT NULL;
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand; import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.portfolio.charge.serialization.ChargeCommandFromCommandJsonDeserializer; import org.mifosplatform.portfolio.charge.serialization.ChargeCommandFromCommandJsonDeserializer;
@@ -19,16 +18,14 @@ import org.springframework.stereotype.Service;
public class ChargeDefinitionCommandHandler implements CommandSourceHandler { public class ChargeDefinitionCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ChargeWritePlatformService writePlatformService; private final ChargeWritePlatformService writePlatformService;
@Autowired @Autowired
public ChargeDefinitionCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public ChargeDefinitionCommandHandler(final PlatformSecurityContext context,
final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ChargeWritePlatformService writePlatformService) { final ChargeWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -55,13 +52,7 @@ public class ChargeDefinitionCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateCharge(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ChargeDefinitionCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateCharge(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -5,32 +5,34 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromCommandJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
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 com.google.gson.JsonElement;
@Service @Service
public class ClientCommandHandler implements CommandSourceHandler { public class ClientCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ClientWritePlatformService clientWritePlatformService; private final ClientWritePlatformService clientWritePlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
@Autowired @Autowired
public ClientCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public ClientCommandHandler(final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final ClientWritePlatformService clientWritePlatformService) { final ClientWritePlatformService clientWritePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.clientWritePlatformService = clientWritePlatformService; this.clientWritePlatformService = clientWritePlatformService;
} }
@@ -40,8 +42,8 @@ public class ClientCommandHandler implements CommandSourceHandler {
final AppUser maker = context.authenticatedUser(); final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate(); final LocalDate asToday = new LocalDate();
final ClientCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSource.resourceId(), final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
commandSource.json()); final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy(); CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null; Long newResourceId = null;
@@ -56,22 +58,19 @@ public class ClientCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(commandSource.resourceId(), command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(changesOnly);
newResourceId = result.getEntityId(); newResourceId = result.getEntityId();
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design // swallow this rollback transaction by design
} }
} else if (commandSource.isDelete()) { } else if (commandSource.isDelete()) {
try { try {
EntityIdentifier result = this.clientWritePlatformService.deleteClient(command); EntityIdentifier result = this.clientWritePlatformService.deleteClient(commandSource.resourceId(), command);
newResourceId = result.getEntityId(); newResourceId = result.getEntityId();
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -87,8 +86,8 @@ public class ClientCommandHandler implements CommandSourceHandler {
final AppUser checker = context.authenticatedUser(); final AppUser checker = context.authenticatedUser();
final ClientCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(), final JsonElement parsedCommand = fromApiJsonHelper.parse(commandSourceResult.json());
commandSourceResult.json(), true); final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, fromApiJsonHelper);
if (commandSourceResult.isCreate()) { if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
@@ -103,14 +102,14 @@ public class ClientCommandHandler implements CommandSourceHandler {
"UPDATE_CLIENT_CHECKER"); "UPDATE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT_CHECKER", allowedPermissions); context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT_CHECKER", allowedPermissions);
this.clientWritePlatformService.updateClientDetails(command); this.clientWritePlatformService.updateClientDetails(commandSourceResult.resourceId(), command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { } else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"DELETE_CLIENT_CHECKER"); "DELETE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT_CHECKER", allowedPermissions); context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT_CHECKER", allowedPermissions);
this.clientWritePlatformService.deleteClient(command); this.clientWritePlatformService.deleteClient(commandSourceResult.resourceId(), command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} }
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromCommandJsonDeserializer; import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromCommandJsonDeserializer;
@@ -19,16 +18,14 @@ import org.springframework.stereotype.Service;
public class ClientIdentifierCommandHandler implements CommandSourceHandler { public class ClientIdentifierCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientWritePlatformService clientWritePlatformService; private final ClientWritePlatformService clientWritePlatformService;
private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired @Autowired
public ClientIdentifierCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public ClientIdentifierCommandHandler(final PlatformSecurityContext context,
final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) { final ClientWritePlatformService clientWritePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService; this.clientWritePlatformService = clientWritePlatformService;
} }
@@ -53,14 +50,7 @@ public class ClientIdentifierCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.clientWritePlatformService.updateClientIdentifier(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientIdentifierCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.clientWritePlatformService.updateClientIdentifier(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design // swallow this rollback transaction by design
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand; import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
@@ -21,16 +20,14 @@ import org.springframework.stereotype.Service;
public class ClientNoteCommandHandler implements CommandSourceHandler { public class ClientNoteCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientWritePlatformService clientWritePlatformService; private final ClientWritePlatformService clientWritePlatformService;
private final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired @Autowired
public ClientNoteCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public ClientNoteCommandHandler(final PlatformSecurityContext context,
final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) { final ClientWritePlatformService clientWritePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService; this.clientWritePlatformService = clientWritePlatformService;
} }
@@ -55,21 +52,12 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.clientWritePlatformService.updateNote(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientNoteCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.clientWritePlatformService.updateNote(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design // swallow this rollback transaction by design
} }
} else if (commandSource.isDelete()) { } else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
throw new UnsupportedCommandException(commandSource.commandName());
}
return commandSourceResult; return commandSourceResult;
} }
@@ -79,8 +67,8 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
final AppUser checker = context.authenticatedUser(); final AppUser checker = context.authenticatedUser();
final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson( final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(),
commandSourceResult.resourceId(), commandSourceResult.json(), true); commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) { if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENTNOTE_CHECKER"); "CREATE_CLIENTNOTE_CHECKER");
@@ -96,9 +84,7 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
this.clientWritePlatformService.updateNote(command); this.clientWritePlatformService.updateNote(command);
commandSourceResult.markAsChecked(checker, new LocalDate()); commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) { } else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
throw new UnsupportedCommandException(commandSourceResult.commandName());
}
return commandSourceResult; return commandSourceResult;
} }
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.codes.command.CodeCommand; import org.mifosplatform.infrastructure.codes.command.CodeCommand;
import org.mifosplatform.infrastructure.codes.serialization.CodeCommandFromCommandJsonDeserializer; import org.mifosplatform.infrastructure.codes.serialization.CodeCommandFromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService; import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
@@ -19,15 +18,13 @@ import org.springframework.stereotype.Service;
public class CodeCommandHandler implements CommandSourceHandler { public class CodeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer; private final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final CodeWritePlatformService writePlatformService; private final CodeWritePlatformService writePlatformService;
@Autowired @Autowired
public CodeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public CodeCommandHandler(final PlatformSecurityContext context,
final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final CodeWritePlatformService writePlatformService) { final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final CodeWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer; this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -53,12 +50,7 @@ public class CodeCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateCode(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final CodeCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateCode(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand; import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromCommandJsonDeserializer; import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromCommandJsonDeserializer;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class CurrencyCommandHandler implements CommandSourceHandler { public class CurrencyCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer; private final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer;
private final CurrencyWritePlatformService writePlatformService; private final CurrencyWritePlatformService writePlatformService;
@Autowired @Autowired
public CurrencyCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public CurrencyCommandHandler(final PlatformSecurityContext context,
final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer, final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer,
final CurrencyWritePlatformService writePlatformService) { final CurrencyWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer; this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -46,13 +43,8 @@ public class CurrencyCommandHandler implements CommandSourceHandler {
throw new UnsupportedCommandException(commandSource.commandName()); throw new UnsupportedCommandException(commandSource.commandName());
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), final CurrencyCommand command = this.fromApiJsonDeserializer.commandFromCommandJson(commandSource.json());
commandSource.resourceId(), commandSource.json()); this.writePlatformService.updateAllowedCurrencies(command);
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final CurrencyCommand changesOnly = this.fromApiJsonDeserializer.commandFromCommandJson(jsonOfChangesOnly);
this.writePlatformService.updateAllowedCurrencies(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design // swallow this rollback transaction by design
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.portfolio.fund.command.FundCommand; import org.mifosplatform.portfolio.fund.command.FundCommand;
@@ -20,15 +19,13 @@ import org.springframework.stereotype.Service;
public class FundCommandHandler implements CommandSourceHandler { public class FundCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer; private final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final FundWritePlatformService writePlatformService; private final FundWritePlatformService writePlatformService;
@Autowired @Autowired
public FundCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public FundCommandHandler(final PlatformSecurityContext context,
final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final FundWritePlatformService writePlatformService) { final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final FundWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer; this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -56,13 +53,7 @@ public class FundCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateFund(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final FundCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateFund(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
@@ -21,16 +20,14 @@ import org.springframework.stereotype.Service;
public class LoanProductCommandHandler implements CommandSourceHandler { public class LoanProductCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final LoanProductWritePlatformService writePlatformService; private final LoanProductWritePlatformService writePlatformService;
@Autowired @Autowired
public LoanProductCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public LoanProductCommandHandler(final PlatformSecurityContext context,
final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final LoanProductWritePlatformService writePlatformService) { final LoanProductWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -55,13 +52,7 @@ public class LoanProductCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateLoanProduct(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final LoanProductCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateLoanProduct(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.command.OfficeCommand; import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromCommandJsonDeserializer; import org.mifosplatform.organisation.office.serialization.OfficeCommandFromCommandJsonDeserializer;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class OfficeCommandHandler implements CommandSourceHandler { public class OfficeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final OfficeWritePlatformService writePlatformService; private final OfficeWritePlatformService writePlatformService;
@Autowired @Autowired
public OfficeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public OfficeCommandHandler(final PlatformSecurityContext context,
final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final OfficeWritePlatformService writePlatformService) { final OfficeWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -57,13 +54,7 @@ public class OfficeCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateOffice(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final OfficeCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateOffice(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.PermissionsCommand; import org.mifosplatform.useradministration.command.PermissionsCommand;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class PermissionsCommandHandler implements CommandSourceHandler { public class PermissionsCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final PermissionWritePlatformService permissionWritePlatformService; private final PermissionWritePlatformService permissionWritePlatformService;
@Autowired @Autowired
public PermissionsCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public PermissionsCommandHandler(final PlatformSecurityContext context,
final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final PermissionWritePlatformService permissionWritePlatformService) { final PermissionWritePlatformService permissionWritePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.permissionWritePlatformService = permissionWritePlatformService; this.permissionWritePlatformService = permissionWritePlatformService;
} }
@@ -44,14 +41,10 @@ public class PermissionsCommandHandler implements CommandSourceHandler {
if (commandSource.isUpdate()) { if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), final PermissionsCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), commandSource.json()); commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final PermissionsCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson( this.permissionWritePlatformService.updateMakerCheckerPermissions(command);
commandSource.resourceId(), jsonOfChangesOnly);
this.permissionWritePlatformService.updateMakerCheckerPermissions(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.RoleCommand; import org.mifosplatform.useradministration.command.RoleCommand;
@@ -22,18 +21,16 @@ import org.springframework.stereotype.Service;
public class RoleCommandHandler implements CommandSourceHandler { public class RoleCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final RoleWritePlatformService writePlatformService; private final RoleWritePlatformService writePlatformService;
private final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer; private final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer;
@Autowired @Autowired
public RoleCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public RoleCommandHandler(final PlatformSecurityContext context,
final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer, final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer, final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer,
final RoleWritePlatformService writePlatformService) { final RoleWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.permissionsCommandFromCommandJsonDeserializer = permissionsCommandFromCommandJsonDeserializer; this.permissionsCommandFromCommandJsonDeserializer = permissionsCommandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
@@ -64,14 +61,10 @@ public class RoleCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), final RoleCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSource.resourceId(), commandSource.json()); commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final RoleCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId, newResourceId = this.writePlatformService.updateRole(command);
jsonOfChangesOnly);
newResourceId = this.writePlatformService.updateRole(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -79,14 +72,10 @@ public class RoleCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdateRolePermissions()) { } else if (commandSource.isUpdateRolePermissions()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), final RolePermissionCommand command = this.permissionsCommandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), commandSource.json()); resourceId, commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final RolePermissionCommand changesOnly = this.permissionsCommandFromCommandJsonDeserializer.commandFromCommandJson( newResourceId = this.writePlatformService.updateRolePermissions(command);
resourceId, jsonOfChangesOnly);
newResourceId = this.writePlatformService.updateRolePermissions(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException; import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.staff.command.StaffCommand; import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromCommandJsonDeserializer; import org.mifosplatform.organisation.staff.serialization.StaffCommandFromCommandJsonDeserializer;
@@ -20,17 +19,13 @@ import org.springframework.stereotype.Service;
public class StaffCommandHandler implements CommandSourceHandler { public class StaffCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer; private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final StaffWritePlatformService writePlatformService; private final StaffWritePlatformService writePlatformService;
@Autowired @Autowired
public StaffCommandHandler(final PlatformSecurityContext context, public StaffCommandHandler(final PlatformSecurityContext context,
final ChangeDetectionService changeDetectionService, final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final StaffWritePlatformService writePlatformService) {
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer,
final StaffWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer; this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -56,13 +51,7 @@ public class StaffCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(), this.writePlatformService.updateStaff(command);
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final StaffCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateStaff(changesOnly);
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) { } catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource; import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException; import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.UserCommand; import org.mifosplatform.useradministration.command.UserCommand;
@@ -19,15 +18,13 @@ import org.springframework.stereotype.Service;
public class UserCommandHandler implements CommandSourceHandler { public class UserCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer; private final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final AppUserWritePlatformService writePlatformService; private final AppUserWritePlatformService writePlatformService;
@Autowired @Autowired
public UserCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService, public UserCommandHandler(final PlatformSecurityContext context,
final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final AppUserWritePlatformService writePlatformService) { final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final AppUserWritePlatformService writePlatformService) {
this.context = context; this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer; this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService; this.writePlatformService = writePlatformService;
} }
@@ -52,15 +49,10 @@ public class UserCommandHandler implements CommandSourceHandler {
} }
} else if (commandSource.isUpdate()) { } else if (commandSource.isUpdate()) {
try { try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final UserCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
if (maker.hasIdOf(command.getId())) { if (maker.hasIdOf(command.getId())) {
this.writePlatformService.updateUsersOwnAccountDetails(changesOnly); this.writePlatformService.updateUsersOwnAccountDetails(command);
} else { } else {
this.writePlatformService.updateUser(changesOnly); this.writePlatformService.updateUser(command);
} }
commandSourceResult.markAsChecked(maker, asToday); commandSourceResult.markAsChecked(maker, asToday);
@@ -1,7 +0,0 @@
package org.mifosplatform.commands.service;
public interface ChangeDetectionService {
String detectChangesOnUpdate(String resourceName, Long resourceId, String commandSerializedAsJson);
}
@@ -1,60 +0,0 @@
package org.mifosplatform.commands.service;
import org.mifosplatform.infrastructure.core.api.PortfolioApiDataConversionService;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.DefaultToApiJsonSerializer;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ChangeDetectionServiceJdbc implements ChangeDetectionService {
private final static Logger logger = LoggerFactory.getLogger(ChangeDetectionServiceJdbc.class);
private final PortfolioApiDataConversionService apiDataConversionService;
private final ClientReadPlatformService clientReadPlatformService;
private final CommandSerializer commandSerializerService;
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
@Autowired
public ChangeDetectionServiceJdbc(final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer,
final PortfolioApiDataConversionService apiDataConversionService, final CommandSerializer commandSerializerService,
final ClientReadPlatformService clientReadPlatformService) {
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiDataConversionService = apiDataConversionService;
this.commandSerializerService = commandSerializerService;
this.clientReadPlatformService = clientReadPlatformService;
}
@Override
public String detectChangesOnUpdate(final String resourceName, final Long resourceId, final String commandSerializedAsJson) {
logger.info(resourceName + ": ID: " + resourceId + " JSON: " + commandSerializedAsJson);
String changesOnlyJson = "";
if ("clients".equalsIgnoreCase(resourceName)) {
// FIXME - KW/JW - this change detection code for update of clients
// using ClientCommand can re placed when more suitable sql version
// is
// implemented.
final ClientData originalClient = this.clientReadPlatformService.retrieveIndividualClient(resourceId);
final ClientData changedClient = this.apiDataConversionService.convertInternalJsonFormatToClientDataChange(resourceId,
commandSerializedAsJson);
final String baseJson = this.toApiJsonSerializer.serialize(originalClient);
final String workingJson = this.toApiJsonSerializer.serialize(changedClient);
final ClientCommand changesOnly = this.apiDataConversionService.detectChanges(resourceId, baseJson, workingJson);
changesOnlyJson = this.commandSerializerService.serializeCommandToJson(changesOnly);
} else {
changesOnlyJson = commandSerializedAsJson;
}
return changesOnlyJson;
}
}
@@ -0,0 +1,129 @@
package org.mifosplatform.infrastructure.core.api;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import com.google.gson.JsonElement;
/**
* Represents JSON based command.
*/
public final class JsonCommand {
private final String jsonCommand;
private final transient boolean approvedByChecker;
private final JsonElement parsedCommand;
private final FromJsonHelper fromApiJsonHelper;
public static JsonCommand from(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper) {
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, false);
}
public static JsonCommand withMakerCheckerApproval(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper) {
return new JsonCommand(jsonCommand, parsedCommand, fromApiJsonHelper, true);
}
public JsonCommand(final String jsonCommand, final JsonElement parsedCommand, final FromJsonHelper fromApiJsonHelper, final boolean approvedByChecker) {
this.jsonCommand = jsonCommand;
this.parsedCommand = parsedCommand;
this.fromApiJsonHelper = fromApiJsonHelper;
this.approvedByChecker = approvedByChecker;
}
public String json() {
return this.jsonCommand;
}
public boolean isApprovedByChecker() {
return this.approvedByChecker;
}
private boolean differenceExists(LocalDate baseValue, LocalDate workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean differenceExists(final String baseValue, final String workingCopyValue) {
boolean differenceExists = false;
if (StringUtils.isNotBlank(baseValue)) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = StringUtils.isNotBlank(workingCopyValue);
}
return differenceExists;
}
private boolean differenceExists(final Long baseValue, final Long workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean parameterExists(final String parameterName) {
return this.fromApiJsonHelper.parameterExists(parameterName, parsedCommand);
}
public String dateFormat() {
return stringValueOfParameterNamed("dateFormat");
}
public String locale() {
return stringValueOfParameterNamed("locale");
}
public boolean isChangeInLongParameterNamed(final String parameterName, final Long existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final Long workingValue = longValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public Long longValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractLongNamed(parameterName, parsedCommand);
}
public boolean isChangeInLocalDateParameterNamed(final String parameterName, final LocalDate existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final LocalDate workingValue = localDateValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public LocalDate localDateValueOfParameterNamed(final String parameterName) {
return this.fromApiJsonHelper.extractLocalDateNamed(parameterName, parsedCommand);
}
public boolean isChangeInStringParameterNamed(final String parameterName, final String existingValue) {
boolean isChanged = false;
if (parameterExists(parameterName)) {
final String workingValue = stringValueOfParameterNamed(parameterName);
isChanged = differenceExists(existingValue, workingValue);
}
return isChanged;
}
public String stringValueOfParameterNamed(final String parameterName) {
final String value = this.fromApiJsonHelper.extractStringNamed(parameterName, parsedCommand);
return StringUtils.defaultIfEmpty(value, "");
}
}
@@ -1,7 +1,6 @@
package org.mifosplatform.infrastructure.core.api; package org.mifosplatform.infrastructure.core.api;
import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand; import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerCommand;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.NoteCommand; import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.group.command.GroupCommand; import org.mifosplatform.portfolio.group.command.GroupCommand;
@@ -28,8 +27,6 @@ public interface PortfolioApiDataConversionService {
ClientData convertInternalJsonFormatToClientDataChange(Long clientId, String json); ClientData convertInternalJsonFormatToClientDataChange(Long clientId, String json);
ClientCommand detectChanges(Long resourceId, String baseJson, String workingJson);
GroupCommand convertJsonToGroupCommand(Long resourceIdentifier, String json); GroupCommand convertJsonToGroupCommand(Long resourceIdentifier, String json);
LoanApplicationCommand convertApiRequestJsonToLoanApplicationCommand(Long resourceIdentifier, String json); LoanApplicationCommand convertApiRequestJsonToLoanApplicationCommand(Long resourceIdentifier, String json);
@@ -26,7 +26,7 @@ import org.mifosplatform.organisation.staff.command.BulkTransferLoanOfficerComma
import org.mifosplatform.portfolio.client.command.ClientCommand; import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.NoteCommand; import org.mifosplatform.portfolio.client.command.NoteCommand;
import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromCommandJsonDeserializer; import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.group.command.GroupCommand; import org.mifosplatform.portfolio.group.command.GroupCommand;
import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand; import org.mifosplatform.portfolio.loanaccount.command.AdjustLoanTransactionCommand;
import org.mifosplatform.portfolio.loanaccount.command.LoanApplicationCommand; import org.mifosplatform.portfolio.loanaccount.command.LoanApplicationCommand;
@@ -61,11 +61,11 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
*/ */
private final Gson gsonConverter; private final Gson gsonConverter;
private final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer; private final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer;
@Autowired @Autowired
public PortfolioApiDataConversionServiceImpl(final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer) { public PortfolioApiDataConversionServiceImpl(final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer) {
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer; this.clientCommandFromApiJsonDeserializer = clientCommandFromApiJsonDeserializer;
this.gsonConverter = new Gson(); this.gsonConverter = new Gson();
} }
@@ -131,125 +131,10 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
return new BulkTransferLoanOfficerCommand(fromLoanOfficerId, toLoanOfficerId, assignmentDate, loans); return new BulkTransferLoanOfficerCommand(fromLoanOfficerId, toLoanOfficerId, assignmentDate, loans);
} }
@Override
public ClientCommand detectChanges(final Long resourceIdentifier, final String baseJson, final String workingJson) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
final Map<String, Object> workingVersion = gsonConverter.fromJson(workingJson, typeOfMap);
final Set<String> workingParameters = workingVersion.keySet();
final JsonParser parser = new JsonParser();
final JsonElement baseElement = parser.parse(baseJson);
final JsonElement workingElement = parser.parse(workingJson);
final JsonParserHelper helper = new JsonParserHelper();
final Set<String> ignoreParameters = new HashSet<String>();
final Set<String> parametersPassedInRequest = new HashSet<String>();
Long officeId = null;
String externalId = null;
String firstname = null;
String lastname = null;
String clientOrBusinessName = null;
LocalDate joiningDate = null;
for (final String parameter : workingParameters) {
final String officeIdParameterName = "officeId";
if (officeIdParameterName.equalsIgnoreCase(parameter)) {
final Long baseOfficeId = helper.extractLongNamed(officeIdParameterName, baseElement, ignoreParameters);
final Long workingOfficeId = helper.extractLongNamed(officeIdParameterName, workingElement, ignoreParameters);
if (!workingOfficeId.equals(baseOfficeId)) {
officeId = workingOfficeId;
parametersPassedInRequest.add(officeIdParameterName);
}
}
final String externalIdParamName = "externalId";
if (externalIdParamName.equalsIgnoreCase(parameter)) {
final String baseExternalId = helper.extractStringNamed(externalIdParamName, baseElement, ignoreParameters);
final String workingExternalId = helper.extractStringNamed(externalIdParamName, workingElement, ignoreParameters);
if (differenceExists(baseExternalId, workingExternalId)) {
externalId = workingExternalId;
parametersPassedInRequest.add(externalIdParamName);
}
}
final String firstnameParamName = "firstname";
if (firstnameParamName.equalsIgnoreCase(parameter)) {
final String baseValue = helper.extractStringNamed(firstnameParamName, baseElement, ignoreParameters);
final String workingCopyValue = helper.extractStringNamed(firstnameParamName, workingElement, ignoreParameters);
if (differenceExists(baseValue, workingCopyValue)) {
firstname = workingCopyValue;
parametersPassedInRequest.add(firstnameParamName);
}
}
final String lastnameParamName = "lastname";
if (lastnameParamName.equalsIgnoreCase(parameter)) {
final String baseValue = helper.extractStringNamed(lastnameParamName, baseElement, ignoreParameters);
final String workingCopyValue = helper.extractStringNamed(lastnameParamName, workingElement, ignoreParameters);
if (differenceExists(baseValue, workingCopyValue)) {
lastname = workingCopyValue;
parametersPassedInRequest.add(lastnameParamName);
}
}
final String clientOrBusinessNameParamName = "clientOrBusinessName";
if (clientOrBusinessNameParamName.equalsIgnoreCase(parameter)) {
final String baseValue = helper.extractStringNamed(clientOrBusinessNameParamName, baseElement, ignoreParameters);
final String workingCopyValue = helper.extractStringNamed(clientOrBusinessNameParamName, workingElement, ignoreParameters);
if (differenceExists(baseValue, workingCopyValue)) {
clientOrBusinessName = workingCopyValue;
parametersPassedInRequest.add(clientOrBusinessNameParamName);
}
}
final String joinedDateParamName = "joinedDate";
if (joinedDateParamName.equalsIgnoreCase(parameter)) {
final LocalDate baseValue = helper.extractLocalDateAsArrayNamed(joinedDateParamName, baseElement, ignoreParameters);
final LocalDate workingCopyValue = helper.extractLocalDateAsArrayNamed(joinedDateParamName, workingElement,
ignoreParameters);
if (differenceExists(baseValue, workingCopyValue)) {
joiningDate = workingCopyValue;
parametersPassedInRequest.add(joinedDateParamName);
}
}
}
return new ClientCommand(parametersPassedInRequest, resourceIdentifier, externalId, firstname, lastname, clientOrBusinessName,
officeId, joiningDate, false);
}
private boolean differenceExists(LocalDate baseValue, LocalDate workingCopyValue) {
boolean differenceExists = false;
if (baseValue != null) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = workingCopyValue != null;
}
return differenceExists;
}
private boolean differenceExists(final String baseValue, final String workingCopyValue) {
boolean differenceExists = false;
if (StringUtils.isNotBlank(baseValue)) {
differenceExists = !baseValue.equals(workingCopyValue);
} else {
differenceExists = StringUtils.isNotBlank(workingCopyValue);
}
return differenceExists;
}
@Override @Override
public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) { public ClientData convertInternalJsonFormatToClientDataChange(final Long resourceIdentifier, final String json) {
final ClientCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceIdentifier, json); final ClientCommand command = this.clientCommandFromApiJsonDeserializer.commandFromApiJson(resourceIdentifier, json);
return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(), return ClientData.dataChangeInstance(resourceIdentifier, command.getOfficeId(), command.getExternalId(), command.getFirstname(),
command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate()); command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate());
@@ -1,5 +1,7 @@
package org.mifosplatform.infrastructure.core.data; package org.mifosplatform.infrastructure.core.data;
import java.util.Map;
/** /**
* Represents the successful result of an REST API call. * Represents the successful result of an REST API call.
*/ */
@@ -12,12 +14,18 @@ public class EntityIdentifier {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private Long makerCheckerId; private Long makerCheckerId;
private Map<String, Object> changes;
public static EntityIdentifier makerChecker(final Long makerCheckerId) { public static EntityIdentifier makerChecker(final Long makerCheckerId) {
return new EntityIdentifier(null, makerCheckerId); return new EntityIdentifier(null, makerCheckerId, null);
} }
public static EntityIdentifier makerChecker(final Long resourceId, final Long makerCheckerId) { public static EntityIdentifier makerChecker(final Long resourceId, final Long makerCheckerId) {
return new EntityIdentifier(resourceId, makerCheckerId); return new EntityIdentifier(resourceId, makerCheckerId, null);
}
public static EntityIdentifier withChanges(final Long resourceId, final Map<String, Object> changesOnly) {
return new EntityIdentifier(resourceId, null, changesOnly);
} }
public EntityIdentifier() { public EntityIdentifier() {
@@ -28,9 +36,10 @@ public class EntityIdentifier {
this.entityId = entityId; this.entityId = entityId;
} }
private EntityIdentifier(final Long entityId, final Long makerCheckerId) { private EntityIdentifier(final Long entityId, final Long makerCheckerId, final Map<String, Object> changesOnly) {
this.entityId = entityId; this.entityId = entityId;
this.makerCheckerId = makerCheckerId; this.makerCheckerId = makerCheckerId;
this.changes = changesOnly;
} }
public Long getEntityId() { public Long getEntityId() {
@@ -40,4 +49,8 @@ public class EntityIdentifier {
public void setEntityId(final Long entityId) { public void setEntityId(final Long entityId) {
this.entityId = entityId; this.entityId = entityId;
} }
public Map<String, Object> getChanges() {
return this.changes;
}
} }
@@ -3,6 +3,7 @@ package org.mifosplatform.infrastructure.core.serialization;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@@ -58,10 +59,22 @@ public class FromJsonHelper {
return parser.parse(json); return parser.parse(json);
} }
public boolean parameterExists(final String parameterName, final JsonElement element) {
return helperDelegator.parameterExists(parameterName, element);
}
public String extractStringNamed(final String parameterName, final JsonElement element) {
return helperDelegator.extractStringNamed(parameterName, element, new HashSet<String>());
}
public String extractStringNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) { public String extractStringNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
return helperDelegator.extractStringNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractStringNamed(parameterName, element, parametersPassedInRequest);
} }
public Long extractLongNamed(final String parameterName, final JsonElement element) {
return helperDelegator.extractLongNamed(parameterName, element, new HashSet<String>());
}
public Long extractLongNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) { public Long extractLongNamed(final String parameterName, final JsonElement element, final Set<String> parametersPassedInRequest) {
return helperDelegator.extractLongNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractLongNamed(parameterName, element, parametersPassedInRequest);
} }
@@ -74,6 +87,10 @@ public class FromJsonHelper {
return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractBooleanNamed(parameterName, element, parametersPassedInRequest);
} }
public LocalDate extractLocalDateNamed(final String parameterName, JsonElement element) {
return helperDelegator.extractLocalDateNamed(parameterName, element, new HashSet<String>());
}
public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element, public LocalDate extractLocalDateNamed(final String parameterName, final JsonElement element,
final Set<String> parametersPassedInRequest) { final Set<String> parametersPassedInRequest) {
return helperDelegator.extractLocalDateNamed(parameterName, element, parametersPassedInRequest); return helperDelegator.extractLocalDateNamed(parameterName, element, parametersPassedInRequest);
@@ -28,6 +28,10 @@ import com.google.gson.JsonPrimitive;
*/ */
public class JsonParserHelper { public class JsonParserHelper {
public boolean parameterExists(final String parameterName, final JsonElement element) {
return element.getAsJsonObject().has(parameterName);
}
public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set<String> requestParamatersDetected) { public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set<String> requestParamatersDetected) {
Boolean value = null; Boolean value = null;
if (element.isJsonObject()) { if (element.isJsonObject()) {
@@ -42,7 +42,6 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData; import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientData; import org.mifosplatform.portfolio.client.data.ClientData;
import org.mifosplatform.portfolio.client.exception.ImageNotFoundException; import org.mifosplatform.portfolio.client.exception.ImageNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.client.service.ClientReadPlatformService; import org.mifosplatform.portfolio.client.service.ClientReadPlatformService;
import org.mifosplatform.portfolio.client.service.ClientWritePlatformService; import org.mifosplatform.portfolio.client.service.ClientWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -66,7 +65,6 @@ public class ClientsApiResource {
private final ClientReadPlatformService clientReadPlatformService; private final ClientReadPlatformService clientReadPlatformService;
private final ClientWritePlatformService clientWritePlatformService; private final ClientWritePlatformService clientWritePlatformService;
private final OfficeReadPlatformService officeReadPlatformService; private final OfficeReadPlatformService officeReadPlatformService;
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer; private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper; private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioApiDataConversionService apiDataConversionService; private final PortfolioApiDataConversionService apiDataConversionService;
@@ -77,7 +75,6 @@ public class ClientsApiResource {
@Autowired @Autowired
public ClientsApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService, public ClientsApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService, final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService,
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper, final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioApiDataConversionService apiDataConversionService, final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioApiJsonSerializerService apiJsonSerializerService, final PortfolioApiJsonSerializerService apiJsonSerializerService,
@@ -87,7 +84,6 @@ public class ClientsApiResource {
this.clientReadPlatformService = readPlatformService; this.clientReadPlatformService = readPlatformService;
this.clientWritePlatformService = clientWritePlatformService; this.clientWritePlatformService = clientWritePlatformService;
this.officeReadPlatformService = officeReadPlatformService; this.officeReadPlatformService = officeReadPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer; this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper; this.apiRequestParameterHelper = apiRequestParameterHelper;
this.apiDataConversionService = apiDataConversionService; this.apiDataConversionService = apiDataConversionService;
@@ -152,8 +148,6 @@ public class ClientsApiResource {
extraCriteria = extraCriteria.substring(4); extraCriteria = extraCriteria.substring(4);
} }
// logger.info("extraCriteria; " + extraCriteria);
return extraCriteria; return extraCriteria;
} }
@@ -237,10 +231,8 @@ public class ClientsApiResource {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT"); final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions); context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null,
commandSerializedAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -254,11 +246,13 @@ public class ClientsApiResource {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT"); final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "UPDATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions); context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer // 1. check json request body for create client
.serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
// final String commandSerializedAsJson = this.fromApiJsonDeserializer
// .serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId, final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
commandSerializedAsJson); apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result); return this.toApiJsonSerializer.serialize(result);
} }
@@ -1,8 +1,13 @@
package org.mifosplatform.portfolio.client.command; package org.mifosplatform.portfolio.client.command;
import java.util.Set; import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
/** /**
* *
@@ -14,80 +19,87 @@ public class ClientCommand {
private final String lastname; private final String lastname;
private final String clientOrBusinessName; private final String clientOrBusinessName;
private final Long officeId; private final Long officeId;
private final LocalDate joiningDate; private final LocalDate joinedDate;
// made transient as dont want them to be serialized/converted to JSON public ClientCommand(final String externalId, final String firstname, final String lastname, final String clientOrBusinessName,
private final transient Long id; final Long officeId, final LocalDate joinedDate) {
private final transient boolean makerCheckerApproval;
private final transient Set<String> parametersPassedInRequest;
public ClientCommand(final Set<String> modifiedParameters, final Long id, final String externalId, final String firstname,
final String lastname, final String clientOrBusinessName, final Long officeId, final LocalDate joiningDate,
final boolean makerCheckerApproval) {
this.parametersPassedInRequest = modifiedParameters;
this.id = id;
this.externalId = externalId; this.externalId = externalId;
this.firstname = firstname; this.firstname = firstname;
this.lastname = lastname; this.lastname = lastname;
this.clientOrBusinessName = clientOrBusinessName; this.clientOrBusinessName = clientOrBusinessName;
this.officeId = officeId; this.officeId = officeId;
this.joiningDate = joiningDate; this.joinedDate = joinedDate;
this.makerCheckerApproval = makerCheckerApproval;
} }
public Long getId() { public void validateForCreate() {
return id; List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (StringUtils.isNotBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
baseDataValidator.reset().parameter("lastname").value(this.lastname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
} else {
baseDataValidator.reset().parameter("firstname").value(this.firstname).notBlank();
baseDataValidator.reset().parameter("lastname").value(this.lastname).notBlank();
}
baseDataValidator.reset().parameter("joinedDate").value(this.joinedDate).notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).notExceedingLengthOf(100);
baseDataValidator.reset().parameter("officeId").value(this.officeId).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (this.clientOrBusinessName != null && StringUtils.isNotBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
baseDataValidator.reset().parameter("lastname").value(this.lastname)
.mustBeBlankWhenParameterProvided("clientOrBusinessName", this.clientOrBusinessName);
} else if (StringUtils.isBlank(this.clientOrBusinessName)) {
baseDataValidator.reset().parameter("firstname").value(this.firstname).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("lastname").value(this.lastname).ignoreIfNull().notBlank();
}
baseDataValidator.reset().parameter("joinedDate").value(this.joinedDate).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(this.externalId).ignoreIfNull().notExceedingLengthOf(100);
baseDataValidator.reset().anyOfNotNull(this.firstname, this.lastname, this.clientOrBusinessName, this.joinedDate, this.externalId,
this.officeId);
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
"Validation errors exist.", dataValidationErrors); }
} }
public String getExternalId() { public String getExternalId() {
return externalId; return this.externalId;
} }
public String getFirstname() { public String getFirstname() {
return firstname; return this.firstname;
} }
public String getLastname() { public String getLastname() {
return lastname; return this.lastname;
} }
public String getClientOrBusinessName() { public String getClientOrBusinessName() {
return clientOrBusinessName; return this.clientOrBusinessName;
} }
public Long getOfficeId() { public Long getOfficeId() {
return officeId; return this.officeId;
} }
public LocalDate getJoiningDate() { public LocalDate getJoiningDate() {
return joiningDate; return this.joinedDate;
}
public boolean isFirstnameChanged() {
return this.parametersPassedInRequest.contains("firstname");
}
public boolean isLastnameChanged() {
return this.parametersPassedInRequest.contains("lastname");
}
public boolean isClientOrBusinessNameChanged() {
return this.parametersPassedInRequest.contains("clientOrBusinessName");
}
public boolean isExternalIdChanged() {
return this.parametersPassedInRequest.contains("externalId");
}
public boolean isJoiningDateChanged() {
return this.parametersPassedInRequest.contains("joiningDate");
}
public boolean isOfficeChanged() {
return this.parametersPassedInRequest.contains("officeId");
}
public boolean isApprovedByChecker() {
return this.makerCheckerApproval;
} }
} }
@@ -1,68 +0,0 @@
package org.mifosplatform.portfolio.client.command;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.DataValidatorBuilder;
import org.mifosplatform.infrastructure.core.exception.PlatformApiDataValidationException;
public class ClientCommandValidator {
private final ClientCommand command;
public ClientCommandValidator(ClientCommand command) {
this.command = command;
}
public void validateForUpdate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (command.getClientOrBusinessName() != null && StringUtils.isNotBlank(command.getClientOrBusinessName())) {
baseDataValidator.reset().parameter("firstname").value(command.getFirstname()).mustBeBlankWhenParameterProvided("clientOrBusinessName", command.getClientOrBusinessName());
baseDataValidator.reset().parameter("lastname").value(command.getLastname()).mustBeBlankWhenParameterProvided("clientOrBusinessName", command.getClientOrBusinessName());
} else if (StringUtils.isBlank(command.getClientOrBusinessName())) {
baseDataValidator.reset().parameter("firstname").value(command.getFirstname()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("lastname").value(command.getLastname()).ignoreIfNull().notBlank();
}
baseDataValidator.reset().parameter("joiningDate").value(command.getJoiningDate()).ignoreIfNull().notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).ignoreIfNull().notExceedingLengthOf(100);
if (command.isOfficeChanged()) {
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
}
baseDataValidator.reset().anyOfNotNull(command.getFirstname(), command.getLastname(), command.getClientOrBusinessName(),
command.getJoiningDate(), command.getExternalId(), command.getOfficeId());
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
public void validateForCreate() {
List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("client");
if (StringUtils.isNotBlank(command.getClientOrBusinessName())) {
baseDataValidator.reset().parameter("firstname").value(command.getFirstname()).mustBeBlankWhenParameterProvided("clientOrBusinessName", command.getClientOrBusinessName());
baseDataValidator.reset().parameter("lastname").value(command.getLastname()).mustBeBlankWhenParameterProvided("clientOrBusinessName", command.getClientOrBusinessName());
} else {
baseDataValidator.reset().parameter("firstname").value(command.getFirstname()).notBlank();
baseDataValidator.reset().parameter("lastname").value(command.getLastname()).notBlank();
}
baseDataValidator.reset().parameter("joiningDate").value(command.getJoiningDate()).notBlank();
baseDataValidator.reset().parameter("externalId").value(command.getExternalId()).notExceedingLengthOf(100);
baseDataValidator.reset().parameter("officeId").value(command.getOfficeId()).notNull().integerGreaterThanZero();
if (!dataValidationErrors.isEmpty()) {
throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors);
}
}
}
@@ -1,6 +1,8 @@
package org.mifosplatform.portfolio.client.domain; package org.mifosplatform.portfolio.client.domain;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
@@ -12,51 +14,67 @@ import javax.persistence.TemporalType;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom; import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
@Entity @Entity
@Table(name = "m_client") @Table(name = "m_client")
public class Client extends AbstractAuditableCustom<AppUser, Long> { public class Client extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne @ManyToOne
@JoinColumn(name = "office_id", nullable = false) @JoinColumn(name = "office_id", nullable = false)
private Office office; private Office office;
@Column(name = "firstname", length=50) @Column(name = "firstname", length = 50)
private String firstName; private String firstName;
@Column(name = "lastname", length=50) @Column(name = "lastname", length = 50)
private String lastName; private String lastName;
@Column(name = "display_name", length=50) @Column(name = "display_name", length = 50)
private String displayName; private String displayName;
@Column(name = "joining_date") @Column(name = "joined_date")
@Temporal(TemporalType.DATE) @Temporal(TemporalType.DATE)
private Date joiningDate; private Date joinedDate;
@Column(name = "external_id", length=100, unique=true) @Column(name = "external_id", length = 100, unique = true)
private String externalId; private String externalId;
@Column(name = "is_deleted", nullable=false) @Column(name = "is_deleted", nullable = false)
private boolean deleted = false; private boolean deleted = false;
@Column(name = "image_key", length=500) @Column(name = "image_key", length = 500)
private String imageKey; private String imageKey;
public static Client newClient(Office clientOffice, String firstname, String lastname, LocalDate joiningDate, String externalId) { public static Client fromJson(final Office clientOffice, final JsonCommand command) {
return new Client(clientOffice, firstname, lastname, joiningDate, externalId);
} final String joiningDateParamName = "joinedDate";
final LocalDate joiningDate = command.localDateValueOfParameterNamed(joiningDateParamName);
final String firstnameParamName = "firstname";
String firstname = command.stringValueOfParameterNamed(firstnameParamName);
final String lastnameParamName = "lastname";
String lastname = command.stringValueOfParameterNamed(lastnameParamName);
final String clientOrBusinessNameParamName = "clientOrBusinessName";
final String clientOrBusinessName = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
if (StringUtils.isNotBlank(clientOrBusinessName)) {
lastname = clientOrBusinessName;
firstname = null;
}
final String externalIdParamName = "externalId";
final String externalId = command.stringValueOfParameterNamed(externalIdParamName);
return new Client(clientOffice, firstname, lastname, joiningDate, externalId);
}
protected Client() { protected Client() {
this.office = null; //
this.joiningDate = null;
this.firstName = null;
this.lastName = null;
this.externalId = null;
} }
private Client(final Office office, final String firstName, final String lastName, final LocalDate openingDate, final String externalId) { private Client(final Office office, final String firstName, final String lastName, final LocalDate openingDate, final String externalId) {
@@ -66,160 +84,190 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
} else { } else {
this.externalId = null; this.externalId = null;
} }
this.joiningDate = openingDate.toDateMidnight().toDate(); this.joinedDate = openingDate.toDateMidnight().toDate();
if (StringUtils.isNotBlank(firstName)) { if (StringUtils.isNotBlank(firstName)) {
this.firstName = firstName.trim(); this.firstName = firstName.trim();
} else { } else {
this.firstName = null; this.firstName = null;
} }
this.lastName = lastName.trim(); this.lastName = lastName.trim();
//populate display name // populate display name
if(this.firstName!=null){ if (this.firstName != null) {
this.displayName = this.firstName + " " + this.lastName; this.displayName = this.firstName + " " + this.lastName;
}else{ } else {
this.displayName = this.lastName; this.displayName = this.lastName;
} }
} }
public boolean identifiedBy(final String identifier) { public boolean identifiedBy(final String identifier) {
return identifier.equalsIgnoreCase(this.externalId); return identifier.equalsIgnoreCase(this.externalId);
} }
public boolean identifiedBy(Long clientId) { public boolean identifiedBy(Long clientId) {
return getId().equals(clientId); return getId().equals(clientId);
} }
public void update(ClientCommand command) { public void changeOffice(final Office newOffice) {
this.joiningDate = command.getJoiningDate().toDate(); this.office = newOffice;
this.firstName = command.getFirstname(); }
this.lastName = command.getLastname();
if (StringUtils.isNotBlank(command.getClientOrBusinessName())) { public Map<String, Object> update(final JsonCommand command) {
this.firstName = null;
this.lastName = command.getClientOrBusinessName().trim();
this.displayName = this.lastName;
}else{
deriveDisplayName();
}
if (StringUtils.isNotBlank(command.getExternalId())) { final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
this.externalId = command.getExternalId().trim();
} else { final String dateFormatAsInput = command.dateFormat();
this.externalId = null; final String localeAsInput = command.locale();
final String officeIdParamName = "officeId";
if (command.isChangeInLongParameterNamed(officeIdParamName, this.office.getId())) {
final Long newValue = command.longValueOfParameterNamed(officeIdParamName);
actualChanges.put(officeIdParamName, newValue);
} }
}
public void update(final Office clientOffice, final ClientCommand command) { final String joiningDateParamName = "joinedDate";
if (command.isOfficeChanged()) { if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) {
this.office = clientOffice; final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName);
} actualChanges.put(joiningDateParamName, valueAsInput);
if (command.isJoiningDateChanged()) { actualChanges.put("dateFormat", dateFormatAsInput);
this.joiningDate = command.getJoiningDate().toDate(); actualChanges.put("locale", localeAsInput);
}
if (command.isFirstnameChanged()) {
this.firstName = command.getFirstname();
}
if (command.isLastnameChanged()) {
this.lastName = command.getLastname();
}
if (command.isClientOrBusinessNameChanged() && StringUtils.isNotBlank(command.getClientOrBusinessName())) { final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName);
this.lastName = command.getClientOrBusinessName(); this.joinedDate = newValue.toDate();
this.firstName = null; }
this.displayName = this.lastName;
}else if(command.isFirstnameChanged() || command.isLastnameChanged()) {
//do not want to enter this condition for business names
deriveDisplayName();
}
if (command.isExternalIdChanged()) { final String firstnameParamName = "firstname";
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null); if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) {
} final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
} actualChanges.put(firstnameParamName, newValue);
this.firstName = newValue;
}
private void deriveDisplayName() { final String lastnameParamName = "lastname";
this.displayName = this.firstName + " " + this.lastName; if (command.isChangeInStringParameterNamed(lastnameParamName, this.lastName)) {
} final String newValue = command.stringValueOfParameterNamed(lastnameParamName);
actualChanges.put(lastnameParamName, newValue);
this.lastName = newValue;
}
final String clientOrBusinessNameParamName = "clientOrBusinessName";
if (command.isChangeInStringParameterNamed(clientOrBusinessNameParamName, getClientOrBusinessName())) {
final String newValue = command.stringValueOfParameterNamed(clientOrBusinessNameParamName);
actualChanges.put(clientOrBusinessNameParamName, newValue);
if (StringUtils.isNotBlank(newValue)) {
this.lastName = newValue;
this.firstName = null;
this.displayName = this.lastName;
} else {
deriveDisplayName();
}
}
final String externalIdParamName = "externalId";
if (command.isChangeInStringParameterNamed(externalIdParamName, this.externalId)) {
final String newValue = command.stringValueOfParameterNamed(externalIdParamName);
actualChanges.put(externalIdParamName, newValue);
this.externalId = StringUtils.defaultIfEmpty(newValue, null);
}
return actualChanges;
}
private void deriveDisplayName() {
this.displayName = this.firstName + " " + this.lastName;
}
private LocalDate getJoiningLocalDate() {
LocalDate joiningLocalDate = null;
if (this.joinedDate != null) {
joiningLocalDate = LocalDate.fromDateFields(this.joinedDate);
}
return joiningLocalDate;
}
private String getClientOrBusinessName() {
String clientOrBusinessName = null;
if (StringUtils.isBlank(this.firstName) && StringUtils.isNotBlank(this.lastName)) {
clientOrBusinessName = this.lastName;
}
return clientOrBusinessName;
}
/** /**
* Delete is a <i>soft delete</i>. Updates flag on client so it wont appear in query/report results. * 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. *
*/ * Any fields with unique constraints and prepended with id of record.
public void delete() { */
this.deleted = true; public void delete() {
this.externalId = this.getId() + "_" + this.externalId; this.deleted = true;
} this.externalId = this.getId() + "_" + this.externalId;
}
public boolean isDeleted() { public boolean isDeleted() {
return deleted; return deleted;
} }
public boolean isOfficeIdentifiedBy(final Long officeId) { public boolean isOfficeIdentifiedBy(final Long officeId) {
return this.office.identifiedBy(officeId); return this.office.identifiedBy(officeId);
} }
public Office getOffice() { public Office getOffice() {
return office; return office;
} }
public void setOffice(Office office) { public void setOffice(Office office) {
this.office = office; this.office = office;
} }
public String getFirstName() { public String getFirstName() {
return firstName; return firstName;
} }
public void setFirstName(String firstName) { public void setFirstName(String firstName) {
this.firstName = firstName; this.firstName = firstName;
} }
public String getLastName() { public String getLastName() {
return lastName; return lastName;
} }
public void setLastName(String lastName) { public void setLastName(String lastName) {
this.lastName = lastName; this.lastName = lastName;
} }
public String getDisplayName() { public String getDisplayName() {
return displayName; return displayName;
} }
public void setDisplayName(String displayName) { public void setDisplayName(String displayName) {
this.displayName = displayName; this.displayName = displayName;
} }
public Date getJoiningDate() { public Date getJoiningDate() {
return joiningDate; return joinedDate;
} }
public void setJoiningDate(Date joiningDate) { public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate; this.joinedDate = joiningDate;
} }
public String getExternalId() { public String getExternalId() {
return externalId; return externalId;
} }
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public String getImageKey() {
return imageKey;
}
public void setImageKey(String imageKey) {
this.imageKey = imageKey;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public String getImageKey() {
return imageKey;
}
public void setImageKey(String imageKey) {
this.imageKey = imageKey;
}
} }
@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.serialization.AbstractFromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.CommandSerializer; import org.mifosplatform.infrastructure.core.serialization.CommandSerializer;
import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer; import org.mifosplatform.infrastructure.core.serialization.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper; import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -22,30 +23,24 @@ import com.google.gson.reflect.TypeToken;
* 's. * 's.
*/ */
@Component @Component
public final class ClientCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ClientCommand> { public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientCommand> {
/** /**
* The parameters supported for this command. * The parameters supported for this command.
*/ */
private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "externalId", "firstname", "lastname", private final Set<String> supportedParameters = new HashSet<String>(Arrays.asList("id", "externalId", "firstname", "lastname",
"clientOrBusinessName", "officeId", "joiningDate", "locale", "dateFormat")); "clientOrBusinessName", "officeId", "joinedDate", "locale", "dateFormat"));
private final FromJsonHelper fromApiJsonHelper; private final FromJsonHelper fromApiJsonHelper;
private final CommandSerializer commandSerializerService;
@Autowired @Autowired
public ClientCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) { public ClientCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper; this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSerializerService = commandSerializerService;
} }
@Override @Override
public ClientCommand commandFromApiJson(final String json) { public ClientCommand commandFromApiJson(@SuppressWarnings("unused") final Long clientId, final String json) {
return commandFromApiJson(null, json);
}
@Override
public ClientCommand commandFromApiJson(final Long clientId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType(); final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
@@ -62,19 +57,6 @@ public final class ClientCommandFromApiJsonDeserializer implements FromApiJsonDe
.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest); .extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest);
final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joiningDate", element, parametersPassedInRequest); final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joiningDate", element, parametersPassedInRequest);
return new ClientCommand(parametersPassedInRequest, clientId, externalId, firstname, lastname, clientOrBusinessName, officeId, return new ClientCommand(externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate);
joiningDate, false);
}
@Override
public String serializedCommandJsonFromApiJson(final String json) {
final ClientCommand command = commandFromApiJson(json);
return this.commandSerializerService.serializeCommandToJson(command);
}
@Override
public String serializedCommandJsonFromApiJson(final Long fundId, final String json) {
final ClientCommand command = commandFromApiJson(fundId, json);
return this.commandSerializerService.serializeCommandToJson(command);
} }
} }
@@ -1,54 +0,0 @@
package org.mifosplatform.portfolio.client.serialization;
import java.util.HashSet;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.exception.InvalidJsonException;
import org.mifosplatform.infrastructure.core.serialization.FromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.google.gson.JsonElement;
@Component
public final class ClientCommandFromCommandJsonDeserializer implements FromCommandJsonDeserializer<ClientCommand> {
private final FromJsonHelper fromJsonHelper;
@Autowired
public ClientCommandFromCommandJsonDeserializer(final FromJsonHelper fromApiJsonHelper) {
this.fromJsonHelper = fromApiJsonHelper;
}
@Override
public ClientCommand commandFromCommandJson(final String commandAsJson) {
return commandFromCommandJson(null, commandAsJson);
}
@Override
public ClientCommand commandFromCommandJson(final Long clientId, final String commandAsJson) {
return commandFromCommandJson(clientId, commandAsJson, false);
}
@Override
public ClientCommand commandFromCommandJson(final Long clientId, final String commandAsJson, final boolean makerCheckerApproval) {
if (StringUtils.isBlank(commandAsJson)) { throw new InvalidJsonException(); }
final Set<String> parametersPassedInRequest = new HashSet<String>();
final JsonElement element = fromJsonHelper.parse(commandAsJson);
final Long officeId = fromJsonHelper.extractLongNamed("officeId", element, parametersPassedInRequest);
final String externalId = fromJsonHelper.extractStringNamed("externalId", element, parametersPassedInRequest);
final String firstname = fromJsonHelper.extractStringNamed("firstname", element, parametersPassedInRequest);
final String lastname = fromJsonHelper.extractStringNamed("lastname", element, parametersPassedInRequest);
final String clientOrBusinessName = fromJsonHelper.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest);
final LocalDate joiningDate = fromJsonHelper.extractLocalDateAsArrayNamed("joiningDate", element, parametersPassedInRequest);
return new ClientCommand(parametersPassedInRequest, clientId, externalId, firstname, lastname, clientOrBusinessName, officeId,
joiningDate, makerCheckerApproval);
}
}
@@ -130,7 +130,7 @@ public class ClientReadPlatformServiceImpl implements ClientReadPlatformService
public String clientSchema() { public String clientSchema() {
return "c.office_id as officeId, o.name as officeName, c.id as id, c.firstname as firstname, c.lastname as lastname, c.display_name as displayName, " return "c.office_id as officeId, o.name as officeName, c.id as id, c.firstname as firstname, c.lastname as lastname, c.display_name as displayName, "
+ "c.external_id as externalId, c.joining_date as joinedDate, c.image_key as imagekey from m_client c join m_office o on o.id = c.office_id " + "c.external_id as externalId, c.joined_date as joinedDate, c.image_key as imagekey from m_client c join m_office o on o.id = c.office_id "
+ " where o.hierarchy like ? and c.is_deleted=0 "; + " where o.hierarchy like ? and c.is_deleted=0 ";
} }
@@ -2,20 +2,20 @@ package org.mifosplatform.portfolio.client.service;
import java.io.InputStream; import java.io.InputStream;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage; import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand; import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
public interface ClientWritePlatformService { public interface ClientWritePlatformService {
Long createClient(ClientCommand command); Long createClient(JsonCommand command);
EntityIdentifier updateClientDetails(ClientCommand command); EntityIdentifier updateClientDetails(Long clientId, JsonCommand command);
EntityIdentifier deleteClient(ClientCommand command); EntityIdentifier deleteClient(Long clientId, JsonCommand command);
@PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')") @PreAuthorize(value = "hasAnyRole('ALL_FUNCTIONS', 'PORTFOLIO_MANAGEMENT_SUPER_USER', 'CREATE_CLIENTIMAGE')")
EntityIdentifier saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream); EntityIdentifier saveOrUpdateClientImage(Long clientId, String imageName, InputStream inputStream);
@@ -3,11 +3,13 @@ package org.mifosplatform.portfolio.client.service;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Map;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository; import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException; import org.mifosplatform.infrastructure.codes.exception.CodeValueNotFoundException;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier; import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage; import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException; import org.mifosplatform.infrastructure.core.exception.PlatformDataIntegrityException;
@@ -19,7 +21,6 @@ import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.office.domain.OfficeRepository; import org.mifosplatform.organisation.office.domain.OfficeRepository;
import org.mifosplatform.organisation.office.exception.OfficeNotFoundException; import org.mifosplatform.organisation.office.exception.OfficeNotFoundException;
import org.mifosplatform.portfolio.client.command.ClientCommand; import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.portfolio.client.command.ClientCommandValidator;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommandValidator; import org.mifosplatform.portfolio.client.command.ClientIdentifierCommandValidator;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand; import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
@@ -33,6 +34,7 @@ import org.mifosplatform.portfolio.client.exception.ClientIdentifierNotFoundExce
import org.mifosplatform.portfolio.client.exception.ClientNotFoundException; import org.mifosplatform.portfolio.client.exception.ClientNotFoundException;
import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException; import org.mifosplatform.portfolio.client.exception.DuplicateClientIdentifierException;
import org.mifosplatform.portfolio.client.exception.NoteNotFoundException; import org.mifosplatform.portfolio.client.exception.NoteNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -52,12 +54,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final NoteRepository noteRepository; private final NoteRepository noteRepository;
private final CodeValueRepository codeValueRepository; private final CodeValueRepository codeValueRepository;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired @Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository, public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository,
final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository, final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository,
final NoteRepository noteRepository, final CodeValueRepository codeValueRepository, final NoteRepository noteRepository, final CodeValueRepository codeValueRepository,
final ConfigurationDomainService configurationDomainService) { final ConfigurationDomainService configurationDomainService, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context; this.context = context;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.clientIdentifierRepository = clientIdentifierRepository; this.clientIdentifierRepository = clientIdentifierRepository;
@@ -65,13 +68,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.noteRepository = noteRepository; this.noteRepository = noteRepository;
this.codeValueRepository = codeValueRepository; this.codeValueRepository = codeValueRepository;
this.configurationDomainService = configurationDomainService; this.configurationDomainService = configurationDomainService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
} }
@Transactional @Transactional
@Override @Override
public EntityIdentifier deleteClient(final ClientCommand command) { public EntityIdentifier deleteClient(final Long clientId, final JsonCommand command) {
final Long clientId = command.getId();
final Client client = this.clientRepository.findOne(clientId); final Client client = this.clientRepository.findOne(clientId);
if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); } if (client == null || client.isDeleted()) { throw new ClientNotFoundException(clientId); }
@@ -87,12 +90,15 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
* Guaranteed to throw an exception no matter what the data integrity issue * Guaranteed to throw an exception no matter what the data integrity issue
* is. * is.
*/ */
private void handleDataIntegrityIssues(final ClientCommand command, final DataIntegrityViolationException dve) { private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause(); Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("external_id")) { throw new PlatformDataIntegrityException( if (realCause.getMessage().contains("external_id")) {
"error.msg.client.duplicate.externalId", "Client with externalId `" + command.getExternalId() + "` already exists",
"externalId", command.getExternalId()); } final String externalId = command.stringValueOfParameterNamed("externalId");
throw new PlatformDataIntegrityException("error.msg.client.duplicate.externalId", "Client with externalId `" + externalId
+ "` already exists", "externalId", externalId);
}
logAsErrorUnexpectedDataIntegrityException(dve); logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.client.unknown.data.integrity.issue", throw new PlatformDataIntegrityException("error.msg.client.unknown.data.integrity.issue",
@@ -101,26 +107,21 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public Long createClient(final ClientCommand command) { public Long createClient(final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
final ClientCommandValidator validator = new ClientCommandValidator(command); final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
validator.validateForCreate(); clientCommand.validateForCreate();
final Office clientOffice = this.officeRepository.findOne(command.getOfficeId()); final String officeIdParamName = "officeId";
if (clientOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); } final Long officeId = command.longValueOfParameterNamed(officeIdParamName);
String firstname = command.getFirstname(); final Office clientOffice = this.officeRepository.findOne(officeId);
String lastname = command.getLastname(); if (clientOffice == null) { throw new OfficeNotFoundException(officeId); }
if (StringUtils.isNotBlank(command.getClientOrBusinessName())) {
lastname = command.getClientOrBusinessName();
firstname = null;
}
final Client newClient = Client.newClient(clientOffice, firstname, lastname, command.getJoiningDate(), command.getExternalId());
final Client newClient = Client.fromJson(clientOffice, command);
this.clientRepository.save(newClient); this.clientRepository.save(newClient);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
@@ -134,30 +135,31 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional @Transactional
@Override @Override
public EntityIdentifier updateClientDetails(final ClientCommand command) { public EntityIdentifier updateClientDetails(final Long clientId, final JsonCommand command) {
try { try {
context.authenticatedUser(); context.authenticatedUser();
final ClientCommandValidator validator = new ClientCommandValidator(command); final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
validator.validateForUpdate(); clientCommand.validateForUpdate();
Office clientOffice = null; final Client clientForUpdate = this.clientRepository.findOne(clientId);
Long officeId = command.getOfficeId(); if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(clientId); }
if (command.isOfficeChanged() && officeId != null) { final Map<String, Object> changesOnly = clientForUpdate.update(command);
clientOffice = this.officeRepository.findOne(officeId);
if (clientOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); } if (changesOnly.containsKey("officeId")) {
final Long officeId = (Long) changesOnly.get("officeId");
Office newOffice = this.officeRepository.findOne(officeId);
if (newOffice == null) { throw new OfficeNotFoundException(officeId); }
clientForUpdate.changeOffice(newOffice);
} }
final Client clientForUpdate = this.clientRepository.findOne(command.getId()); this.clientRepository.save(clientForUpdate);
if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(command.getId()); }
clientForUpdate.update(clientOffice, command);
this.clientRepository.saveAndFlush(clientForUpdate);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); } if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return new EntityIdentifier(clientForUpdate.getId()); return EntityIdentifier.withChanges(clientId, changesOnly);
} catch (DataIntegrityViolationException dve) { } catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1)); return new EntityIdentifier(Long.valueOf(-1));