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.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.charge.command.ChargeDefinitionCommand;
import org.mifosplatform.portfolio.charge.serialization.ChargeCommandFromCommandJsonDeserializer;
@@ -19,16 +18,14 @@ import org.springframework.stereotype.Service;
public class ChargeDefinitionCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ChargeWritePlatformService writePlatformService;
@Autowired
public ChargeDefinitionCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public ChargeDefinitionCommandHandler(final PlatformSecurityContext context,
final ChargeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ChargeWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -55,13 +52,7 @@ public class ChargeDefinitionCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ChargeDefinitionCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateCharge(changesOnly);
this.writePlatformService.updateCharge(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -5,32 +5,34 @@ import java.util.List;
import org.joda.time.LocalDate;
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.serialization.ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
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.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.google.gson.JsonElement;
@Service
public class ClientCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ClientWritePlatformService clientWritePlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer;
@Autowired
public ClientCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
public ClientCommandHandler(final PlatformSecurityContext context, final FromJsonHelper fromApiJsonHelper,
final ExcludeNothingWithPrettyPrintingOffJsonSerializerGoogleGson toApiJsonSerializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.fromApiJsonHelper = fromApiJsonHelper;
this.toApiJsonSerializer = toApiJsonSerializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@@ -40,8 +42,8 @@ public class ClientCommandHandler implements CommandSourceHandler {
final AppUser maker = context.authenticatedUser();
final LocalDate asToday = new LocalDate();
final ClientCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSource.resourceId(),
commandSource.json());
final JsonElement parsedCommand = this.fromApiJsonHelper.parse(commandSource.json());
final JsonCommand command = JsonCommand.from(commandSource.json(), parsedCommand, this.fromApiJsonHelper);
CommandSource commandSourceResult = commandSource.copy();
Long newResourceId = null;
@@ -56,14 +58,11 @@ public class ClientCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(changesOnly);
EntityIdentifier result = this.clientWritePlatformService.updateClientDetails(commandSource.resourceId(), command);
newResourceId = result.getEntityId();
final String jsonOfChangesOnly = toApiJsonSerializer.serialize(result.getChanges());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -71,7 +70,7 @@ public class ClientCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isDelete()) {
try {
EntityIdentifier result = this.clientWritePlatformService.deleteClient(command);
EntityIdentifier result = this.clientWritePlatformService.deleteClient(commandSource.resourceId(), command);
newResourceId = result.getEntityId();
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -87,8 +86,8 @@ public class ClientCommandHandler implements CommandSourceHandler {
final AppUser checker = context.authenticatedUser();
final ClientCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(),
commandSourceResult.json(), true);
final JsonElement parsedCommand = fromApiJsonHelper.parse(commandSourceResult.json());
final JsonCommand command = JsonCommand.withMakerCheckerApproval(commandSourceResult.json(), parsedCommand, fromApiJsonHelper);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
@@ -103,14 +102,14 @@ public class ClientCommandHandler implements CommandSourceHandler {
"UPDATE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT_CHECKER", allowedPermissions);
this.clientWritePlatformService.updateClientDetails(command);
this.clientWritePlatformService.updateClientDetails(commandSourceResult.resourceId(), command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"DELETE_CLIENT_CHECKER");
context.authenticatedUser().validateHasPermissionTo("DELETE_CLIENT_CHECKER", allowedPermissions);
this.clientWritePlatformService.deleteClient(command);
this.clientWritePlatformService.deleteClient(commandSourceResult.resourceId(), command);
commandSourceResult.markAsChecked(checker, new LocalDate());
}
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientIdentifierCommand;
import org.mifosplatform.portfolio.client.serialization.ClientIdentifierCommandFromCommandJsonDeserializer;
@@ -19,16 +18,14 @@ import org.springframework.stereotype.Service;
public class ClientIdentifierCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientWritePlatformService clientWritePlatformService;
private final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired
public ClientIdentifierCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public ClientIdentifierCommandHandler(final PlatformSecurityContext context,
final ClientIdentifierCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@@ -53,14 +50,7 @@ public class ClientIdentifierCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientIdentifierCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.clientWritePlatformService.updateClientIdentifier(changesOnly);
this.clientWritePlatformService.updateClientIdentifier(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.command.ClientNoteCommand;
@@ -21,16 +20,14 @@ import org.springframework.stereotype.Service;
public class ClientNoteCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final ClientWritePlatformService clientWritePlatformService;
private final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
@Autowired
public ClientNoteCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public ClientNoteCommandHandler(final PlatformSecurityContext context,
final ClientNoteCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final ClientWritePlatformService clientWritePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.clientWritePlatformService = clientWritePlatformService;
}
@@ -55,21 +52,12 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final ClientNoteCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.clientWritePlatformService.updateNote(changesOnly);
this.clientWritePlatformService.updateNote(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
}
} else if (commandSource.isDelete()) {
throw new UnsupportedCommandException(commandSource.commandName());
}
} else if (commandSource.isDelete()) { throw new UnsupportedCommandException(commandSource.commandName()); }
return commandSourceResult;
}
@@ -79,8 +67,8 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
final AppUser checker = context.authenticatedUser();
final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSourceResult.resourceId(), commandSourceResult.json(), true);
final ClientNoteCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(commandSourceResult.resourceId(),
commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER",
"CREATE_CLIENTNOTE_CHECKER");
@@ -96,9 +84,7 @@ public class ClientNoteCommandHandler implements CommandSourceHandler {
this.clientWritePlatformService.updateNote(command);
commandSourceResult.markAsChecked(checker, new LocalDate());
} else if (commandSourceResult.isDelete()) {
throw new UnsupportedCommandException(commandSourceResult.commandName());
}
} else if (commandSourceResult.isDelete()) { throw new UnsupportedCommandException(commandSourceResult.commandName()); }
return commandSourceResult;
}
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.codes.command.CodeCommand;
import org.mifosplatform.infrastructure.codes.serialization.CodeCommandFromCommandJsonDeserializer;
import org.mifosplatform.infrastructure.codes.service.CodeWritePlatformService;
@@ -19,15 +18,13 @@ import org.springframework.stereotype.Service;
public class CodeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final CodeWritePlatformService writePlatformService;
@Autowired
public CodeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public CodeCommandHandler(final PlatformSecurityContext context,
final CodeCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final CodeWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -53,12 +50,7 @@ public class CodeCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final CodeCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateCode(changesOnly);
this.writePlatformService.updateCode(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.monetary.command.CurrencyCommand;
import org.mifosplatform.organisation.monetary.serialization.CurrencyCommandFromCommandJsonDeserializer;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class CurrencyCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer;
private final CurrencyWritePlatformService writePlatformService;
@Autowired
public CurrencyCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public CurrencyCommandHandler(final PlatformSecurityContext context,
final CurrencyCommandFromCommandJsonDeserializer fromApiJsonDeserializer,
final CurrencyWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -46,13 +43,8 @@ public class CurrencyCommandHandler implements CommandSourceHandler {
throw new UnsupportedCommandException(commandSource.commandName());
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final CurrencyCommand changesOnly = this.fromApiJsonDeserializer.commandFromCommandJson(jsonOfChangesOnly);
this.writePlatformService.updateAllowedCurrencies(changesOnly);
final CurrencyCommand command = this.fromApiJsonDeserializer.commandFromCommandJson(commandSource.json());
this.writePlatformService.updateAllowedCurrencies(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
// swallow this rollback transaction by design
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.portfolio.fund.command.FundCommand;
@@ -20,15 +19,13 @@ import org.springframework.stereotype.Service;
public class FundCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final FundWritePlatformService writePlatformService;
@Autowired
public FundCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public FundCommandHandler(final PlatformSecurityContext context,
final FundCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final FundWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -56,13 +53,7 @@ public class FundCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final FundCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateFund(changesOnly);
this.writePlatformService.updateFund(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
@@ -21,16 +20,14 @@ import org.springframework.stereotype.Service;
public class LoanProductCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final LoanProductWritePlatformService writePlatformService;
@Autowired
public LoanProductCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public LoanProductCommandHandler(final PlatformSecurityContext context,
final LoanProductCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final LoanProductWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -55,13 +52,7 @@ public class LoanProductCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final LoanProductCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateLoanProduct(changesOnly);
this.writePlatformService.updateLoanProduct(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.office.command.OfficeCommand;
import org.mifosplatform.organisation.office.serialization.OfficeCommandFromCommandJsonDeserializer;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class OfficeCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final OfficeWritePlatformService writePlatformService;
@Autowired
public OfficeCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public OfficeCommandHandler(final PlatformSecurityContext context,
final OfficeCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final OfficeWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -57,13 +54,7 @@ public class OfficeCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final OfficeCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
this.writePlatformService.updateOffice(changesOnly);
this.writePlatformService.updateOffice(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.PermissionsCommand;
@@ -20,16 +19,14 @@ import org.springframework.stereotype.Service;
public class PermissionsCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final PermissionWritePlatformService permissionWritePlatformService;
@Autowired
public PermissionsCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public PermissionsCommandHandler(final PlatformSecurityContext context,
final PermissionsCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final PermissionWritePlatformService permissionWritePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.permissionWritePlatformService = permissionWritePlatformService;
}
@@ -44,14 +41,10 @@ public class PermissionsCommandHandler implements CommandSourceHandler {
if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
final PermissionsCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final PermissionsCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(
commandSource.resourceId(), jsonOfChangesOnly);
this.permissionWritePlatformService.updateMakerCheckerPermissions(changesOnly);
this.permissionWritePlatformService.updateMakerCheckerPermissions(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.RoleCommand;
@@ -22,18 +21,16 @@ import org.springframework.stereotype.Service;
public class RoleCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final RoleWritePlatformService writePlatformService;
private final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer;
@Autowired
public RoleCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public RoleCommandHandler(final PlatformSecurityContext context,
final RoleCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer,
final RolePermissionsCommandFromCommandJsonDeserializer permissionsCommandFromCommandJsonDeserializer,
final RoleWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
this.permissionsCommandFromCommandJsonDeserializer = permissionsCommandFromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
@@ -64,14 +61,10 @@ public class RoleCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final RoleCommand command = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
commandSource.json());
final RoleCommand changesOnly = this.commandFromCommandJsonDeserializer.commandFromCommandJson(resourceId,
jsonOfChangesOnly);
newResourceId = this.writePlatformService.updateRole(changesOnly);
newResourceId = this.writePlatformService.updateRole(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -79,14 +72,10 @@ public class RoleCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdateRolePermissions()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final RolePermissionCommand command = this.permissionsCommandFromCommandJsonDeserializer.commandFromCommandJson(
resourceId, commandSource.json());
final RolePermissionCommand changesOnly = this.permissionsCommandFromCommandJsonDeserializer.commandFromCommandJson(
resourceId, jsonOfChangesOnly);
newResourceId = this.writePlatformService.updateRolePermissions(changesOnly);
newResourceId = this.writePlatformService.updateRolePermissions(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -6,7 +6,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.exception.UnsupportedCommandException;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.organisation.staff.command.StaffCommand;
import org.mifosplatform.organisation.staff.serialization.StaffCommandFromCommandJsonDeserializer;
@@ -20,17 +19,13 @@ import org.springframework.stereotype.Service;
public class StaffCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final StaffWritePlatformService writePlatformService;
@Autowired
public StaffCommandHandler(final PlatformSecurityContext context,
final ChangeDetectionService changeDetectionService,
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer,
final StaffWritePlatformService writePlatformService) {
public StaffCommandHandler(final PlatformSecurityContext context,
final StaffCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final StaffWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -56,13 +51,7 @@ public class StaffCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
try {
final String jsonOfChangesOnly = this.changeDetectionService.detectChangesOnUpdate(commandSource.resourceName(),
commandSource.resourceId(), commandSource.json());
commandSourceResult.updateJsonTo(jsonOfChangesOnly);
final StaffCommand changesOnly = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, jsonOfChangesOnly);
this.writePlatformService.updateStaff(changesOnly);
this.writePlatformService.updateStaff(command);
commandSourceResult.markAsChecked(maker, asToday);
} catch (RollbackTransactionAsCommandIsNotApprovedByCheckerException e) {
@@ -80,7 +69,7 @@ public class StaffCommandHandler implements CommandSourceHandler {
Long resourceId = commandSourceResult.resourceId();
final StaffCommand command = this.fromCommandJsonDeserializer.commandFromCommandJson(resourceId, commandSourceResult.json(), true);
if (commandSourceResult.isCreate()) {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "ORGANISATION_ADMINISTRATION_SUPER_USER",
"CREATE_STAFF_CHECKER");
@@ -5,7 +5,6 @@ import java.util.List;
import org.joda.time.LocalDate;
import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.service.ChangeDetectionService;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.portfolio.client.service.RollbackTransactionAsCommandIsNotApprovedByCheckerException;
import org.mifosplatform.useradministration.command.UserCommand;
@@ -19,15 +18,13 @@ import org.springframework.stereotype.Service;
public class UserCommandHandler implements CommandSourceHandler {
private final PlatformSecurityContext context;
private final ChangeDetectionService changeDetectionService;
private final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer;
private final AppUserWritePlatformService writePlatformService;
@Autowired
public UserCommandHandler(final PlatformSecurityContext context, final ChangeDetectionService changeDetectionService,
public UserCommandHandler(final PlatformSecurityContext context,
final UserCommandFromCommandJsonDeserializer fromCommandJsonDeserializer, final AppUserWritePlatformService writePlatformService) {
this.context = context;
this.changeDetectionService = changeDetectionService;
this.fromCommandJsonDeserializer = fromCommandJsonDeserializer;
this.writePlatformService = writePlatformService;
}
@@ -52,15 +49,10 @@ public class UserCommandHandler implements CommandSourceHandler {
}
} else if (commandSource.isUpdate()) {
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())) {
this.writePlatformService.updateUsersOwnAccountDetails(changesOnly);
this.writePlatformService.updateUsersOwnAccountDetails(command);
} else {
this.writePlatformService.updateUser(changesOnly);
this.writePlatformService.updateUser(command);
}
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;
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.data.ClientData;
import org.mifosplatform.portfolio.group.command.GroupCommand;
@@ -28,8 +27,6 @@ public interface PortfolioApiDataConversionService {
ClientData convertInternalJsonFormatToClientDataChange(Long clientId, String json);
ClientCommand detectChanges(Long resourceId, String baseJson, String workingJson);
GroupCommand convertJsonToGroupCommand(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.NoteCommand;
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.loanaccount.command.AdjustLoanTransactionCommand;
import org.mifosplatform.portfolio.loanaccount.command.LoanApplicationCommand;
@@ -61,11 +61,11 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
*/
private final Gson gsonConverter;
private final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer;
private final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer;
@Autowired
public PortfolioApiDataConversionServiceImpl(final ClientCommandFromCommandJsonDeserializer commandFromCommandJsonDeserializer) {
this.commandFromCommandJsonDeserializer = commandFromCommandJsonDeserializer;
public PortfolioApiDataConversionServiceImpl(final ClientCommandFromApiJsonDeserializer clientCommandFromApiJsonDeserializer) {
this.clientCommandFromApiJsonDeserializer = clientCommandFromApiJsonDeserializer;
this.gsonConverter = new Gson();
}
@@ -131,125 +131,10 @@ public class PortfolioApiDataConversionServiceImpl implements PortfolioApiDataCo
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
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(),
command.getLastname(), command.getClientOrBusinessName(), command.getJoiningDate());
@@ -1,5 +1,7 @@
package org.mifosplatform.infrastructure.core.data;
import java.util.Map;
/**
* Represents the successful result of an REST API call.
*/
@@ -12,12 +14,18 @@ public class EntityIdentifier {
@SuppressWarnings("unused")
private Long makerCheckerId;
private Map<String, Object> changes;
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) {
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() {
@@ -28,9 +36,10 @@ public class EntityIdentifier {
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.makerCheckerId = makerCheckerId;
this.changes = changesOnly;
}
public Long getEntityId() {
@@ -40,4 +49,8 @@ public class EntityIdentifier {
public void setEntityId(final Long 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.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -57,11 +58,23 @@ public class FromJsonHelper {
public JsonElement parse(final String 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) {
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) {
return helperDelegator.extractLongNamed(parameterName, element, parametersPassedInRequest);
}
@@ -73,6 +86,10 @@ public class FromJsonHelper {
public Boolean extractBooleanNamed(final String parameterName, final JsonElement element, final Set<String> 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,
final Set<String> parametersPassedInRequest) {
@@ -27,6 +27,10 @@ import com.google.gson.JsonPrimitive;
* Helper class to extract values of json named attributes.
*/
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) {
Boolean value = null;
@@ -42,7 +42,6 @@ import org.mifosplatform.organisation.office.service.OfficeReadPlatformService;
import org.mifosplatform.portfolio.client.data.ClientAccountSummaryCollectionData;
import org.mifosplatform.portfolio.client.data.ClientData;
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.ClientWritePlatformService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -66,7 +65,6 @@ public class ClientsApiResource {
private final ClientReadPlatformService clientReadPlatformService;
private final ClientWritePlatformService clientWritePlatformService;
private final OfficeReadPlatformService officeReadPlatformService;
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
private final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer;
private final ApiRequestParameterHelper apiRequestParameterHelper;
private final PortfolioApiDataConversionService apiDataConversionService;
@@ -77,7 +75,6 @@ public class ClientsApiResource {
@Autowired
public ClientsApiResource(final PlatformSecurityContext context, final ClientReadPlatformService readPlatformService,
final ClientWritePlatformService clientWritePlatformService, final OfficeReadPlatformService officeReadPlatformService,
final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer,
final DefaultToApiJsonSerializer<ClientData> toApiJsonSerializer, final ApiRequestParameterHelper apiRequestParameterHelper,
final PortfolioApiDataConversionService apiDataConversionService,
final PortfolioApiJsonSerializerService apiJsonSerializerService,
@@ -87,7 +84,6 @@ public class ClientsApiResource {
this.clientReadPlatformService = readPlatformService;
this.clientWritePlatformService = clientWritePlatformService;
this.officeReadPlatformService = officeReadPlatformService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.toApiJsonSerializer = toApiJsonSerializer;
this.apiRequestParameterHelper = apiRequestParameterHelper;
this.apiDataConversionService = apiDataConversionService;
@@ -152,8 +148,6 @@ public class ClientsApiResource {
extraCriteria = extraCriteria.substring(4);
}
// logger.info("extraCriteria; " + extraCriteria);
return extraCriteria;
}
@@ -237,10 +231,8 @@ public class ClientsApiResource {
final List<String> allowedPermissions = Arrays.asList("ALL_FUNCTIONS", "PORTFOLIO_MANAGEMENT_SUPER_USER", "CREATE_CLIENT");
context.authenticatedUser().validateHasPermissionTo("CREATE_CLIENT", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer.serializedCommandJsonFromApiJson(apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("CREATE", "clients", null,
commandSerializedAsJson);
apiRequestBodyAsJson);
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");
context.authenticatedUser().validateHasPermissionTo("UPDATE_CLIENT", allowedPermissions);
final String commandSerializedAsJson = this.fromApiJsonDeserializer
.serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
// 1. check json request body for create client
// final String commandSerializedAsJson = this.fromApiJsonDeserializer
// .serializedCommandJsonFromApiJson(clientId, apiRequestBodyAsJson);
final EntityIdentifier result = this.commandsSourceWritePlatformService.logCommandSource("UPDATE", "clients", clientId,
commandSerializedAsJson);
apiRequestBodyAsJson);
return this.toApiJsonSerializer.serialize(result);
}
@@ -1,8 +1,13 @@
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.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 clientOrBusinessName;
private final Long officeId;
private final LocalDate joiningDate;
private final LocalDate joinedDate;
// made transient as dont want them to be serialized/converted to JSON
private final transient Long id;
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;
public ClientCommand(final String externalId, final String firstname, final String lastname, final String clientOrBusinessName,
final Long officeId, final LocalDate joinedDate) {
this.externalId = externalId;
this.firstname = firstname;
this.lastname = lastname;
this.clientOrBusinessName = clientOrBusinessName;
this.officeId = officeId;
this.joiningDate = joiningDate;
this.makerCheckerApproval = makerCheckerApproval;
this.joinedDate = joinedDate;
}
public Long getId() {
return id;
public void validateForCreate() {
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() {
return externalId;
return this.externalId;
}
public String getFirstname() {
return firstname;
return this.firstname;
}
public String getLastname() {
return lastname;
return this.lastname;
}
public String getClientOrBusinessName() {
return clientOrBusinessName;
return this.clientOrBusinessName;
}
public Long getOfficeId() {
return officeId;
return this.officeId;
}
public LocalDate getJoiningDate() {
return joiningDate;
}
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;
return this.joinedDate;
}
}
@@ -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;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -12,51 +14,67 @@ import javax.persistence.TemporalType;
import org.apache.commons.lang.StringUtils;
import org.joda.time.LocalDate;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.domain.AbstractAuditableCustom;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.portfolio.client.command.ClientCommand;
import org.mifosplatform.useradministration.domain.AppUser;
@Entity
@Table(name = "m_client")
public class Client extends AbstractAuditableCustom<AppUser, Long> {
@ManyToOne
@ManyToOne
@JoinColumn(name = "office_id", nullable = false)
private Office office;
private Office office;
@Column(name = "firstname", length=50)
private String firstName;
@Column(name = "lastname", length=50)
private String lastName;
@Column(name = "display_name", length=50)
private String displayName;
@Column(name = "firstname", length = 50)
private String firstName;
@Column(name = "joining_date")
@Column(name = "lastname", length = 50)
private String lastName;
@Column(name = "display_name", length = 50)
private String displayName;
@Column(name = "joined_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;
@Column(name = "is_deleted", nullable=false)
private boolean deleted = false;
@Column(name = "image_key", length=500)
@Column(name = "is_deleted", nullable = false)
private boolean deleted = false;
@Column(name = "image_key", length = 500)
private String imageKey;
public static Client newClient(Office clientOffice, String firstname, String lastname, LocalDate joiningDate, String externalId) {
return new Client(clientOffice, firstname, lastname, joiningDate, externalId);
}
public static Client fromJson(final Office clientOffice, final JsonCommand command) {
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() {
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) {
@@ -66,160 +84,190 @@ public class Client extends AbstractAuditableCustom<AppUser, Long> {
} else {
this.externalId = null;
}
this.joiningDate = openingDate.toDateMidnight().toDate();
this.joinedDate = openingDate.toDateMidnight().toDate();
if (StringUtils.isNotBlank(firstName)) {
this.firstName = firstName.trim();
this.firstName = firstName.trim();
} else {
this.firstName = null;
this.firstName = null;
}
this.lastName = lastName.trim();
//populate display name
if(this.firstName!=null){
this.displayName = this.firstName + " " + this.lastName;
}else{
this.displayName = this.lastName;
// populate display name
if (this.firstName != null) {
this.displayName = this.firstName + " " + this.lastName;
} else {
this.displayName = this.lastName;
}
}
public boolean identifiedBy(final String identifier) {
return identifier.equalsIgnoreCase(this.externalId);
}
public boolean identifiedBy(Long clientId) {
return getId().equals(clientId);
}
public boolean identifiedBy(final String identifier) {
return identifier.equalsIgnoreCase(this.externalId);
}
public void update(ClientCommand command) {
this.joiningDate = command.getJoiningDate().toDate();
this.firstName = command.getFirstname();
this.lastName = command.getLastname();
if (StringUtils.isNotBlank(command.getClientOrBusinessName())) {
this.firstName = null;
this.lastName = command.getClientOrBusinessName().trim();
this.displayName = this.lastName;
}else{
deriveDisplayName();
}
if (StringUtils.isNotBlank(command.getExternalId())) {
this.externalId = command.getExternalId().trim();
} else {
this.externalId = null;
public boolean identifiedBy(Long clientId) {
return getId().equals(clientId);
}
public void changeOffice(final Office newOffice) {
this.office = newOffice;
}
public Map<String, Object> update(final JsonCommand command) {
final Map<String, Object> actualChanges = new LinkedHashMap<String, Object>(7);
final String dateFormatAsInput = command.dateFormat();
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);
}
}
final String joiningDateParamName = "joinedDate";
if (command.isChangeInLocalDateParameterNamed(joiningDateParamName, getJoiningLocalDate())) {
final String valueAsInput = command.stringValueOfParameterNamed(joiningDateParamName);
actualChanges.put(joiningDateParamName, valueAsInput);
actualChanges.put("dateFormat", dateFormatAsInput);
actualChanges.put("locale", localeAsInput);
final LocalDate newValue = command.localDateValueOfParameterNamed(joiningDateParamName);
this.joinedDate = newValue.toDate();
}
final String firstnameParamName = "firstname";
if (command.isChangeInStringParameterNamed(firstnameParamName, this.firstName)) {
final String newValue = command.stringValueOfParameterNamed(firstnameParamName);
actualChanges.put(firstnameParamName, newValue);
this.firstName = newValue;
}
final String lastnameParamName = "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;
}
public void update(final Office clientOffice, final ClientCommand command) {
if (command.isOfficeChanged()) {
this.office = clientOffice;
}
if (command.isJoiningDateChanged()) {
this.joiningDate = command.getJoiningDate().toDate();
}
if (command.isFirstnameChanged()) {
this.firstName = command.getFirstname();
}
if (command.isLastnameChanged()) {
this.lastName = command.getLastname();
}
if (command.isClientOrBusinessNameChanged() && StringUtils.isNotBlank(command.getClientOrBusinessName())) {
this.lastName = command.getClientOrBusinessName();
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()) {
this.externalId = StringUtils.defaultIfEmpty(command.getExternalId(), null);
}
}
private void deriveDisplayName() {
this.displayName = this.firstName + " " + this.lastName;
}
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.
*
* Any fields with unique constraints and prepended with id of record.
*/
public void delete() {
this.deleted = true;
this.externalId = this.getId() + "_" + this.externalId;
}
* Delete is a <i>soft delete</i>. Updates flag on client so it wont appear
* in query/report results.
*
* Any fields with unique constraints and prepended with id of record.
*/
public void delete() {
this.deleted = true;
this.externalId = this.getId() + "_" + this.externalId;
}
public boolean isDeleted() {
return deleted;
}
public boolean isDeleted() {
return deleted;
}
public boolean isOfficeIdentifiedBy(final Long officeId) {
return this.office.identifiedBy(officeId);
}
public boolean isOfficeIdentifiedBy(final Long officeId) {
return this.office.identifiedBy(officeId);
}
public Office getOffice() {
return office;
}
public Office getOffice() {
return office;
}
public void setOffice(Office office) {
this.office = office;
}
public void setOffice(Office office) {
this.office = office;
}
public String getFirstName() {
return firstName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDisplayName() {
return displayName;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public Date getJoiningDate() {
return joiningDate;
}
public Date getJoiningDate() {
return joinedDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joinedDate = joiningDate;
}
public String getExternalId() {
return externalId;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public String getImageKey() {
return imageKey;
}
public String getImageKey() {
return imageKey;
}
public void setImageKey(String imageKey) {
this.imageKey = imageKey;
}
public void setImageKey(String imageKey) {
this.imageKey = imageKey;
}
}
@@ -7,6 +7,7 @@ import java.util.Map;
import java.util.Set;
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.FromApiJsonDeserializer;
import org.mifosplatform.infrastructure.core.serialization.FromJsonHelper;
@@ -22,30 +23,24 @@ import com.google.gson.reflect.TypeToken;
* 's.
*/
@Component
public final class ClientCommandFromApiJsonDeserializer implements FromApiJsonDeserializer<ClientCommand> {
public final class ClientCommandFromApiJsonDeserializer extends AbstractFromApiJsonDeserializer<ClientCommand> {
/**
* The parameters supported for this command.
*/
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 CommandSerializer commandSerializerService;
@Autowired
public ClientCommandFromApiJsonDeserializer(final FromJsonHelper fromApiJsonHelper, final CommandSerializer commandSerializerService) {
super(commandSerializerService);
this.fromApiJsonHelper = fromApiJsonHelper;
this.commandSerializerService = commandSerializerService;
}
@Override
public ClientCommand commandFromApiJson(final String json) {
return commandFromApiJson(null, json);
}
@Override
public ClientCommand commandFromApiJson(final Long clientId, final String json) {
public ClientCommand commandFromApiJson(@SuppressWarnings("unused") final Long clientId, final String json) {
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
@@ -62,19 +57,6 @@ public final class ClientCommandFromApiJsonDeserializer implements FromApiJsonDe
.extractStringNamed("clientOrBusinessName", element, parametersPassedInRequest);
final LocalDate joiningDate = fromApiJsonHelper.extractLocalDateNamed("joiningDate", element, parametersPassedInRequest);
return new ClientCommand(parametersPassedInRequest, clientId, externalId, firstname, lastname, clientOrBusinessName, officeId,
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);
return new ClientCommand(externalId, firstname, lastname, clientOrBusinessName, officeId, joiningDate);
}
}
@@ -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() {
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 ";
}
@@ -2,20 +2,20 @@ package org.mifosplatform.portfolio.client.service;
import java.io.InputStream;
import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.EntityIdentifier;
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.ClientNoteCommand;
import org.springframework.security.access.prepost.PreAuthorize;
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')")
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.IOException;
import java.io.InputStream;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepository;
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.domain.Base64EncodedImage;
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.exception.OfficeNotFoundException;
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.ClientIdentifierCommandValidator;
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.DuplicateClientIdentifierException;
import org.mifosplatform.portfolio.client.exception.NoteNotFoundException;
import org.mifosplatform.portfolio.client.serialization.ClientCommandFromApiJsonDeserializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,12 +54,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final NoteRepository noteRepository;
private final CodeValueRepository codeValueRepository;
private final ConfigurationDomainService configurationDomainService;
private final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer;
@Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final ClientRepository clientRepository,
final ClientIdentifierRepository clientIdentifierRepository, final OfficeRepository officeRepository,
final NoteRepository noteRepository, final CodeValueRepository codeValueRepository,
final ConfigurationDomainService configurationDomainService) {
final ConfigurationDomainService configurationDomainService, final ClientCommandFromApiJsonDeserializer fromApiJsonDeserializer) {
this.context = context;
this.clientRepository = clientRepository;
this.clientIdentifierRepository = clientIdentifierRepository;
@@ -65,13 +68,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.noteRepository = noteRepository;
this.codeValueRepository = codeValueRepository;
this.configurationDomainService = configurationDomainService;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
}
@Transactional
@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);
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
* is.
*/
private void handleDataIntegrityIssues(final ClientCommand command, final DataIntegrityViolationException dve) {
private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) {
Throwable realCause = dve.getMostSpecificCause();
if (realCause.getMessage().contains("external_id")) { throw new PlatformDataIntegrityException(
"error.msg.client.duplicate.externalId", "Client with externalId `" + command.getExternalId() + "` already exists",
"externalId", command.getExternalId()); }
if (realCause.getMessage().contains("external_id")) {
final String externalId = command.stringValueOfParameterNamed("externalId");
throw new PlatformDataIntegrityException("error.msg.client.duplicate.externalId", "Client with externalId `" + externalId
+ "` already exists", "externalId", externalId);
}
logAsErrorUnexpectedDataIntegrityException(dve);
throw new PlatformDataIntegrityException("error.msg.client.unknown.data.integrity.issue",
@@ -101,26 +107,21 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public Long createClient(final ClientCommand command) {
public Long createClient(final JsonCommand command) {
try {
context.authenticatedUser();
final ClientCommandValidator validator = new ClientCommandValidator(command);
validator.validateForCreate();
final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
clientCommand.validateForCreate();
final Office clientOffice = this.officeRepository.findOne(command.getOfficeId());
if (clientOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
final String officeIdParamName = "officeId";
final Long officeId = command.longValueOfParameterNamed(officeIdParamName);
String firstname = command.getFirstname();
String lastname = command.getLastname();
if (StringUtils.isNotBlank(command.getClientOrBusinessName())) {
lastname = command.getClientOrBusinessName();
firstname = null;
}
final Client newClient = Client.newClient(clientOffice, firstname, lastname, command.getJoiningDate(), command.getExternalId());
final Office clientOffice = this.officeRepository.findOne(officeId);
if (clientOffice == null) { throw new OfficeNotFoundException(officeId); }
final Client newClient = Client.fromJson(clientOffice, command);
this.clientRepository.save(newClient);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("CREATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
@@ -134,30 +135,31 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public EntityIdentifier updateClientDetails(final ClientCommand command) {
public EntityIdentifier updateClientDetails(final Long clientId, final JsonCommand command) {
try {
context.authenticatedUser();
final ClientCommandValidator validator = new ClientCommandValidator(command);
validator.validateForUpdate();
final ClientCommand clientCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
clientCommand.validateForUpdate();
Office clientOffice = null;
Long officeId = command.getOfficeId();
if (command.isOfficeChanged() && officeId != null) {
clientOffice = this.officeRepository.findOne(officeId);
if (clientOffice == null) { throw new OfficeNotFoundException(command.getOfficeId()); }
final Client clientForUpdate = this.clientRepository.findOne(clientId);
if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(clientId); }
final Map<String, Object> changesOnly = clientForUpdate.update(command);
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());
if (clientForUpdate == null || clientForUpdate.isDeleted()) { throw new ClientNotFoundException(command.getId()); }
clientForUpdate.update(clientOffice, command);
this.clientRepository.saveAndFlush(clientForUpdate);
this.clientRepository.save(clientForUpdate);
if (this.configurationDomainService.isMakerCheckerEnabledForTask("UPDATE_CLIENT") && !command.isApprovedByChecker()) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(); }
return new EntityIdentifier(clientForUpdate.getId());
return EntityIdentifier.withChanges(clientId, changesOnly);
} catch (DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve);
return new EntityIdentifier(Long.valueOf(-1));