added some validations around transfers of savings accounts
This commit is contained in:
+16
@@ -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();
|
||||
}
|
||||
|
||||
+27
@@ -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;
|
||||
|
||||
+20
@@ -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);
|
||||
}
|
||||
|
||||
+41
@@ -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();
|
||||
}
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
+21
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user