Merge branch 'master' into develop
This commit is contained in:
@@ -621,6 +621,10 @@ public class CommandWrapper {
|
||||
return this.actionName.equalsIgnoreCase("PROPOSETRANSFER") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
public boolean isProposeAndAcceptClientTransfer() {
|
||||
return this.actionName.equalsIgnoreCase("PROPOSEANDACCEPTTRANSFER") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
public boolean isWithdrawClientTransfer() {
|
||||
return this.actionName.equalsIgnoreCase("WITHDRAWTRANSFER") && this.entityName.equalsIgnoreCase("CLIENT");
|
||||
}
|
||||
|
||||
+9
@@ -362,6 +362,15 @@ public class CommandWrapperBuilder {
|
||||
this.href = "/clientId/" + clientId + "?command=proposeTransfer";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder proposeAndAcceptClientTransfer(final Long clientId) {
|
||||
this.actionName = "PROPOSEANDACCEPTTRANSFER";
|
||||
this.entityName = "CLIENT";
|
||||
this.entityId = clientId;
|
||||
this.clientId = clientId;
|
||||
this.href = "/clientId/" + clientId + "?command=proposeAndAcceptTransfer";
|
||||
return this;
|
||||
}
|
||||
|
||||
public CommandWrapperBuilder withdrawClientTransferRequest(final Long clientId) {
|
||||
this.actionName = "WITHDRAWTRANSFER";
|
||||
|
||||
+2
@@ -170,6 +170,8 @@ public class SynchronousCommandProcessingService implements CommandProcessingSer
|
||||
handler = this.applicationContext.getBean("closeClientCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isProposeClientTransfer()) {
|
||||
handler = this.applicationContext.getBean("proposeClientTransferCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isProposeAndAcceptClientTransfer()) {
|
||||
handler = this.applicationContext.getBean("proposeAndAcceptClientTransferCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isWithdrawClientTransfer()) {
|
||||
handler = this.applicationContext.getBean("withdrawClientTransferCommandHandler", NewCommandSourceHandler.class);
|
||||
} else if (wrapper.isAcceptClientTransfer()) {
|
||||
|
||||
+3
@@ -212,6 +212,9 @@ public class ClientsApiResource {
|
||||
} else if (is(commandParam, "proposeTransfer")) {
|
||||
commandRequest = builder.proposeClientTransfer(clientId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "proposeAndAcceptTransfer")) {
|
||||
commandRequest = builder.proposeAndAcceptClientTransfer(clientId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
} else if (is(commandParam, "withdrawTransfer")) {
|
||||
commandRequest = builder.withdrawClientTransferRequest(clientId).build();
|
||||
result = this.commandsSourceWritePlatformService.logCommandSource(commandRequest);
|
||||
|
||||
+7
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
package org.mifosplatform.portfolio.group.domain;
|
||||
|
||||
import org.mifosplatform.organisation.office.domain.Office;
|
||||
import org.mifosplatform.portfolio.group.exception.GroupNotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -31,6 +32,12 @@ public class GroupRepositoryWrapper {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Group findByOfficeWithNotFoundDetection(final Long id, final Office office) {
|
||||
final Group group = findOneWithNotFoundDetection(id);
|
||||
if (group.getOffice().getId() != office.getId()) { throw new GroupNotFoundException(id); }
|
||||
return group;
|
||||
}
|
||||
|
||||
public void save(final Group entity) {
|
||||
this.repository.save(entity);
|
||||
}
|
||||
|
||||
+5
-4
@@ -19,8 +19,9 @@ public enum SavingsAccountTransactionType {
|
||||
INTEREST_POSTING(3, "savingsAccountTransactionType.interestPosting"), //
|
||||
WITHDRAWAL_FEE(4, "savingsAccountTransactionType.withdrawalFee"), //
|
||||
ANNUAL_FEE(5, "savingsAccountTransactionType.annualFee"), //
|
||||
WAIVE_CHARGES(6, "savingsAccountTransactionType.waiveCharges"), APPLY_CHARGES(7, "savingsAccountTransactionType.applyCharges"), INITIATE_TRANSFER(
|
||||
12, "savingsAccountTransactionType.initiateTransfer"), //
|
||||
WAIVE_CHARGES(6, "savingsAccountTransactionType.waiveCharges"), //
|
||||
PAY_CHARGE(7, "savingsAccountTransactionType.payCharge"), //
|
||||
INITIATE_TRANSFER(12, "savingsAccountTransactionType.initiateTransfer"), //
|
||||
APPROVE_TRANSFER(13, "savingsAccountTransactionType.approveTransfer"), //
|
||||
WITHDRAW_TRANSFER(14, "savingsAccountTransactionType.withdrawTransfer"), //
|
||||
REJECT_TRANSFER(15, "savingsAccountTransactionType.rejectTransfer");
|
||||
@@ -66,7 +67,7 @@ public enum SavingsAccountTransactionType {
|
||||
savingsAccountTransactionType = SavingsAccountTransactionType.WAIVE_CHARGES;
|
||||
break;
|
||||
case 7:
|
||||
savingsAccountTransactionType = SavingsAccountTransactionType.APPLY_CHARGES;
|
||||
savingsAccountTransactionType = SavingsAccountTransactionType.PAY_CHARGE;
|
||||
break;
|
||||
case 12:
|
||||
savingsAccountTransactionType = SavingsAccountTransactionType.INITIATE_TRANSFER;
|
||||
@@ -105,7 +106,7 @@ public enum SavingsAccountTransactionType {
|
||||
}
|
||||
|
||||
public boolean isCharge() {
|
||||
return this.value.equals(SavingsAccountTransactionType.APPLY_CHARGES.getValue());
|
||||
return this.value.equals(SavingsAccountTransactionType.PAY_CHARGE.getValue());
|
||||
}
|
||||
|
||||
public boolean isWaiveCharge() {
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ public class SavingsAccountTransactionEnumData {
|
||||
this.withdrawal = Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL.getValue()).equals(this.id);
|
||||
this.interestPosting = Long.valueOf(SavingsAccountTransactionType.INTEREST_POSTING.getValue()).equals(this.id);
|
||||
this.feeDeduction = Long.valueOf(SavingsAccountTransactionType.ANNUAL_FEE.getValue()).equals(this.id)
|
||||
|| Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id);
|
||||
|| Long.valueOf(SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue()).equals(this.id)
|
||||
|| Long.valueOf(SavingsAccountTransactionType.PAY_CHARGE.getValue()).equals(this.id);
|
||||
this.initiateTransfer = Long.valueOf(SavingsAccountTransactionType.INITIATE_TRANSFER.getValue()).equals(this.id);
|
||||
this.approveTransfer = Long.valueOf(SavingsAccountTransactionType.APPROVE_TRANSFER.getValue()).equals(this.id);
|
||||
this.withdrawTransfer = Long.valueOf(SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue()).equals(this.id);
|
||||
|
||||
+1
-1
@@ -131,7 +131,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
|
||||
public static SavingsAccountTransaction charge(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
|
||||
final Money amount) {
|
||||
final boolean isReversed = false;
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.APPLY_CHARGES.getValue(), date, amount,
|
||||
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.PAY_CHARGE.getValue(), date, amount,
|
||||
isReversed);
|
||||
}
|
||||
|
||||
|
||||
+7
@@ -514,6 +514,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.getTransactions().add(newTransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.TRANSFER_IN_PROGRESS.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(newTransferTransaction);
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
@@ -534,6 +536,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
savingsAccount.office(), transferDate);
|
||||
savingsAccount.getTransactions().add(withdrawtransferTransaction);
|
||||
savingsAccount.setStatus(SavingsAccountStatusType.ACTIVE.getValue());
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(withdrawtransferTransaction);
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
@@ -565,6 +569,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
||||
if (fieldOfficer != null) {
|
||||
savingsAccount.update(fieldOfficer);
|
||||
}
|
||||
|
||||
final MathContext mc = MathContext.DECIMAL64;
|
||||
savingsAccount.calculateInterestUsing(mc, transferDate);
|
||||
|
||||
this.savingsAccountTransactionRepository.save(acceptTransferTransaction);
|
||||
this.savingAccountRepository.save(savingsAccount);
|
||||
|
||||
+3
-3
@@ -101,9 +101,9 @@ public class SavingsEnumerations {
|
||||
SavingsAccountTransactionType.WITHDRAW_TRANSFER.getCode(), "Transfer Withdrawn");
|
||||
break;
|
||||
default:
|
||||
case APPLY_CHARGES:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.APPLY_CHARGES.getValue().longValue(),
|
||||
SavingsAccountTransactionType.APPLY_CHARGES.getCode(), "Apply Charge");
|
||||
case PAY_CHARGE:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.PAY_CHARGE.getValue().longValue(),
|
||||
SavingsAccountTransactionType.PAY_CHARGE.getCode(), "Pay Charge");
|
||||
break;
|
||||
case WAIVE_CHARGES:
|
||||
optionData = new SavingsAccountTransactionEnumData(SavingsAccountTransactionType.WAIVE_CHARGES.getValue().longValue(),
|
||||
|
||||
+3
@@ -35,6 +35,9 @@ public class TransferApiConstants {
|
||||
public static final Set<String> ACCEPT_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(newStaffIdParamName,
|
||||
destinationGroupIdParamName, note));
|
||||
|
||||
public static final Set<String> PROPOSE_AND_ACCEPT_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(localeParamName,
|
||||
dateFormatParamName, destinationOfficeIdParamName, transferActiveLoans, newStaffIdParamName, destinationGroupIdParamName, note));
|
||||
|
||||
public static final Set<String> REJECT_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(note));
|
||||
|
||||
public static final Set<String> WITHDRAW_CLIENT_TRANSFER_DATA_PARAMETERS = new HashSet<String>(Arrays.asList(note));
|
||||
|
||||
+35
@@ -125,6 +125,41 @@ public final class TransfersDataValidator {
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForProposeAndAcceptClientTransfer(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
final Type typeOfMap = new TypeToken<Map<String, Object>>() {}.getType();
|
||||
this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json,
|
||||
TransferApiConstants.PROPOSE_AND_ACCEPT_CLIENT_TRANSFER_DATA_PARAMETERS);
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource(ClientApiConstants.CLIENT_RESOURCE_NAME);
|
||||
final JsonElement element = this.fromApiJsonHelper.parse(json);
|
||||
|
||||
final Long destinationOfficeId = this.fromApiJsonHelper
|
||||
.extractLongNamed(TransferApiConstants.destinationOfficeIdParamName, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.destinationOfficeIdParamName).value(destinationOfficeId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.newStaffIdParamName, element)) {
|
||||
final Long newStaffId = this.fromApiJsonHelper.extractLongNamed(TransferApiConstants.newStaffIdParamName, element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.newStaffIdParamName).value(newStaffId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
if (this.fromApiJsonHelper.parameterExists(TransferApiConstants.destinationGroupIdParamName, element)) {
|
||||
final Long destinationGroupId = this.fromApiJsonHelper.extractLongNamed(TransferApiConstants.destinationGroupIdParamName,
|
||||
element);
|
||||
baseDataValidator.reset().parameter(TransferApiConstants.destinationGroupIdParamName).value(destinationGroupId).notNull()
|
||||
.integerGreaterThanZero();
|
||||
}
|
||||
|
||||
validateNote(baseDataValidator, element);
|
||||
|
||||
throwExceptionIfValidationWarningsExist(dataValidationErrors);
|
||||
}
|
||||
|
||||
public void validateForRejectClientTransfer(final String json) {
|
||||
if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); }
|
||||
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
package org.mifosplatform.portfolio.transfer.handler;
|
||||
|
||||
import org.mifosplatform.commands.handler.NewCommandSourceHandler;
|
||||
import org.mifosplatform.infrastructure.core.api.JsonCommand;
|
||||
import org.mifosplatform.infrastructure.core.data.CommandProcessingResult;
|
||||
import org.mifosplatform.portfolio.transfer.service.TransferWritePlatformService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Service
|
||||
public class ProposeAndAcceptClientTransferCommandHandler implements NewCommandSourceHandler {
|
||||
|
||||
private final TransferWritePlatformService writePlatformService;
|
||||
|
||||
@Autowired
|
||||
public ProposeAndAcceptClientTransferCommandHandler(final TransferWritePlatformService writePlatformService) {
|
||||
this.writePlatformService = writePlatformService;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult processCommand(final JsonCommand command) {
|
||||
return this.writePlatformService.proposeAndAcceptClientTransfer(command.entityId(), command);
|
||||
}
|
||||
}
|
||||
+4
@@ -25,4 +25,8 @@ public enum TransferEventType {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
public boolean isAcceptance() {
|
||||
return value.equals(TransferEventType.ACCEPTANCE.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
@@ -20,4 +20,6 @@ public interface TransferWritePlatformService {
|
||||
|
||||
CommandProcessingResult rejectClientTransfer(final Long clientId, final JsonCommand jsonCommand);
|
||||
|
||||
CommandProcessingResult proposeAndAcceptClientTransfer(final Long clientId, final JsonCommand jsonCommand);
|
||||
|
||||
}
|
||||
+31
-2
@@ -220,6 +220,35 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is meant for transferring clients between branches mainly by
|
||||
* Organizations following an Individual lending Model <br/>
|
||||
*
|
||||
* @param clientId
|
||||
* @param destinationOfficeId
|
||||
* @param jsonCommand
|
||||
* @return
|
||||
**/
|
||||
@Transactional
|
||||
@Override
|
||||
public CommandProcessingResult proposeAndAcceptClientTransfer(final Long clientId, final JsonCommand jsonCommand) {
|
||||
// validation
|
||||
this.transfersDataValidator.validateForProposeAndAcceptClientTransfer(jsonCommand.json());
|
||||
|
||||
final Long destinationOfficeId = jsonCommand.longValueOfParameterNamed(TransferApiConstants.destinationOfficeIdParamName);
|
||||
final Office office = this.officeRepository.findOneWithNotFoundDetection(destinationOfficeId);
|
||||
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
|
||||
handleClientTransferLifecycleEvent(client, office, TransferEventType.PROPOSAL, jsonCommand);
|
||||
this.clientRepository.saveAndFlush(client);
|
||||
handleClientTransferLifecycleEvent(client, client.getTransferToOffice(), TransferEventType.ACCEPTANCE, jsonCommand);
|
||||
this.clientRepository.save(client);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withClientId(clientId) //
|
||||
.withEntityId(clientId) //
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* This API is meant for transferring clients between branches mainly by
|
||||
* Organizations following an Individual lending Model <br/>
|
||||
@@ -322,8 +351,8 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
|
||||
if (staffId != null) {
|
||||
staff = this.staffRepositoryWrapper.findByOfficeHierarchyWithNotFoundDetection(staffId, destinationOffice.getHierarchy());
|
||||
}
|
||||
if (destinationGroupId != null) {
|
||||
destinationGroup = this.groupRepository.findOneWithNotFoundDetection(destinationGroupId);
|
||||
if (transferEventType.isAcceptance() && destinationGroupId != null) {
|
||||
destinationGroup = this.groupRepository.findByOfficeWithNotFoundDetection(destinationGroupId, destinationOffice);
|
||||
}
|
||||
|
||||
/*** Handle Active Loans ***/
|
||||
|
||||
Reference in New Issue
Block a user