Added support to activate closed account by adjusting the transaction
This commit is contained in:
+75
@@ -0,0 +1,75 @@
|
|||||||
|
package org.mifosplatform.portfolio.savings.data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joda.time.LocalDate;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
|
||||||
|
|
||||||
|
public class SavingsAccountTransactionDTO {
|
||||||
|
|
||||||
|
private DateTimeFormatter formatter;
|
||||||
|
private LocalDate transactionDate;
|
||||||
|
private BigDecimal transactionAmount;
|
||||||
|
private List<Long> existingTransactionIds;
|
||||||
|
private List<Long> existingReversedTransactionIds;
|
||||||
|
private PaymentDetail paymentDetail;
|
||||||
|
private boolean checkAccountStatus;
|
||||||
|
|
||||||
|
|
||||||
|
public SavingsAccountTransactionDTO(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
||||||
|
final BigDecimal transactionAmount, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
|
final PaymentDetail paymentDetail, boolean checkAccountStatus) {
|
||||||
|
this.formatter = formatter;
|
||||||
|
this.transactionDate = transactionDate;
|
||||||
|
this.transactionAmount = transactionAmount;
|
||||||
|
this.existingTransactionIds = existingTransactionIds;
|
||||||
|
this.existingReversedTransactionIds = existingReversedTransactionIds;
|
||||||
|
this.paymentDetail = paymentDetail;
|
||||||
|
this.checkAccountStatus = checkAccountStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public DateTimeFormatter getFormatter() {
|
||||||
|
return this.formatter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public LocalDate getTransactionDate() {
|
||||||
|
return this.transactionDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public BigDecimal getTransactionAmount() {
|
||||||
|
return this.transactionAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<Long> getExistingTransactionIds() {
|
||||||
|
return this.existingTransactionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<Long> getExistingReversedTransactionIds() {
|
||||||
|
return this.existingReversedTransactionIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PaymentDetail getPaymentDetail() {
|
||||||
|
return this.paymentDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isCheckAccountStatus() {
|
||||||
|
return this.checkAccountStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
+57
-53
@@ -63,7 +63,6 @@ import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
|
|||||||
import org.mifosplatform.portfolio.client.domain.Client;
|
import org.mifosplatform.portfolio.client.domain.Client;
|
||||||
import org.mifosplatform.portfolio.group.domain.Group;
|
import org.mifosplatform.portfolio.group.domain.Group;
|
||||||
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
import org.mifosplatform.portfolio.loanproduct.domain.PeriodFrequencyType;
|
||||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
|
||||||
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
|
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
|
||||||
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
import org.mifosplatform.portfolio.savings.SavingsCompoundingInterestPeriodType;
|
||||||
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
|
import org.mifosplatform.portfolio.savings.SavingsInterestCalculationDaysInYearType;
|
||||||
@@ -71,6 +70,7 @@ import org.mifosplatform.portfolio.savings.SavingsInterestCalculationType;
|
|||||||
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
|
import org.mifosplatform.portfolio.savings.SavingsPeriodFrequencyType;
|
||||||
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
|
import org.mifosplatform.portfolio.savings.SavingsPostingInterestPeriodType;
|
||||||
import org.mifosplatform.portfolio.savings.SavingsWithdrawalFeesType;
|
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.domain.interest.PostingPeriod;
|
||||||
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
|
import org.mifosplatform.portfolio.savings.exception.InsufficientAccountBalanceException;
|
||||||
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
import org.mifosplatform.portfolio.savings.service.SavingsEnumerations;
|
||||||
@@ -259,14 +259,14 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||||
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType, boolean withdrawalFeeApplicableForTransfer,
|
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType,
|
||||||
final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay) {
|
boolean withdrawalFeeApplicableForTransfer, final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay) {
|
||||||
|
|
||||||
final SavingsAccountStatusType status = SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL;
|
final SavingsAccountStatusType status = SavingsAccountStatusType.SUBMITTED_AND_PENDING_APPROVAL;
|
||||||
return new SavingsAccount(client, group, product, fieldOfficer, accountNo, externalId, status, accountType, submittedOnDate,
|
return new SavingsAccount(client, group, product, fieldOfficer, accountNo, externalId, status, accountType, submittedOnDate,
|
||||||
interestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
interestRate, interestCompoundingPeriodType, interestPostingPeriodType, interestCalculationType,
|
||||||
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
interestCalculationDaysInYearType, minRequiredOpeningBalance, lockinPeriodFrequency, lockinPeriodFrequencyType,
|
||||||
withdrawalFeeAmount, withdrawalFeeType,withdrawalFeeApplicableForTransfer, annualFeeAmount, annualFeeOnMonthDay);
|
withdrawalFeeAmount, withdrawalFeeType, withdrawalFeeApplicableForTransfer, annualFeeAmount, annualFeeOnMonthDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final Staff fieldOfficer,
|
private SavingsAccount(final Client client, final Group group, final SavingsProduct product, final Staff fieldOfficer,
|
||||||
@@ -276,8 +276,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
final SavingsPostingInterestPeriodType interestPostingPeriodType, final SavingsInterestCalculationType interestCalculationType,
|
||||||
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
final SavingsInterestCalculationDaysInYearType interestCalculationDaysInYearType, final BigDecimal minRequiredOpeningBalance,
|
||||||
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
final Integer lockinPeriodFrequency, final SavingsPeriodFrequencyType lockinPeriodFrequencyType,
|
||||||
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType,final boolean withdrawalFeeApplicableForTransfer, final BigDecimal annualFeeAmount,
|
final BigDecimal withdrawalFeeAmount, final SavingsWithdrawalFeesType withdrawalFeeType,
|
||||||
final MonthDay annualFeeOnMonthDay) {
|
final boolean withdrawalFeeApplicableForTransfer, final BigDecimal annualFeeAmount, final MonthDay annualFeeOnMonthDay) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.group = group;
|
this.group = group;
|
||||||
this.product = product;
|
this.product = product;
|
||||||
@@ -465,8 +465,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
for (final LocalDateInterval periodInterval : postingPeriodIntervals) {
|
||||||
|
|
||||||
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
|
final PostingPeriod postingPeriod = PostingPeriod.createFrom(periodInterval, periodStartingBalance,
|
||||||
retreiveOrderedListOfTransactions(), this.currency, compoundingPeriodType, interestCalculationType, interestRateAsFraction,
|
retreiveOrderedListOfTransactions(), this.currency, compoundingPeriodType, interestCalculationType,
|
||||||
daysInYearType.getValue());
|
interestRateAsFraction, daysInYearType.getValue());
|
||||||
|
|
||||||
periodStartingBalance = postingPeriod.closingBalance();
|
periodStartingBalance = postingPeriod.closingBalance();
|
||||||
|
|
||||||
@@ -543,14 +543,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction deposit(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
public SavingsAccountTransaction deposit(final SavingsAccountTransactionDTO transactionDTO) {
|
||||||
final BigDecimal transactionAmount, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
|
||||||
final PaymentDetail paymentDetail) {
|
|
||||||
|
|
||||||
if (isNotActive()) {
|
if (transactionDTO.isCheckAccountStatus() && isNotActive()) {
|
||||||
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.account.is.not.active",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.account.is.not.active",
|
||||||
defaultUserMessage, "transactionDate", transactionDate.toString(formatter));
|
defaultUserMessage, "transactionDate", transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()));
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
@@ -558,10 +556,10 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDateInTheFuture(transactionDate)) {
|
if (isDateInTheFuture(transactionDTO.getTransactionDate())) {
|
||||||
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.in.the.future",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.in.the.future",
|
||||||
defaultUserMessage, "transactionDate", transactionDate.toString(formatter));
|
defaultUserMessage, "transactionDate", transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()));
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
@@ -569,9 +567,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactionDate.isBefore(getActivationLocalDate())) {
|
if (transactionDTO.getTransactionDate().isBefore(getActivationLocalDate())) {
|
||||||
final Object[] defaultUserArgs = Arrays.asList(transactionDate.toString(formatter),
|
final Object[] defaultUserArgs = Arrays.asList(transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()),
|
||||||
getActivationLocalDate().toString(formatter)).toArray();
|
getActivationLocalDate().toString(transactionDTO.getFormatter())).toArray();
|
||||||
final String defaultUserMessage = "Transaction date cannot be before accounts activation date.";
|
final String defaultUserMessage = "Transaction date cannot be before accounts activation date.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.before.activation.date",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.before.activation.date",
|
||||||
defaultUserMessage, "transactionDate", defaultUserArgs);
|
defaultUserMessage, "transactionDate", defaultUserArgs);
|
||||||
@@ -582,12 +580,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
transactionDTO.getExistingTransactionIds().addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
transactionDTO.getExistingReversedTransactionIds().addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money amount = Money.of(this.currency, transactionAmount);
|
final Money amount = Money.of(this.currency, transactionDTO.getTransactionAmount());
|
||||||
|
|
||||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, paymentDetail, transactionDate, amount);
|
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(), amount);
|
||||||
this.transactions.add(transaction);
|
this.transactions.add(transaction);
|
||||||
|
|
||||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||||
@@ -603,15 +601,13 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return activationLocalDate;
|
return activationLocalDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SavingsAccountTransaction withdraw(final DateTimeFormatter formatter, final LocalDate transactionDate,
|
public SavingsAccountTransaction withdraw(SavingsAccountTransactionDTO transactionDTO, final boolean applyWithdrawFee) {
|
||||||
final BigDecimal transactionAmount, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
|
||||||
final PaymentDetail paymentDetail,final boolean applyWithdrawFee) {
|
|
||||||
|
|
||||||
if (isNotActive()) {
|
if (transactionDTO.isCheckAccountStatus() && isNotActive()) {
|
||||||
|
|
||||||
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
final String defaultUserMessage = "Transaction is not allowed. Account is not active.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.account.is.not.active",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.account.is.not.active",
|
||||||
defaultUserMessage, "transactionDate", transactionDate.toString(formatter));
|
defaultUserMessage, "transactionDate", transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()));
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
@@ -619,10 +615,10 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDateInTheFuture(transactionDate)) {
|
if (isDateInTheFuture(transactionDTO.getTransactionDate())) {
|
||||||
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
final String defaultUserMessage = "Transaction date cannot be in the future.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.in.the.future",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.in.the.future",
|
||||||
defaultUserMessage, "transactionDate", transactionDate.toString(formatter));
|
defaultUserMessage, "transactionDate", transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()));
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
@@ -630,9 +626,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactionDate.isBefore(getActivationLocalDate())) {
|
if (transactionDTO.getTransactionDate().isBefore(getActivationLocalDate())) {
|
||||||
final Object[] defaultUserArgs = Arrays.asList(transactionDate.toString(formatter),
|
final Object[] defaultUserArgs = Arrays.asList(transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()),
|
||||||
getActivationLocalDate().toString(formatter)).toArray();
|
getActivationLocalDate().toString(transactionDTO.getFormatter())).toArray();
|
||||||
final String defaultUserMessage = "Transaction date cannot be before accounts activation date.";
|
final String defaultUserMessage = "Transaction date cannot be before accounts activation date.";
|
||||||
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.before.activation.date",
|
final ApiParameterError error = ApiParameterError.parameterError("error.msg.savingsaccount.transaction.before.activation.date",
|
||||||
defaultUserMessage, "transactionDate", defaultUserArgs);
|
defaultUserMessage, "transactionDate", defaultUserArgs);
|
||||||
@@ -643,12 +639,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAccountLocked(transactionDate)) {
|
if (isAccountLocked(transactionDTO.getTransactionDate())) {
|
||||||
final String defaultUserMessage = "Withdrawal is not allowed. No withdrawals are allowed until after "
|
final String defaultUserMessage = "Withdrawal is not allowed. No withdrawals are allowed until after "
|
||||||
+ getLockedInUntilLocalDate().toString(formatter);
|
+ getLockedInUntilLocalDate().toString(transactionDTO.getFormatter());
|
||||||
final ApiParameterError error = ApiParameterError.parameterError(
|
final ApiParameterError error = ApiParameterError.parameterError(
|
||||||
"error.msg.savingsaccount.transaction.withdrawals.blocked.during.lockin.period", defaultUserMessage, "transactionDate",
|
"error.msg.savingsaccount.transaction.withdrawals.blocked.during.lockin.period", defaultUserMessage, "transactionDate",
|
||||||
transactionDate.toString(formatter), getLockedInUntilLocalDate().toString(formatter));
|
transactionDTO.getTransactionDate().toString(transactionDTO.getFormatter()), getLockedInUntilLocalDate().toString(transactionDTO.getFormatter()));
|
||||||
|
|
||||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
|
||||||
dataValidationErrors.add(error);
|
dataValidationErrors.add(error);
|
||||||
@@ -656,11 +652,11 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
throw new PlatformApiDataValidationException(dataValidationErrors);
|
throw new PlatformApiDataValidationException(dataValidationErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
transactionDTO.getExistingTransactionIds().addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
transactionDTO.getExistingReversedTransactionIds().addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money transactionAmountMoney = Money.of(this.currency, transactionAmount);
|
final Money transactionAmountMoney = Money.of(this.currency, transactionDTO.getTransactionAmount());
|
||||||
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, paymentDetail, transactionDate,
|
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(),
|
||||||
transactionAmountMoney);
|
transactionAmountMoney);
|
||||||
this.transactions.add(transaction);
|
this.transactions.add(transaction);
|
||||||
|
|
||||||
@@ -673,14 +669,14 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
break;
|
break;
|
||||||
case FLAT:
|
case FLAT:
|
||||||
feeAmount = Money.of(this.currency, this.withdrawalFeeAmount);
|
feeAmount = Money.of(this.currency, this.withdrawalFeeAmount);
|
||||||
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDate, feeAmount);
|
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDTO.getTransactionDate(), feeAmount);
|
||||||
this.transactions.add(withdrawalFeeTransaction);
|
this.transactions.add(withdrawalFeeTransaction);
|
||||||
break;
|
break;
|
||||||
case PERCENT_OF_AMOUNT:
|
case PERCENT_OF_AMOUNT:
|
||||||
final BigDecimal feeAmountDecimal = transactionAmount.multiply(this.withdrawalFeeAmount).divide(
|
final BigDecimal feeAmountDecimal = transactionDTO.getTransactionAmount().multiply(this.withdrawalFeeAmount).divide(
|
||||||
BigDecimal.valueOf(100l));
|
BigDecimal.valueOf(100l));
|
||||||
feeAmount = Money.of(this.currency, feeAmountDecimal);
|
feeAmount = Money.of(this.currency, feeAmountDecimal);
|
||||||
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDate, feeAmount);
|
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDTO.getTransactionDate(), feeAmount);
|
||||||
this.transactions.add(withdrawalFeeTransaction);
|
this.transactions.add(withdrawalFeeTransaction);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -806,11 +802,12 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
|
||||||
final SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, annualFeeTransactionDate, annualFee);
|
final SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, annualFeeTransactionDate,
|
||||||
|
annualFee);
|
||||||
this.transactions.add(annualFeeTransaction);
|
this.transactions.add(annualFeeTransaction);
|
||||||
|
|
||||||
validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.applyAnnualFeeTransactionAction);
|
validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.applyAnnualFeeTransactionAction);
|
||||||
|
|
||||||
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
this.summary.updateSummary(this.currency, this.savingsAccountTransactionSummaryWrapper, this.transactions);
|
||||||
|
|
||||||
calculateInterestUsing(mc, today);
|
calculateInterestUsing(mc, today);
|
||||||
@@ -1035,8 +1032,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
actualChanges.put(withdrawalFeeTypeParamName, newValue);
|
actualChanges.put(withdrawalFeeTypeParamName, newValue);
|
||||||
this.withdrawalFeeType = newValue != null ? SavingsWithdrawalFeesType.fromInt(newValue).getValue() : newValue;
|
this.withdrawalFeeType = newValue != null ? SavingsWithdrawalFeesType.fromInt(newValue).getValue() : newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(command.isChangeInBooleanParameterNamed(withdrawalFeeForTransfersParamName, this.withdrawalFeeApplicableForTransfer)){
|
if (command.isChangeInBooleanParameterNamed(withdrawalFeeForTransfersParamName, this.withdrawalFeeApplicableForTransfer)) {
|
||||||
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
|
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(withdrawalFeeForTransfersParamName);
|
||||||
actualChanges.put(withdrawalFeeForTransfersParamName, newValue);
|
actualChanges.put(withdrawalFeeForTransfersParamName, newValue);
|
||||||
this.withdrawalFeeApplicableForTransfer = newValue;
|
this.withdrawalFeeApplicableForTransfer = newValue;
|
||||||
@@ -1143,7 +1140,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
.integerZeroOrGreater();
|
.integerZeroOrGreater();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(this.lockinPeriodFrequencyType).integerZeroOrGreater();
|
baseDataValidator.reset().parameter(lockinPeriodFrequencyParamName).value(this.lockinPeriodFrequencyType)
|
||||||
|
.integerZeroOrGreater();
|
||||||
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(this.lockinPeriodFrequencyType).notNull()
|
baseDataValidator.reset().parameter(lockinPeriodFrequencyTypeParamName).value(this.lockinPeriodFrequencyType).notNull()
|
||||||
.inMinMaxRange(0, 3);
|
.inMinMaxRange(0, 3);
|
||||||
}
|
}
|
||||||
@@ -1438,8 +1436,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
if (this.annualFeeNextDueDate == null) {
|
if (this.annualFeeNextDueDate == null) {
|
||||||
updateToNextAnnualFeeDueDateFrom(getActivationLocalDate());
|
updateToNextAnnualFeeDueDateFrom(getActivationLocalDate());
|
||||||
} else {
|
} else {
|
||||||
final LocalDate newAnnualFeeNextDueDate = new LocalDate(this.annualFeeNextDueDate).withMonthOfYear(this.annualFeeOnMonth)
|
final LocalDate newAnnualFeeNextDueDate = new LocalDate(this.annualFeeNextDueDate)
|
||||||
.withDayOfMonth(this.annualFeeOnDay).plusYears(1);
|
.withMonthOfYear(this.annualFeeOnMonth).withDayOfMonth(this.annualFeeOnDay).plusYears(1);
|
||||||
this.annualFeeNextDueDate = newAnnualFeeNextDueDate.toDate();
|
this.annualFeeNextDueDate = newAnnualFeeNextDueDate.toDate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1667,8 +1665,9 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
// activating account.
|
// activating account.
|
||||||
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
|
||||||
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
if (minRequiredOpeningBalance.isGreaterThanZero()) {
|
||||||
deposit(fmt, activationDate, minRequiredOpeningBalance.getAmount(), existingTransactionIds, existingReversedTransactionIds,
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, activationDate, minRequiredOpeningBalance.getAmount(), existingTransactionIds, existingReversedTransactionIds,
|
||||||
null);
|
null, true);
|
||||||
|
deposit(transactionDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
return actualChanges;
|
return actualChanges;
|
||||||
@@ -1759,8 +1758,13 @@ public class SavingsAccount extends AbstractPersistable<Long> {
|
|||||||
return this.group;
|
return this.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isWithdrawalFeeApplicableForTransfer() {
|
public boolean isWithdrawalFeeApplicableForTransfer() {
|
||||||
return this.withdrawalFeeApplicableForTransfer;
|
return this.withdrawalFeeApplicableForTransfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void activateAccountBasedOnBalance() {
|
||||||
|
if (SavingsAccountStatusType.fromInt(this.status).isClosed() && !this.summary.getAccountBalance(getCurrency()).isZero()) {
|
||||||
|
this.status = SavingsAccountStatusType.ACTIVE.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-6
@@ -19,6 +19,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
|||||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper;
|
||||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -49,9 +50,9 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
final SavingsAccountTransaction withdrawal = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
existingTransactionIds,existingReversedTransactionIds, paymentDetail,true);
|
||||||
existingReversedTransactionIds, paymentDetail, applyWithdrawFee);
|
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO , applyWithdrawFee);
|
||||||
|
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
@@ -77,9 +78,9 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
|
|||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
final List<Long> existingTransactionIds = new ArrayList<Long>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<Long>();
|
||||||
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
final SavingsAccountTransaction deposit = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds,
|
existingTransactionIds, existingReversedTransactionIds, paymentDetail, true);
|
||||||
existingReversedTransactionIds, paymentDetail);
|
final SavingsAccountTransaction deposit = account.deposit(transactionDTO);
|
||||||
|
|
||||||
final MathContext mc = MathContext.DECIMAL64;
|
final MathContext mc = MathContext.DECIMAL64;
|
||||||
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
if (account.isBeforeLastPostingPeriod(transactionDate)) {
|
||||||
|
|||||||
+17
-5
@@ -38,6 +38,7 @@ import org.mifosplatform.portfolio.note.domain.NoteRepository;
|
|||||||
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
import org.mifosplatform.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
|
||||||
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
|
import org.mifosplatform.portfolio.savings.SavingsApiConstants;
|
||||||
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
|
||||||
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler;
|
||||||
@@ -307,7 +308,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction);
|
||||||
|
account.activateAccountBasedOnBalance();
|
||||||
postJournalEntries(account, newTransactionIds, reversedTransactionIds);
|
postJournalEntries(account, newTransactionIds, reversedTransactionIds);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
@@ -345,13 +346,23 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
|
|
||||||
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
final MathContext mc = new MathContext(10, RoundingMode.HALF_EVEN);
|
||||||
account.undoTransaction(transactionId, existingReversedTransactionIds);
|
account.undoTransaction(transactionId, existingReversedTransactionIds);
|
||||||
|
|
||||||
|
//for undo withdrawal fee
|
||||||
|
SavingsAccountTransaction nextSavingsAccountTransaction = this.savingsAccountTransactionRepository.findOneByIdAndSavingsAccountId(
|
||||||
|
transactionId+1, savingsId);
|
||||||
|
if(nextSavingsAccountTransaction.isWithdrawalFeeAndNotReversed()){
|
||||||
|
account.undoTransaction(transactionId+1, existingReversedTransactionIds);
|
||||||
|
}
|
||||||
|
|
||||||
SavingsAccountTransaction transaction = null;
|
SavingsAccountTransaction transaction = null;
|
||||||
if (savingsAccountTransaction.isDeposit()) {
|
if (savingsAccountTransaction.isDeposit()) {
|
||||||
transaction = account.deposit(fmt, transactionDate, transactionAmount, existingTransactionIds, existingReversedTransactionIds,
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
paymentDetail);
|
existingTransactionIds, existingReversedTransactionIds,paymentDetail, false);
|
||||||
|
transaction = account.deposit(transactionDTO);
|
||||||
} else {
|
} else {
|
||||||
transaction = account.withdraw(fmt, transactionDate, transactionAmount, existingTransactionIds, existingReversedTransactionIds,
|
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
|
||||||
paymentDetail, true);
|
existingTransactionIds, existingReversedTransactionIds, paymentDetail, false);
|
||||||
|
transaction = account.withdraw(transactionDTO , true);
|
||||||
}
|
}
|
||||||
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
final Long newtransactionId = saveTransactionToGenerateTransactionId(transaction);
|
||||||
|
|
||||||
@@ -362,6 +373,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
account.calculateInterestUsing(mc, today);
|
account.calculateInterestUsing(mc, today);
|
||||||
}
|
}
|
||||||
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction);
|
||||||
|
account.activateAccountBasedOnBalance();
|
||||||
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(newtransactionId) //
|
.withEntityId(newtransactionId) //
|
||||||
|
|||||||
Reference in New Issue
Block a user