added some validations around transfers of savings accounts

This commit is contained in:
Vishwas Babu A J
2013-09-20 00:33:50 +05:30
parent 421724d24c
commit c46eab4453
6 changed files with 146 additions and 0 deletions
@@ -113,6 +113,22 @@ public enum SavingsAccountTransactionType {
return this.value.equals(SavingsAccountTransactionType.WAIVE_CHARGES.getValue());
}
public boolean isTransferInitiation() {
return this.value.equals(SavingsAccountTransactionType.INITIATE_TRANSFER.getValue());
}
public boolean isTransferApproval() {
return this.value.equals(SavingsAccountTransactionType.APPROVE_TRANSFER.getValue());
}
public boolean isTransferRejection() {
return this.value.equals(SavingsAccountTransactionType.REJECT_TRANSFER.getValue());
}
public boolean isTransferWithdrawal() {
return this.value.equals(SavingsAccountTransactionType.WITHDRAW_TRANSFER.getValue());
}
public boolean isDebit() {
return isWithdrawal() || isWithdrawalFee() || isAnnualFee() || isCharge();
}
@@ -79,6 +79,8 @@ import org.mifosplatform.portfolio.savings.SavingsWithdrawalFeesType;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.portfolio.savings.domain.interest.PostingPeriod;
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
import org.mifosplatform.portfolio.savings.exception.SavingsActivityPriorToClientTransferException;
import org.mifosplatform.portfolio.savings.exception.SavingsTransferTransactionsCannotBeUndoneException;
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.data.jpa.domain.AbstractPersistable;
@@ -605,6 +607,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_DEPOSIT, transactionDTO.getTransactionDate());
transactionDTO.getExistingTransactionIds().addAll(findExistingTransactionIds());
transactionDTO.getExistingReversedTransactionIds().addAll(findExistingReversedTransactionIds());
@@ -679,6 +682,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_WITHDRAWAL, transactionDTO.getTransactionDate());
transactionDTO.getExistingTransactionIds().addAll(findExistingTransactionIds());
transactionDTO.getExistingReversedTransactionIds().addAll(findExistingReversedTransactionIds());
@@ -823,6 +827,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
throw new PlatformApiDataValidationException(dataValidationErrors);
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_PAY_FEE, annualFeeTransactionDate);
existingTransactionIds.addAll(findExistingTransactionIds());
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
@@ -1416,6 +1421,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_APPLICATION_APPROVED, approvedOn);
// FIXME - kw - support field officer history for savings accounts
// if (this.fieldOfficer != null) {
@@ -1476,6 +1482,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
// throw non found exception
} else {
validateAttemptToUndoTransferRelatedTransactions(transactionToUndo);
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_UNDO_TRANSACTION,
transactionToUndo.transactionLocalDate());
transactionToUndo.reverse();
reversedTransactionIds.add(transactionId);
@@ -1558,6 +1567,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
actualChanges.put(SavingsApiConstants.closedOnDateParamName, rejectedOnAsString);
final LocalDate submittalDate = getSubmittedOnLocalDate();
if (rejectedOn.isBefore(submittalDate)) {
final DateTimeFormatter formatter = DateTimeFormat.forPattern(command.dateFormat()).withLocale(command.extractLocale());
@@ -1576,6 +1586,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_APPLICATION_REJECTED, rejectedOn);
return actualChanges;
}
@@ -1634,6 +1645,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_APPLICATION_WITHDRAWAL_BY_CUSTOMER, withdrawnOn);
return actualChanges;
}
@@ -1715,6 +1727,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_ACTIVATE, activationDate);
// auto enter deposit for minimum required opening balance when
// activating account.
@@ -1778,6 +1791,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode("results.in.balance.not.zero");
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); }
}
validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent.SAVINGS_CLOSE_ACCOUNT, closedDate);
this.status = SavingsAccountStatusType.CLOSED.getValue();
actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
@@ -1794,6 +1808,19 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return actualChanges;
}
private void validateActivityNotBeforeClientOrGroupTransferDate(SavingsEvent event, LocalDate activityDate) {
if (this.client != null && this.client.getOfficeJoiningLocalDate() != null) {
LocalDate clientOfficeJoiningDate = client.getOfficeJoiningLocalDate();
if (activityDate.isBefore(clientOfficeJoiningDate)) { throw new SavingsActivityPriorToClientTransferException(event.toString(),
clientOfficeJoiningDate); }
}
}
private void validateAttemptToUndoTransferRelatedTransactions(SavingsAccountTransaction savingsAccountTransaction) {
if (savingsAccountTransaction.isTransferRelatedTransaction()) { throw new SavingsTransferTransactionsCannotBeUndoneException(
savingsAccountTransaction.getId()); }
}
private Date calculateDateAccountIsLockedUntil(final LocalDate activationLocalDate) {
Date lockedInUntilLocalDate = null;
@@ -232,6 +232,26 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
return this.reversed;
}
public boolean isTransferInitiation() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isTransferInitiation();
}
public boolean isTransferApproval() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isTransferApproval();
}
public boolean isTransferRejection() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isTransferRejection();
}
public boolean isTransferWithdrawal() {
return SavingsAccountTransactionType.fromInt(this.typeOf).isTransferWithdrawal();
}
public boolean isTransferRelatedTransaction() {
return isTransferInitiation() || isTransferApproval() || isTransferRejection() || isTransferWithdrawal();
}
public boolean occursOn(final LocalDate occursOnDate) {
return getTransactionLocalDate().isEqual(occursOnDate);
}
@@ -0,0 +1,41 @@
/**
* 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.savings.domain;
/**
*
*/
public enum SavingsEvent {
SAVINGS_APPLICATION_REJECTED("application.rejected"), //
SAVINGS_APPLICATION_WITHDRAWAL_BY_CUSTOMER("application.withdrawal"), //
SAVINGS_APPLICATION_APPROVED("application.approval"), //
SAVINGS_APPLICATION_APPROVAL_UNDO("application.approval.undo"), //
SAVINGS_ACTIVATE("activate"), //
SAVINGS_DEPOSIT("deposit"), //
SAVINGS_WITHDRAWAL("withdraw"), //
SAVINGS_POST_INTEREST("interest.post"), //
SAVINGS_UNDO_TRANSACTION("transaction.undo"), //
SAVINGS_ADJUST_TRANSACTION("transaction.adjust"), //
SAVINGS_APPLY_FEE("fee.apply"), //
SAVINGS_PAY_FEE("fee.pay"), //
SAVINGS_CLOSE_ACCOUNT("account.close");
private final String value;
private SavingsEvent(final String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
@Override
public String toString() {
return getValue();
}
}
@@ -0,0 +1,21 @@
/**
* 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.savings.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown an action to transition a
* loan from one state to another violates a domain rule.
*/
public class SavingsActivityPriorToClientTransferException extends AbstractPlatformDomainRuleException {
public SavingsActivityPriorToClientTransferException(final String action, Object... defaultUserMessageArgs) {
super("error.msg.savings." + action + "." + "not.permitted.before.client.transfer.date",
"Transactions on savings account prior to the customer joining date are not permitted", defaultUserMessageArgs);
}
}
@@ -0,0 +1,21 @@
/**
* 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.savings.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* {@link AbstractPlatformDomainRuleException} thrown an action to transition a
* loan from one state to another violates a domain rule.
*/
public class SavingsTransferTransactionsCannotBeUndoneException extends AbstractPlatformDomainRuleException {
public SavingsTransferTransactionsCannotBeUndoneException(Long transactionId) {
super("error.msg.savings.transfer.transactions.cannot.be.undone",
"Transactions related to savings account transfers cannot be undone", transactionId);
}
}