Merge pull request #774 from pramodn02/MIFOSX-929

MIFOSX-929 - added check for multiple permission for client
This commit is contained in:
Vishwas Babu A J
2014-02-28 11:09:58 -08:00
7 changed files with 74 additions and 23 deletions
@@ -9,11 +9,14 @@ import org.mifosplatform.commands.domain.CommandSource;
import org.mifosplatform.commands.domain.CommandWrapper; import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
import org.mifosplatform.useradministration.domain.AppUser;
public interface CommandProcessingService { public interface CommandProcessingService {
CommandProcessingResult processAndLogCommand(CommandWrapper wrapper, JsonCommand command, boolean isApprovedByChecker); CommandProcessingResult processAndLogCommand(CommandWrapper wrapper, JsonCommand command, boolean isApprovedByChecker);
CommandProcessingResult logCommand(CommandSource commandSourceResult); CommandProcessingResult logCommand(CommandSource commandSourceResult);
boolean validateCommand(final CommandWrapper commandWrapper,final AppUser user);
} }
@@ -53,8 +53,7 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
public CommandProcessingResult processAndLogCommand(final CommandWrapper wrapper, final JsonCommand command, public CommandProcessingResult processAndLogCommand(final CommandWrapper wrapper, final JsonCommand command,
final boolean isApprovedByChecker) { final boolean isApprovedByChecker) {
final boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName()) final boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(wrapper.taskPermissionName());
&& !isApprovedByChecker;
final NewCommandSourceHandler handler = findCommandHandler(wrapper); final NewCommandSourceHandler handler = findCommandHandler(wrapper);
final CommandProcessingResult result = handler.processCommand(command); final CommandProcessingResult result = handler.processCommand(command);
@@ -86,8 +85,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
this.commandSourceRepository.save(commandSourceResult); this.commandSourceRepository.save(commandSourceResult);
} }
if (rollbackTransaction) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(commandSourceResult); } if ((rollbackTransaction || result.isRollbackTransaction()) && !isApprovedByChecker) { throw new RollbackTransactionAsCommandIsNotApprovedByCheckerException(commandSourceResult); }
result.setRollbackTransaction(null);
return result; return result;
} }
@@ -627,4 +626,11 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
return handler; return handler;
} }
@Override
public boolean validateCommand(final CommandWrapper commandWrapper, final AppUser user) {
boolean rollbackTransaction = this.configurationDomainService.isMakerCheckerEnabledForTask(commandWrapper.taskPermissionName());
user.validateHasPermissionTo(commandWrapper.getTaskPermissionName());
return rollbackTransaction;
}
} }
@@ -26,12 +26,13 @@ public class CommandProcessingResult {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String resourceIdentifier; private final String resourceIdentifier;
private final Long productId; private final Long productId;
private Boolean rollbackTransaction;
public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId, public static CommandProcessingResult fromDetails(final Long commandId, final Long officeId, final Long groupId, final Long clientId,
final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final String transactionId, final Long loanId, final Long savingsId, final String resourceIdentifier, final Long entityId, final String transactionId,
final Map<String, Object> changes, final Long productId) { final Map<String, Object> changes, final Long productId,final Boolean rollbackTransaction) {
return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId, return new CommandProcessingResult(commandId, officeId, groupId, clientId, loanId, savingsId, resourceIdentifier, entityId,
transactionId, changes, productId); transactionId, changes, productId,rollbackTransaction);
} }
public static CommandProcessingResult commandOnlyResult(final Long commandId) { public static CommandProcessingResult commandOnlyResult(final Long commandId) {
@@ -85,7 +86,7 @@ public class CommandProcessingResult {
private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId, private CommandProcessingResult(final Long commandId, final Long officeId, final Long groupId, final Long clientId, final Long loanId,
final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId, final Long savingsId, final String resourceIdentifier, final Long resourceId, final String transactionId,
final Map<String, Object> changesOnly, final Long productId) { final Map<String, Object> changesOnly, final Long productId, Boolean rollbackTransaction) {
this.commandId = commandId; this.commandId = commandId;
this.officeId = officeId; this.officeId = officeId;
this.groupId = groupId; this.groupId = groupId;
@@ -97,6 +98,7 @@ public class CommandProcessingResult {
this.changes = changesOnly; this.changes = changesOnly;
this.transactionId = transactionId; this.transactionId = transactionId;
this.productId = productId; this.productId = productId;
this.rollbackTransaction = rollbackTransaction;
} }
private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map<String, Object> changesOnly) { private CommandProcessingResult(final Long resourceId, final Long officeId, final Long commandId, final Map<String, Object> changesOnly) {
@@ -169,4 +171,14 @@ public class CommandProcessingResult {
public Long getProductId() { public Long getProductId() {
return this.productId; return this.productId;
} }
public boolean isRollbackTransaction() {
return this.rollbackTransaction!=null && this.rollbackTransaction;
}
public void setRollbackTransaction(Boolean rollbackTransaction) {
this.rollbackTransaction = rollbackTransaction;
}
} }
@@ -24,10 +24,11 @@ public class CommandProcessingResultBuilder {
private String transactionId; private String transactionId;
private Map<String, Object> changes; private Map<String, Object> changes;
private Long productId; private Long productId;
private boolean rollbackTransaction = false;
public CommandProcessingResult build() { public CommandProcessingResult build() {
return CommandProcessingResult.fromDetails(this.commandId, this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId, return CommandProcessingResult.fromDetails(this.commandId, this.officeId, this.groupId, this.clientId, this.loanId, this.savingsId,
this.resourceIdentifier, this.entityId, this.transactionId, this.changes, this.productId); this.resourceIdentifier, this.entityId, this.transactionId, this.changes, this.productId,this.rollbackTransaction);
} }
public CommandProcessingResultBuilder withCommandId(final Long withCommandId) { public CommandProcessingResultBuilder withCommandId(final Long withCommandId) {
@@ -84,5 +85,10 @@ public class CommandProcessingResultBuilder {
this.productId = productId; this.productId = productId;
return this; return this;
} }
public CommandProcessingResultBuilder setRollbackTransaction(final boolean rollbackTransaction) {
this.rollbackTransaction = this.rollbackTransaction || rollbackTransaction;
return this;
}
} }
@@ -13,6 +13,9 @@ import java.util.Map;
import org.joda.time.LocalDate; import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.DateTimeFormatter;
import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandProcessingService;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.infrastructure.codes.domain.CodeValue; import org.mifosplatform.infrastructure.codes.domain.CodeValue;
import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper; import org.mifosplatform.infrastructure.codes.domain.CodeValueRepositoryWrapper;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
@@ -77,6 +80,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
private final SavingsAccountRepository savingsRepository; private final SavingsAccountRepository savingsRepository;
private final SavingsProductRepository savingsProductRepository; private final SavingsProductRepository savingsProductRepository;
private final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService; private final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService;
private final CommandProcessingService commandProcessingService;
@Autowired @Autowired
public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -85,7 +89,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final GroupRepository groupRepository, final StaffRepositoryWrapper staffRepository, final GroupRepository groupRepository, final StaffRepositoryWrapper staffRepository,
final CodeValueRepositoryWrapper codeValueRepository, final LoanRepository loanRepository, final CodeValueRepositoryWrapper codeValueRepository, final LoanRepository loanRepository,
final SavingsAccountRepository savingsRepository,final SavingsProductRepository savingsProductRepository, final SavingsAccountRepository savingsRepository,final SavingsProductRepository savingsProductRepository,
final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService) { final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService,
final CommandProcessingService commandProcessingService) {
this.context = context; this.context = context;
this.clientRepository = clientRepository; this.clientRepository = clientRepository;
this.officeRepository = officeRepository; this.officeRepository = officeRepository;
@@ -99,6 +104,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
this.savingsRepository = savingsRepository; this.savingsRepository = savingsRepository;
this.savingsProductRepository = savingsProductRepository; this.savingsProductRepository = savingsProductRepository;
this.savingsApplicationProcessWritePlatformService = savingsApplicationProcessWritePlatformService; this.savingsApplicationProcessWritePlatformService = savingsApplicationProcessWritePlatformService;
this.commandProcessingService = commandProcessingService;
} }
@Transactional @Transactional
@@ -185,6 +191,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
} }
final Client newClient = Client.createNew(currentUser,clientOffice, clientParentGroup, staff, savingsProduct, command); final Client newClient = Client.createNew(currentUser,clientOffice, clientParentGroup, staff, savingsProduct, command);
boolean rollbackTransaction = false;
if(newClient.isActive()){
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build();
rollbackTransaction = this.commandProcessingService.validateCommand(commandWrapper, currentUser);
}
this.clientRepository.save(newClient); this.clientRepository.save(newClient);
@@ -197,7 +208,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final Locale locale = command.extractLocale(); final Locale locale = command.extractLocale();
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
Long savingsId = openOverdraftSavingsAccount(newClient, fmt); CommandProcessingResult result = openOverdraftSavingsAccount(newClient, fmt);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //
@@ -205,7 +216,9 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.withClientId(newClient.getId()) // .withClientId(newClient.getId()) //
.withGroupId(groupId) // .withGroupId(groupId) //
.withEntityId(newClient.getId()) // .withEntityId(newClient.getId()) //
.withSavingsId(savingsId)// .withSavingsId(result.getSavingsId())//
.setRollbackTransaction(rollbackTransaction)//
.setRollbackTransaction(result.isRollbackTransaction())//
.build(); .build();
} catch (final DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
@@ -284,7 +297,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final AppUser currentUser = this.context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
client.activate(currentUser, fmt, activationDate); client.activate(currentUser, fmt, activationDate);
Long savingsId = openOverdraftSavingsAccount(client, fmt); CommandProcessingResult result = openOverdraftSavingsAccount(client, fmt);
this.clientRepository.saveAndFlush(client); this.clientRepository.saveAndFlush(client);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
@@ -292,7 +305,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
.withOfficeId(client.officeId()) // .withOfficeId(client.officeId()) //
.withClientId(clientId) // .withClientId(clientId) //
.withEntityId(clientId) // .withEntityId(clientId) //
.withSavingsId(savingsId)// .withSavingsId(result.getSavingsId())//
.setRollbackTransaction(result.isRollbackTransaction())//
.build(); .build();
} catch (final DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
handleDataIntegrityIssues(command, dve); handleDataIntegrityIssues(command, dve);
@@ -300,17 +314,17 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
} }
} }
private Long openOverdraftSavingsAccount(final Client client, final DateTimeFormatter fmt) { private CommandProcessingResult openOverdraftSavingsAccount(final Client client, final DateTimeFormatter fmt) {
Long accountId = null; CommandProcessingResult commandProcessingResult = CommandProcessingResult.empty();
if(client.isActive() && client.SavingsProduct() != null){ if(client.isActive() && client.SavingsProduct() != null){
if(!client.SavingsProduct().isAllowOverdraft()){ if(!client.SavingsProduct().isAllowOverdraft()){
String defaultUserMessage = "Client's saving account must be a overdraft account"; String defaultUserMessage = "Client's saving account must be a overdraft account";
throw new InvalidClientSavingProductException("saving.product", "must.be.ovrdraft.account", defaultUserMessage, client.SavingsProduct().getId(),client.getId()); throw new InvalidClientSavingProductException("saving.product", "must.be.ovrdraft.account", defaultUserMessage, client.SavingsProduct().getId(),client.getId());
} }
SavingsAccountDataDTO savingsAccountDataDTO = new SavingsAccountDataDTO(client, null, client.SavingsProduct(), client.getActivationLocalDate(), client.activatedBy(), fmt); SavingsAccountDataDTO savingsAccountDataDTO = new SavingsAccountDataDTO(client, null, client.SavingsProduct(), client.getActivationLocalDate(), client.activatedBy(), fmt);
accountId = this.savingsApplicationProcessWritePlatformService.createActiveApplication(savingsAccountDataDTO); commandProcessingResult = this.savingsApplicationProcessWritePlatformService.createActiveApplication(savingsAccountDataDTO);
} }
return accountId; return commandProcessingResult;
} }
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
@@ -25,5 +25,5 @@ public interface SavingsApplicationProcessWritePlatformService {
CommandProcessingResult applicantWithdrawsFromApplication(Long savingsId, JsonCommand command); CommandProcessingResult applicantWithdrawsFromApplication(Long savingsId, JsonCommand command);
Long createActiveApplication(SavingsAccountDataDTO savingsAccountDataDTO); CommandProcessingResult createActiveApplication(SavingsAccountDataDTO savingsAccountDataDTO);
} }
@@ -8,14 +8,15 @@ package org.mifosplatform.portfolio.savings.service;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.joda.time.format.DateTimeFormatter; import org.mifosplatform.commands.domain.CommandWrapper;
import org.mifosplatform.commands.service.CommandProcessingService;
import org.mifosplatform.commands.service.CommandWrapperBuilder;
import org.mifosplatform.infrastructure.core.api.JsonCommand; import org.mifosplatform.infrastructure.core.api.JsonCommand;
import org.mifosplatform.infrastructure.core.data.ApiParameterError; import org.mifosplatform.infrastructure.core.data.ApiParameterError;
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult; import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
@@ -75,6 +76,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
private final StaffRepositoryWrapper staffRepository; private final StaffRepositoryWrapper staffRepository;
private final SavingsAccountApplicationTransitionApiJsonValidator savingsAccountApplicationTransitionApiJsonValidator; private final SavingsAccountApplicationTransitionApiJsonValidator savingsAccountApplicationTransitionApiJsonValidator;
private final SavingsAccountChargeAssembler savingsAccountChargeAssembler; private final SavingsAccountChargeAssembler savingsAccountChargeAssembler;
private final CommandProcessingService commandProcessingService;
@Autowired @Autowired
public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -84,7 +86,8 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository, final GroupRepository groupRepository, final SavingsProductRepository savingsProductRepository,
final NoteRepository noteRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository, final StaffRepositoryWrapper staffRepository,
final SavingsAccountApplicationTransitionApiJsonValidator savingsAccountApplicationTransitionApiJsonValidator, final SavingsAccountApplicationTransitionApiJsonValidator savingsAccountApplicationTransitionApiJsonValidator,
final SavingsAccountChargeAssembler savingsAccountChargeAssembler) { final SavingsAccountChargeAssembler savingsAccountChargeAssembler,
final CommandProcessingService commandProcessingService) {
this.context = context; this.context = context;
this.savingAccountRepository = savingAccountRepository; this.savingAccountRepository = savingAccountRepository;
this.savingAccountAssembler = savingAccountAssembler; this.savingAccountAssembler = savingAccountAssembler;
@@ -97,6 +100,7 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
this.staffRepository = staffRepository; this.staffRepository = staffRepository;
this.savingsAccountApplicationTransitionApiJsonValidator = savingsAccountApplicationTransitionApiJsonValidator; this.savingsAccountApplicationTransitionApiJsonValidator = savingsAccountApplicationTransitionApiJsonValidator;
this.savingsAccountChargeAssembler = savingsAccountChargeAssembler; this.savingsAccountChargeAssembler = savingsAccountChargeAssembler;
this.commandProcessingService = commandProcessingService;
} }
/* /*
@@ -433,7 +437,10 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
} }
@Override @Override
public Long createActiveApplication(final SavingsAccountDataDTO savingsAccountDataDTO) { public CommandProcessingResult createActiveApplication(final SavingsAccountDataDTO savingsAccountDataDTO) {
final CommandWrapper commandWrapper = new CommandWrapperBuilder().savingsAccountActivation(null).build();
boolean rollbackTransaction = this.commandProcessingService.validateCommand(commandWrapper, savingsAccountDataDTO.getAppliedBy());
final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsAccountDataDTO.getClient(),savingsAccountDataDTO.getGroup(), final SavingsAccount account = this.savingAccountAssembler.assembleFrom(savingsAccountDataDTO.getClient(),savingsAccountDataDTO.getGroup(),
savingsAccountDataDTO.getSavingsProduct(),savingsAccountDataDTO.getApplicationDate(),savingsAccountDataDTO.getAppliedBy()); savingsAccountDataDTO.getSavingsProduct(),savingsAccountDataDTO.getApplicationDate(),savingsAccountDataDTO.getAppliedBy());
@@ -446,6 +453,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
account.updateAccountNo(accountNoGenerator.generate()); account.updateAccountNo(accountNoGenerator.generate());
this.savingAccountRepository.save(account); this.savingAccountRepository.save(account);
} }
return account.getId(); return new CommandProcessingResultBuilder() //
.withSavingsId(account.getId()) //
.setRollbackTransaction(rollbackTransaction)//
.build();
} }
} }