MIFOSX-1335,MIFOSX-1300 - corrected FD and RD related issues

This commit is contained in:
Pramod Nuthakki
2014-06-13 23:10:09 +05:30
parent baeab1f7c8
commit 63173c0de0
21 changed files with 198 additions and 130 deletions
@@ -34,13 +34,15 @@ public class AccountTransferDTO {
private final Loan loan; private final Loan loan;
private final SavingsAccount toSavingsAccount; private final SavingsAccount toSavingsAccount;
private final SavingsAccount fromSavingsAccount; private final SavingsAccount fromSavingsAccount;
private final Boolean isRegularTransaction;
public AccountTransferDTO(final LocalDate transactionDate, final BigDecimal transactionAmount, public AccountTransferDTO(final LocalDate transactionDate, final BigDecimal transactionAmount,
final PortfolioAccountType fromAccountType, final PortfolioAccountType toAccountType, final Long fromAccountId, final PortfolioAccountType fromAccountType, final PortfolioAccountType toAccountType, final Long fromAccountId,
final Long toAccountId, final String description, final Locale locale, final DateTimeFormatter fmt, final Long toAccountId, final String description, final Locale locale, final DateTimeFormatter fmt,
final PaymentDetail paymentDetail, final Integer fromTransferType, final Integer toTransferType, final Long chargeId, final PaymentDetail paymentDetail, final Integer fromTransferType, final Integer toTransferType, final Long chargeId,
Integer loanInstallmentNumber, Integer transferType, final AccountTransferDetails accountTransferDetails, Integer loanInstallmentNumber, Integer transferType, final AccountTransferDetails accountTransferDetails,
final String noteText, final String txnExternalId, final Loan loan, SavingsAccount toSavingsAccount, final SavingsAccount fromSavingsAccount) { final String noteText, final String txnExternalId, final Loan loan, SavingsAccount toSavingsAccount,
final SavingsAccount fromSavingsAccount,final Boolean isRegularTransaction) {
this.transactionDate = transactionDate; this.transactionDate = transactionDate;
this.transactionAmount = transactionAmount; this.transactionAmount = transactionAmount;
this.fromAccountType = fromAccountType; this.fromAccountType = fromAccountType;
@@ -62,6 +64,7 @@ public class AccountTransferDTO {
this.loan = loan; this.loan = loan;
this.toSavingsAccount = toSavingsAccount; this.toSavingsAccount = toSavingsAccount;
this.fromSavingsAccount = fromSavingsAccount; this.fromSavingsAccount = fromSavingsAccount;
this.isRegularTransaction = isRegularTransaction;
} }
public LocalDate getTransactionDate() { public LocalDate getTransactionDate() {
@@ -148,4 +151,9 @@ public class AccountTransferDTO {
return this.fromSavingsAccount; return this.fromSavingsAccount;
} }
public Boolean isRegularTransaction() {
return this.isRegularTransaction;
}
} }
@@ -22,7 +22,6 @@ import org.joda.time.format.DateTimeFormatter;
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.infrastructure.core.data.CommandProcessingResultBuilder; import org.mifosplatform.infrastructure.core.data.CommandProcessingResultBuilder;
import org.mifosplatform.infrastructure.core.exception.GeneralPlatformDomainRuleException;
import org.mifosplatform.portfolio.account.PortfolioAccountType; import org.mifosplatform.portfolio.account.PortfolioAccountType;
import org.mifosplatform.portfolio.account.data.AccountTransferDTO; import org.mifosplatform.portfolio.account.data.AccountTransferDTO;
import org.mifosplatform.portfolio.account.data.AccountTransfersDataValidator; import org.mifosplatform.portfolio.account.data.AccountTransfersDataValidator;
@@ -81,6 +80,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
@Transactional @Transactional
@Override @Override
public CommandProcessingResult create(final JsonCommand command) { public CommandProcessingResult create(final JsonCommand command) {
boolean isRegularTransaction = true;
this.accountTransfersDataValidator.validate(command); this.accountTransfersDataValidator.validate(command);
@@ -106,18 +106,16 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName);
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId); final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
validateAccountForTransfer(fromSavingsAccount);
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(),
isInterestTransfer, isAccountTransfer); isInterestTransfer, isAccountTransfer, isRegularTransaction);
final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName); final Long toSavingsId = command.longValueOfParameterNamed(toAccountIdParamName);
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId); final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsId);
validateAccountForTransfer(toSavingsAccount);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
transactionDate, transactionAmount, paymentDetail, isAccountTransfer); transactionDate, transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleSavingsToSavingsTransfer(command, final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleSavingsToSavingsTransfer(command,
fromSavingsAccount, toSavingsAccount, withdrawal, deposit); fromSavingsAccount, toSavingsAccount, withdrawal, deposit);
@@ -128,11 +126,10 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
// //
fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName); fromSavingsAccountId = command.longValueOfParameterNamed(fromAccountIdParamName);
final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId); final SavingsAccount fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(fromSavingsAccountId);
validateAccountForTransfer(fromSavingsAccount);
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, fmt,
transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), transactionDate, transactionAmount, paymentDetail, fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(),
isInterestTransfer, isAccountTransfer); isInterestTransfer, isAccountTransfer, isRegularTransaction);
final Long toLoanAccountId = command.longValueOfParameterNamed(toAccountIdParamName); final Long toLoanAccountId = command.longValueOfParameterNamed(toAccountIdParamName);
final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId); final Loan toLoanAccount = this.loanAccountAssembler.assembleFrom(toLoanAccountId);
@@ -159,10 +156,9 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final Long toSavingsAccountId = command.longValueOfParameterNamed(toAccountIdParamName); final Long toSavingsAccountId = command.longValueOfParameterNamed(toAccountIdParamName);
final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsAccountId); final SavingsAccount toSavingsAccount = this.savingsAccountAssembler.assembleFrom(toSavingsAccountId);
validateAccountForTransfer(toSavingsAccount);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, fmt,
transactionDate, transactionAmount, paymentDetail, isAccountTransfer); transactionDate, transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleLoanToSavingsTransfer(command, final AccountTransferDetails accountTransferDetails = this.accountTransferAssembler.assembleLoanToSavingsTransfer(command,
fromLoanAccount, toSavingsAccount, deposit, loanRefundTransaction); fromLoanAccount, toSavingsAccount, deposit, loanRefundTransaction);
@@ -238,7 +234,8 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
@Transactional @Transactional
public Long transferFunds(final AccountTransferDTO accountTransferDTO) { public Long transferFunds(final AccountTransferDTO accountTransferDTO) {
Long transferTransactionId = null; Long transferTransactionId = null;
boolean isAccountTransfer = true; final boolean isAccountTransfer = true;
final boolean isRegularTransaction = accountTransferDTO.isRegularTransaction();
AccountTransferDetails accountTransferDetails = accountTransferDTO.getAccountTransferDetails(); AccountTransferDetails accountTransferDetails = accountTransferDTO.getAccountTransferDetails();
if (isSavingsToLoanAccountTransfer(accountTransferDTO.getFromAccountType(), accountTransferDTO.getToAccountType())) { if (isSavingsToLoanAccountTransfer(accountTransferDTO.getFromAccountType(), accountTransferDTO.getToAccountType())) {
// //
@@ -257,7 +254,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType
.fromInt(accountTransferDTO.getTransferType()).isInterestTransfer(), isAccountTransfer); .fromInt(accountTransferDTO.getTransferType()).isInterestTransfer(), isAccountTransfer, isRegularTransaction);
LoanTransaction loanTransaction = null; LoanTransaction loanTransaction = null;
@@ -285,7 +282,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
if (accountTransferDetails == null) { if (accountTransferDetails == null) {
if (accountTransferDTO.getFromSavingsAccount() == null) { if (accountTransferDTO.getFromSavingsAccount() == null) {
fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(accountTransferDTO.getFromAccountId()); fromSavingsAccount = this.savingsAccountAssembler.assembleFrom(accountTransferDTO.getFromAccountId());
}else{ } else {
fromSavingsAccount = accountTransferDTO.getFromSavingsAccount(); fromSavingsAccount = accountTransferDTO.getFromSavingsAccount();
} }
if (accountTransferDTO.getToSavingsAccount() == null) { if (accountTransferDTO.getToSavingsAccount() == null) {
@@ -303,11 +300,11 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(fromSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType accountTransferDTO.getPaymentDetail(), fromSavingsAccount.isWithdrawalFeeApplicableForTransfer(), AccountTransferType
.fromInt(accountTransferDTO.getTransferType()).isInterestTransfer(), isAccountTransfer); .fromInt(accountTransferDTO.getTransferType()).isInterestTransfer(), isAccountTransfer, isRegularTransaction);
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
accountTransferDTO.getPaymentDetail(), isAccountTransfer); accountTransferDTO.getPaymentDetail(), isAccountTransfer, isRegularTransaction);
accountTransferDetails = this.accountTransferAssembler.assembleSavingsToSavingsTransfer(accountTransferDTO, fromSavingsAccount, accountTransferDetails = this.accountTransferAssembler.assembleSavingsToSavingsTransfer(accountTransferDTO, fromSavingsAccount,
toSavingsAccount, withdrawal, deposit); toSavingsAccount, withdrawal, deposit);
@@ -345,7 +342,7 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(toSavingsAccount,
accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(), accountTransferDTO.getFmt(), accountTransferDTO.getTransactionDate(), accountTransferDTO.getTransactionAmount(),
accountTransferDTO.getPaymentDetail(), isAccountTransfer); accountTransferDTO.getPaymentDetail(), isAccountTransfer, isRegularTransaction);
accountTransferDetails = this.accountTransferAssembler.assembleLoanToSavingsTransfer(accountTransferDTO, fromLoanAccount, accountTransferDetails = this.accountTransferAssembler.assembleLoanToSavingsTransfer(accountTransferDTO, fromLoanAccount,
toSavingsAccount, deposit, loanTransaction); toSavingsAccount, deposit, loanTransaction);
this.accountTransferDetailRepository.saveAndFlush(accountTransferDetails); this.accountTransferDetailRepository.saveAndFlush(accountTransferDetails);
@@ -377,13 +374,4 @@ public class AccountTransfersWritePlatformServiceImpl implements AccountTransfer
return fromAccountType.isSavingsAccount() && toAccountType.isSavingsAccount(); return fromAccountType.isSavingsAccount() && toAccountType.isSavingsAccount();
} }
private void validateAccountForTransfer(final SavingsAccount account) {
if (account.depositAccountType().isFixedDeposit() && account.isActive()) {
final String globalisationMessageCode = "error.msg.accounttransfers.are.not.allowed.on.active.fixeddepositaccount";
final String defaultUserMessage = "Account Transfers are not allowed on Active Fixed Deposit Account";
throw new GeneralPlatformDomainRuleException(globalisationMessageCode, defaultUserMessage, account.getId());
}
}
} }
@@ -215,11 +215,13 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
if (isDueForTransfer && transactionAmount != null && transactionAmount.compareTo(BigDecimal.ZERO) > 0) { if (isDueForTransfer && transactionAmount != null && transactionAmount.compareTo(BigDecimal.ZERO) > 0) {
final AccountTransferDetails accountTransferDetails = this.accountTransferDetailRepository.findOne(data.accountDetailId()); final AccountTransferDetails accountTransferDetails = this.accountTransferDetailRepository.findOne(data.accountDetailId());
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
accountTransferDetails.accountTransferStandingInstruction().updateLatsRunDate(transactionDate.toDate()); accountTransferDetails.accountTransferStandingInstruction().updateLatsRunDate(transactionDate.toDate());
AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, transactionAmount, data.fromAccountType(), AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, transactionAmount, data.fromAccountType(),
data.toAccountType(), data.fromAccount().accountId(), data.toAccount().accountId(), data.name() data.toAccountType(), data.fromAccount().accountId(), data.toAccount().accountId(), data.name()
+ " Standing instruction trasfer ", null, null, null, null, data.toTransferType(), null, null, data + " Standing instruction trasfer ", null, null, null, null, data.toTransferType(), null, null, data
.transferType().getValue(), accountTransferDetails, null, null, null, null, fromSavingsAccount); .transferType().getValue(), accountTransferDetails, null, null, null, null, fromSavingsAccount,
isRegularTransaction);
transferAmount(sb, accountTransferDTO, data.getId()); transferAmount(sb, accountTransferDTO, data.getId());
} }
} }
@@ -321,10 +321,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) { for (final Map.Entry<Long, BigDecimal> entrySet : disBuLoanCharges.entrySet()) {
final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId); final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loanId);
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(),
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loanId, "Loan Charge Payment", PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loanId, "Loan Charge Payment",
locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null, locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), entrySet.getKey(), null,
AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount); AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
@@ -494,11 +495,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loan final PortfolioAccountData savingAccountData = this.accountAssociationsReadPlatformService.retriveLoanAssociation(loan
.getId()); .getId());
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(actualDisbursementDate, entrySet.getValue(),
PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, savingAccountData.accountId(), loan.getId(),
"Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(), "Loan Charge Payment", locale, fmt, null, null, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT.getValue(),
entrySet.getKey(), null, AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, entrySet.getKey(), null, AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null,
fromSavingsAccount); fromSavingsAccount, isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
} }
@@ -1260,10 +1262,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId); throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId);
} }
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS, final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS,
PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null, PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null,
LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber, LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber,
AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount); AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
@@ -1289,10 +1292,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
throw new LinkedAccountRequiredException("loan.disburse.to.savings", errorMessage, loan.getId()); throw new LinkedAccountRequiredException("loan.disburse.to.savings", errorMessage, loan.getId());
} }
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount.getAmount(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount.getAmount(),
PortfolioAccountType.LOAN, PortfolioAccountType.SAVINGS, loan.getId(), portfolioAccountData.accountId(), PortfolioAccountType.LOAN, PortfolioAccountType.SAVINGS, loan.getId(), portfolioAccountData.accountId(),
"Loan Disbursement", locale, fmt, paymentDetail, LoanTransactionType.DISBURSEMENT.getValue(), null, null, null, "Loan Disbursement", locale, fmt, paymentDetail, LoanTransactionType.DISBURSEMENT.getValue(), null, null, null,
AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, txnExternalId, loan, null, fromSavingsAccount); AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, txnExternalId, loan, null, fromSavingsAccount, isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
@@ -1302,6 +1306,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
public void transferFeeCharges() throws JobExecutionException { public void transferFeeCharges() throws JobExecutionException {
final Collection<LoanChargeData> chargeDatas = this.loanChargeReadPlatformService.retrieveLoanChargesForFeePayment( final Collection<LoanChargeData> chargeDatas = this.loanChargeReadPlatformService.retrieveLoanChargesForFeePayment(
ChargePaymentMode.ACCOUNT_TRANSFER.getValue(), LoanStatus.ACTIVE.getValue()); ChargePaymentMode.ACCOUNT_TRANSFER.getValue(), LoanStatus.ACTIVE.getValue());
final boolean isRegularTransaction = true;
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
if (chargeDatas != null) { if (chargeDatas != null) {
for (final LoanChargeData chargeData : chargeDatas) { for (final LoanChargeData chargeData : chargeDatas) {
@@ -1321,7 +1326,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null,
null, LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null, LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(),
installmentChargeData.getInstallmentNumber(), AccountTransferType.CHARGE_PAYMENT.getValue(), null, installmentChargeData.getInstallmentNumber(), AccountTransferType.CHARGE_PAYMENT.getValue(), null,
null, null, null, null, fromSavingsAccount); null, null, null, null, fromSavingsAccount, isRegularTransaction);
transferFeeCharge(sb, accountTransferDTO); transferFeeCharge(sb, accountTransferDTO);
} }
} }
@@ -1333,7 +1338,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
chargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN, chargeData.getAmountOutstanding(), PortfolioAccountType.SAVINGS, PortfolioAccountType.LOAN,
portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null, portfolioAccountData.accountId(), chargeData.getLoanId(), "Loan Charge Payment", null, null, null, null,
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null, LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null,
AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount); AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount,
isRegularTransaction);
transferFeeCharge(sb, accountTransferDTO); transferFeeCharge(sb, accountTransferDTO);
} }
} }
@@ -2043,10 +2049,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId); throw new LinkedAccountRequiredException("loanCharge.pay", errorMessage, loanChargeId);
} }
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final boolean isRegularTransaction = true;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS, final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(transactionDate, amount, PortfolioAccountType.SAVINGS,
PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null, PortfolioAccountType.LOAN, portfolioAccountData.accountId(), loanId, "Loan Charge Payment", locale, fmt, null, null,
LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber, LoanTransactionType.CHARGE_PAYMENT.getValue(), loanChargeId, loanInstallmentNumber,
AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount); AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount, isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
return transaction; return transaction;
@@ -17,13 +17,13 @@ import org.mifosplatform.useradministration.domain.AppUser;
public interface DepositAccountDomainService { public interface DepositAccountDomainService {
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate, SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee); BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee, boolean isRegularTransaction);
SavingsAccountTransaction handleFDDeposit(FixedDepositAccount account, DateTimeFormatter fmt, LocalDate transactionDate, SavingsAccountTransaction handleFDDeposit(FixedDepositAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail); BigDecimal transactionAmount, PaymentDetail paymentDetail);
SavingsAccountTransaction handleRDDeposit(RecurringDepositAccount account, DateTimeFormatter fmt, LocalDate transactionDate, SavingsAccountTransaction handleRDDeposit(RecurringDepositAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail); BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isRegularTransaction);
Long handleFDAccountClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command, Long handleFDAccountClosure(FixedDepositAccount account, PaymentDetail paymentDetail, AppUser user, JsonCommand command,
LocalDate tenantsTodayDate, Map<String, Object> changes); LocalDate tenantsTodayDate, Map<String, Object> changes);
@@ -5,12 +5,12 @@
*/ */
package org.mifosplatform.portfolio.savings.domain; package org.mifosplatform.portfolio.savings.domain;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.onAccountClosureIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.toSavingsAccountIdParamName; import static org.mifosplatform.portfolio.savings.DepositsApiConstants.toSavingsAccountIdParamName;
import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferDescriptionParamName; import static org.mifosplatform.portfolio.savings.DepositsApiConstants.transferDescriptionParamName;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.MathContext; import java.math.MathContext;
import java.util.Date;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@@ -37,7 +37,6 @@ import org.mifosplatform.portfolio.savings.DepositAccountOnClosureType;
import org.mifosplatform.portfolio.savings.DepositAccountType; import org.mifosplatform.portfolio.savings.DepositAccountType;
import org.mifosplatform.portfolio.savings.DepositsApiConstants; import org.mifosplatform.portfolio.savings.DepositsApiConstants;
import org.mifosplatform.portfolio.savings.SavingsApiConstants; import org.mifosplatform.portfolio.savings.SavingsApiConstants;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.useradministration.domain.AppUser; import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -47,7 +46,6 @@ import org.springframework.transaction.annotation.Transactional;
public class DepositAccountDomainServiceJpa implements DepositAccountDomainService { public class DepositAccountDomainServiceJpa implements DepositAccountDomainService {
private final SavingsAccountRepositoryWrapper savingsAccountRepository; private final SavingsAccountRepositoryWrapper savingsAccountRepository;
private final SavingsAccountTransactionRepository savingsAccountTransactionRepository;
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper; private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper;
private final JournalEntryWritePlatformService journalEntryWritePlatformService; private final JournalEntryWritePlatformService journalEntryWritePlatformService;
private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory; private final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory;
@@ -57,14 +55,12 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
@Autowired @Autowired
public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository, public DepositAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository,
final SavingsAccountTransactionRepository savingsAccountTransactionRepository,
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper,
final JournalEntryWritePlatformService journalEntryWritePlatformService, final JournalEntryWritePlatformService journalEntryWritePlatformService,
final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final DepositAccountAssembler depositAccountAssembler, final AccountNumberGeneratorFactory accountIdentifierGeneratorFactory, final DepositAccountAssembler depositAccountAssembler,
final SavingsAccountDomainService savingsAccountDomainService, final SavingsAccountDomainService savingsAccountDomainService,
final AccountTransfersWritePlatformService accountTransfersWritePlatformService) { final AccountTransfersWritePlatformService accountTransfersWritePlatformService) {
this.savingsAccountRepository = savingsAccountRepository; this.savingsAccountRepository = savingsAccountRepository;
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper; this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper;
this.journalEntryWritePlatformService = journalEntryWritePlatformService; this.journalEntryWritePlatformService = journalEntryWritePlatformService;
this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory; this.accountIdentifierGeneratorFactory = accountIdentifierGeneratorFactory;
@@ -77,30 +73,11 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
@Override @Override
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
final boolean applyWithdrawFee) { final boolean applyWithdrawFee, final boolean isRegularTransaction) {
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
final SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, transactionDate, transactionAmount,
paymentDetail, new Date());
final SavingsAccountTransaction withdrawal = account.withdraw(transactionDTO, applyWithdrawFee);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final MathContext mc = MathContext.DECIMAL64; return this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, transactionAmount, paymentDetail,
if (account.isBeforeLastPostingPeriod(transactionDate)) { applyWithdrawFee, isInterestTransfer, isAccountTransfer, isRegularTransaction);
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.postInterest(mc, today, isInterestTransfer);
} else {
final LocalDate today = DateUtils.getLocalDateOfTenant();
account.calculateInterestUsing(mc, today, isInterestTransfer);
}
account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount);
saveTransactionToGenerateTransactionId(withdrawal);
this.savingsAccountRepository.save(account);
postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds, isAccountTransfer);
return withdrawal;
} }
@Transactional @Transactional
@@ -108,19 +85,21 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
public SavingsAccountTransaction handleFDDeposit(final FixedDepositAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleFDDeposit(final FixedDepositAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) { final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) {
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
boolean isRegularTransaction = false;
return this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, transactionAmount, paymentDetail, return this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, transactionAmount, paymentDetail,
isAccountTransfer); isAccountTransfer, isRegularTransaction);
} }
@Transactional @Transactional
@Override @Override
public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleRDDeposit(final RecurringDepositAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail) { final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
final boolean isRegularTransaction) {
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
final boolean isPreMatureClosure = false; final boolean isPreMatureClosure = false;
final MathContext mc = MathContext.DECIMAL64; final MathContext mc = MathContext.DECIMAL64;
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
transactionAmount, paymentDetail, isAccountTransfer); transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
account.handleScheduleInstallments(deposit); account.handleScheduleInstallments(deposit);
account.updateMaturityDateAndAmount(mc, isPreMatureClosure); account.updateMaturityDateAndAmount(mc, isPreMatureClosure);
@@ -132,6 +111,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
@Override @Override
public Long handleFDAccountClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user, public Long handleFDAccountClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) { final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
boolean isRegularTransaction = false;
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
final boolean isPreMatureClosure = false; final boolean isPreMatureClosure = false;
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
@@ -156,16 +136,18 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName); final LocalDate closedDate = command.localDateValueOfParameterNamed(SavingsApiConstants.closedOnDateParamName);
Long savingsTransactionId = null; Long savingsTransactionId = null;
account.postMaturityInterest(); account.postMaturityInterest();
if (account.isReinvestOnClosure()) { final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
if (onClosureType.isReinvest()) {
FixedDepositAccount reinvestedDeposit = account.reInvest(account.getAccountBalance()); FixedDepositAccount reinvestedDeposit = account.reInvest(account.getAccountBalance());
this.depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit); this.depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
reinvestedDeposit.updateMaturityDateAndAmountBeforeAccountActivation(mc,isPreMatureClosure); reinvestedDeposit.updateMaturityDateAndAmountBeforeAccountActivation(mc, isPreMatureClosure);
this.savingsAccountRepository.save(reinvestedDeposit); this.savingsAccountRepository.save(reinvestedDeposit);
autoGenerateAccountNumber(reinvestedDeposit); autoGenerateAccountNumber(reinvestedDeposit);
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} else if (account.isTransferToSavingsOnClosure()) { } else if (onClosureType.isTransferToSavings()) {
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName); final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName); final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId, final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
@@ -173,11 +155,12 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(),
PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null,
null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account); null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account,
isAccountTransfer);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} else { } else {
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} }
@@ -193,6 +176,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
@Override @Override
public Long handleRDAccountClosure(final RecurringDepositAccount account, final PaymentDetail paymentDetail, final AppUser user, public Long handleRDAccountClosure(final RecurringDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) { final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
boolean isRegularTransaction = false;
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
final boolean isPreMatureClosure = false; final boolean isPreMatureClosure = false;
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
@@ -206,7 +190,9 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
Long savingsTransactionId = null; Long savingsTransactionId = null;
account.postMaturityInterest(); account.postMaturityInterest();
final BigDecimal transactionAmount = account.getAccountBalance(); final BigDecimal transactionAmount = account.getAccountBalance();
if (account.isReinvestOnClosure()) { final Integer onAccountClosureId = command.integerValueOfParameterNamed(onAccountClosureIdParamName);
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
if (onClosureType.isReinvest()) {
RecurringDepositAccount reinvestedDeposit = account.reInvest(transactionAmount); RecurringDepositAccount reinvestedDeposit = account.reInvest(transactionAmount);
depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit); depositAccountAssembler.assignSavingAccountHelpers(reinvestedDeposit);
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure); reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure);
@@ -217,17 +203,17 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
Money amountForDeposit = reinvestedDeposit.activateWithBalance(); Money amountForDeposit = reinvestedDeposit.activateWithBalance();
if (amountForDeposit.isGreaterThanZero()) { if (amountForDeposit.isGreaterThanZero()) {
handleRDDeposit(reinvestedDeposit, fmt, reinvestedDeposit.getActivationLocalDate(), amountForDeposit.getAmount(), handleRDDeposit(reinvestedDeposit, fmt, reinvestedDeposit.getActivationLocalDate(), amountForDeposit.getAmount(),
paymentDetail); paymentDetail, isRegularTransaction);
} }
reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure); reinvestedDeposit.updateMaturityDateAndAmount(mc, isPreMatureClosure);
this.savingsAccountRepository.save(reinvestedDeposit); this.savingsAccountRepository.save(reinvestedDeposit);
autoGenerateAccountNumber(reinvestedDeposit); autoGenerateAccountNumber(reinvestedDeposit);
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} else if (account.isTransferToSavingsOnClosure()) { } else if (onClosureType.isTransferToSavings()) {
final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName); final Long toSavingsId = command.longValueOfParameterNamed(toSavingsAccountIdParamName);
final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName); final String transferDescription = command.stringValueOfParameterNamed(transferDescriptionParamName);
final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId, final SavingsAccount toSavingsAccount = this.depositAccountAssembler.assembleFrom(toSavingsId,
@@ -235,11 +221,12 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, transactionAmount, final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, transactionAmount,
PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null,
null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account); null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account,
isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} else { } else {
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} }
@@ -266,6 +253,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
public Long handleFDAccountPreMatureClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user, public Long handleFDAccountPreMatureClosure(final FixedDepositAccount account, final PaymentDetail paymentDetail, final AppUser user,
final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) { final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
boolean isRegularTransaction = false;
final boolean isPreMatureClosure = true; final boolean isPreMatureClosure = true;
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>(); final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
@@ -289,11 +277,12 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
DepositAccountType.SAVINGS_DEPOSIT); DepositAccountType.SAVINGS_DEPOSIT);
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(),
PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null,
null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account); null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account,
isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} else { } else {
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} }
@@ -311,6 +300,7 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
final AppUser user, final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) { final AppUser user, final JsonCommand command, final LocalDate tenantsTodayDate, final Map<String, Object> changes) {
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
final boolean isPreMatureClosure = true; final boolean isPreMatureClosure = true;
boolean isRegularTransaction = false;
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>(); final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -332,11 +322,12 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
DepositAccountType.SAVINGS_DEPOSIT); DepositAccountType.SAVINGS_DEPOSIT);
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(closedDate, account.getAccountBalance(),
PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, null, null, transferDescription, locale, fmt, null, null,
null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account); null, null, null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, toSavingsAccount, account,
isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} else { } else {
final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(), final SavingsAccountTransaction withdrawal = this.handleWithdrawal(account, fmt, closedDate, account.getAccountBalance(),
paymentDetail, false); paymentDetail, false, isRegularTransaction);
savingsTransactionId = withdrawal.getId(); savingsTransactionId = withdrawal.getId();
} }
@@ -346,11 +337,6 @@ public class DepositAccountDomainServiceJpa implements DepositAccountDomainServi
return savingsTransactionId; return savingsTransactionId;
} }
private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) {
this.savingsAccountTransactionRepository.save(transaction);
return transaction.getId();
}
private void updateExistingTransactionsDetails(SavingsAccount account, Set<Long> existingTransactionIds, private void updateExistingTransactionsDetails(SavingsAccount account, Set<Long> existingTransactionIds,
Set<Long> existingReversedTransactionIds) { Set<Long> existingReversedTransactionIds) {
existingTransactionIds.addAll(account.findExistingTransactionIds()); existingTransactionIds.addAll(account.findExistingTransactionIds());
@@ -13,10 +13,12 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_deposit_account_interest_incentives") @Table(name = "m_deposit_account_interest_incentives")
public class DepositAccountInterestIncentive extends AbstractPersistable<Long> { public class DepositAccountInterestIncentive extends AbstractPersistable<Long> {
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false)
private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs; private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs;
@SuppressWarnings("unused")
@Embedded @Embedded
private InterestIncentivesFields interestIncentivesFields; private InterestIncentivesFields interestIncentivesFields;
@@ -13,6 +13,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable;
@Table(name = "m_savings_interest_incentives") @Table(name = "m_savings_interest_incentives")
public class DepositAccountInterestIncentives extends AbstractPersistable<Long> { public class DepositAccountInterestIncentives extends AbstractPersistable<Long> {
@SuppressWarnings("unused")
@ManyToOne @ManyToOne
@JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false)
private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs; private DepositAccountInterestRateChartSlabs depositAccountInterestRateChartSlabs;
@@ -29,18 +29,21 @@ public class DepositAccountRecurringDetail extends AbstractPersistable<Long> {
@Column(name = "mandatory_recommended_deposit_amount", scale = 6, precision = 19, nullable = true) @Column(name = "mandatory_recommended_deposit_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal mandatoryRecommendedDepositAmount; private BigDecimal mandatoryRecommendedDepositAmount;
@SuppressWarnings("unused")
@Column(name = "total_overdue_amount", scale = 6, precision = 19, nullable = true) @Column(name = "total_overdue_amount", scale = 6, precision = 19, nullable = true)
private BigDecimal totalOverdueAmount; private BigDecimal totalOverdueAmount;
@Column(name = "is_calendar_inherited", nullable = false) @Column(name = "is_calendar_inherited", nullable = false)
private boolean isCalendarInherited; private boolean isCalendarInherited;
@SuppressWarnings("unused")
@Column(name = "no_of_overdue_installments", nullable = false) @Column(name = "no_of_overdue_installments", nullable = false)
private Integer noOfOverdueInstallments; private Integer noOfOverdueInstallments;
@Embedded @Embedded
private DepositRecurringDetail recurringDetail; private DepositRecurringDetail recurringDetail;
@SuppressWarnings("unused")
@OneToOne @OneToOne
@JoinColumn(name = "savings_account_id", nullable = false) @JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount account; private SavingsAccount account;
@@ -272,7 +272,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable<Long> {
final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy(); final DepositPreClosureDetail preClosureDetail = this.preClosureDetail.copy();
final DepositTermDetail depositTermDetail = this.depositTermDetail.copy(); final DepositTermDetail depositTermDetail = this.depositTermDetail.copy();
final LocalDate expectedFirstDepositOnDate = null; final LocalDate expectedFirstDepositOnDate = null;
final Boolean transferInterestToLinkedAccount = null; final Boolean transferInterestToLinkedAccount = false;
final DepositAccountOnClosureType accountOnClosureType = null; final DepositAccountOnClosureType accountOnClosureType = null;
return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, actualDepositAmount, maturityAmount, return DepositAccountTermAndPreClosure.createNew(preClosureDetail, depositTermDetail, account, actualDepositAmount, maturityAmount,
@@ -24,6 +24,7 @@ public class DepositProductRecurringDetail extends AbstractPersistable<Long> {
@Embedded @Embedded
private DepositRecurringDetail recurringDetail; private DepositRecurringDetail recurringDetail;
@SuppressWarnings("unused")
@OneToOne @OneToOne
@JoinColumn(name = "savings_product_id", nullable = false) @JoinColumn(name = "savings_product_id", nullable = false)
private RecurringDepositProduct product; private RecurringDepositProduct product;
@@ -28,6 +28,7 @@ public class DepositProductTermAndPreClosure extends AbstractPersistable<Long> {
@Embedded @Embedded
protected DepositTermDetail depositTermDetail; protected DepositTermDetail depositTermDetail;
@SuppressWarnings("unused")
@OneToOne @OneToOne
@JoinColumn(name = "savings_product_id", nullable = false) @JoinColumn(name = "savings_product_id", nullable = false)
private FixedDepositProduct product; private FixedDepositProduct product;
@@ -156,8 +156,7 @@ public class FixedDepositAccount extends SavingsAccount {
} }
final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount(); final BigDecimal depositAmount = accountTermAndPreClosure.depositAmount();
applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate, applicableInterestRate = this.chart.getApplicableInterestRate(depositAmount, depositStartDate(), depositCloseDate, this.client);
this.client);
if (applyPreMaturePenalty) { if (applyPreMaturePenalty) {
applicableInterestRate = applicableInterestRate.subtract(penalInterest); applicableInterestRate = applicableInterestRate.subtract(penalInterest);
@@ -291,8 +290,8 @@ public class FixedDepositAccount extends SavingsAccount {
return allPostingPeriods; return allPostingPeriods;
} }
public void prematureClosure(final AppUser currentUser, final JsonCommand command, public void prematureClosure(final AppUser currentUser, final JsonCommand command, final LocalDate tenantsTodayDate,
final LocalDate tenantsTodayDate, final Map<String, Object> actualChanges) { final Map<String, Object> actualChanges) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<ApiParameterError>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
@@ -348,13 +347,14 @@ public class FixedDepositAccount extends SavingsAccount {
final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId); final DepositAccountOnClosureType onClosureType = DepositAccountOnClosureType.fromInt(onAccountClosureId);
this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType); this.accountTermAndPreClosure.updateOnAccountClosureStatus(onClosureType);
/*
/* // withdraw deposit amount before closing the account * // withdraw deposit amount before closing the account final Money
final Money transactionAmountMoney = Money.of(this.currency, this.getAccountBalance()); * transactionAmountMoney = Money.of(this.currency,
final SavingsAccountTransaction withdraw = SavingsAccountTransaction.withdrawal(this, office(), paymentDetail, closedDate, * this.getAccountBalance()); final SavingsAccountTransaction withdraw =
transactionAmountMoney, new Date()); * SavingsAccountTransaction.withdrawal(this, office(), paymentDetail,
this.transactions.add(withdraw); * closedDate, transactionAmountMoney, new Date());
*/ * this.transactions.add(withdraw);
*/
actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status)); actualChanges.put(SavingsApiConstants.statusParamName, SavingsEnumerations.status(this.status));
actualChanges.put(SavingsApiConstants.localeParamName, command.locale()); actualChanges.put(SavingsApiConstants.localeParamName, command.locale());
actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat()); actualChanges.put(SavingsApiConstants.dateFormatParamName, command.dateFormat());
@@ -499,7 +499,8 @@ public class FixedDepositAccount extends SavingsAccount {
public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure) { public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure) {
Money interestPostedToDate = totalInterestPosted(); Money interestPostedToDate = totalInterestPosted();
final Money interestOnMaturity = calculatePreMatureInterest(accountCloseDate, retreiveOrderedNonInterestPostingTransactions(), isPreMatureClosure); final Money interestOnMaturity = calculatePreMatureInterest(accountCloseDate, retreiveOrderedNonInterestPostingTransactions(),
isPreMatureClosure);
boolean recalucateDailyBalance = false; boolean recalucateDailyBalance = false;
// post remaining interest // post remaining interest
@@ -734,4 +735,28 @@ public class FixedDepositAccount extends SavingsAccount {
protected boolean isTransferInterestToOtherAccount() { protected boolean isTransferInterestToOtherAccount() {
return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount(); return this.accountTermAndPreClosure.isTransferInterestToLinkedAccount();
} }
@Override
public boolean allowDeposit() {
return false;
}
@Override
public boolean allowWithdrawal() {
return false;
}
@Override
public boolean allowModify() {
return false;
}
@Override
public boolean isTransactionsAllowed() {
return isActive() || isAccountMatured();
}
private boolean isAccountMatured() {
return SavingsAccountStatusType.fromInt(status).isMatured();
}
} }
@@ -600,7 +600,8 @@ public class RecurringDepositAccount extends SavingsAccount {
public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure) { public void postPreMaturityInterest(final LocalDate accountCloseDate, final boolean isPreMatureClosure) {
final Money interestPostedToDate = totalInterestPosted(); final Money interestPostedToDate = totalInterestPosted();
final Money interestOnMaturity = calculatePreMatureInterest(accountCloseDate, retreiveOrderedNonInterestPostingTransactions(), isPreMatureClosure); final Money interestOnMaturity = calculatePreMatureInterest(accountCloseDate, retreiveOrderedNonInterestPostingTransactions(),
isPreMatureClosure);
boolean recalucateDailyBalance = false; boolean recalucateDailyBalance = false;
@@ -1078,6 +1079,7 @@ public class RecurringDepositAccount extends SavingsAccount {
this.recurringDetail.updateOverdueDetails(noOfOverdueInstallments, totalOverdueAmount); this.recurringDetail.updateOverdueDetails(noOfOverdueInstallments, totalOverdueAmount);
} }
@Override
public boolean allowWithdrawal() { public boolean allowWithdrawal() {
return this.recurringDetail.allowWithdrawal(); return this.recurringDetail.allowWithdrawal();
} }
@@ -1085,4 +1087,9 @@ public class RecurringDepositAccount extends SavingsAccount {
public boolean adjustAdvanceTowardsFuturePayments() { public boolean adjustAdvanceTowardsFuturePayments() {
return this.recurringDetail.adjustAdvanceTowardsFuturePayments(); return this.recurringDetail.adjustAdvanceTowardsFuturePayments();
} }
@Override
public boolean isTransactionsAllowed() {
return isActive() || isAccountMatured();
}
} }
@@ -668,7 +668,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
public SavingsAccountTransaction withdraw(final SavingsAccountTransactionDTO transactionDTO, final boolean applyWithdrawFee) { public SavingsAccountTransaction withdraw(final SavingsAccountTransactionDTO transactionDTO, final boolean applyWithdrawFee) {
if (isNotActive()) { if (!isTransactionsAllowed()) {
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",
@@ -2107,4 +2107,20 @@ public class SavingsAccount extends AbstractPersistable<Long> {
} }
} }
public boolean allowDeposit() {
return true;
}
public boolean allowWithdrawal() {
return true;
}
public boolean allowModify() {
return true;
}
public boolean isTransactionsAllowed() {
return isActive();
}
} }
@@ -14,8 +14,9 @@ import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
public interface SavingsAccountDomainService { public interface SavingsAccountDomainService {
SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate, SavingsAccountTransaction handleWithdrawal(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee, boolean isInterestTransfer, boolean isAccountTransfer); BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean applyWithdrawFee, boolean isInterestTransfer,
boolean isAccountTransfer, boolean isRegularTransaction);
SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate, SavingsAccountTransaction handleDeposit(SavingsAccount account, DateTimeFormatter fmt, LocalDate transactionDate,
BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isAccountTransfer); BigDecimal transactionAmount, PaymentDetail paymentDetail, boolean isAccountTransfer, boolean isRegularTransaction);
} }
@@ -21,6 +21,7 @@ import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyReposit
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.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO;
import org.mifosplatform.portfolio.savings.exception.DepositAccountTransactionNotAllowedException;
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;
@@ -48,8 +49,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
@Override @Override
public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleWithdrawal(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
final boolean applyWithdrawFee, boolean isInterestTransfer, final boolean isAccountTransfer) { final boolean applyWithdrawFee, boolean isInterestTransfer, final boolean isAccountTransfer, final boolean isRegularTransaction) {
if (isRegularTransaction && !account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException(account.getId(),
"withdraw", account.depositAccountType()); }
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>(); final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -78,7 +81,10 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi
@Override @Override
public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt, public SavingsAccountTransaction handleDeposit(final SavingsAccount account, final DateTimeFormatter fmt,
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail,
final boolean isAccountTransfer) { final boolean isAccountTransfer, final boolean isRegularTransaction) {
if (isRegularTransaction && !account.allowDeposit()) { throw new DepositAccountTransactionNotAllowedException(account.getId(),
"deposit", account.depositAccountType()); }
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
@@ -1387,10 +1387,11 @@ public class DepositAccountReadPlatformServiceImpl implements DepositAccountRead
final Long fromAccountId = rs.getLong("fromAcc"); final Long fromAccountId = rs.getLong("fromAcc");
final Long toAccountId = rs.getLong("toAcc"); final Long toAccountId = rs.getLong("toAcc");
final BigDecimal transactionAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount"); final BigDecimal transactionAmount = JdbcSupport.getBigDecimalDefaultToNullIfZero(rs, "amount");
final boolean isRegularTransaction = false;
final LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate"); final LocalDate transactionDate = JdbcSupport.getLocalDate(rs, "transactionDate");
return new AccountTransferDTO(transactionDate, transactionAmount, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, return new AccountTransferDTO(transactionDate, transactionAmount, PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
fromAccountId, toAccountId, "trasfer interest to savings", null, null, null, null, null, null, null, fromAccountId, toAccountId, "trasfer interest to savings", null, null, null, null, null, null, null,
AccountTransferType.INTEREST_TRANSFER.getValue(), null, null, null, null, null, null); AccountTransferType.INTEREST_TRANSFER.getValue(), null, null, null, null, null, null, isRegularTransaction);
} }
} }
@@ -197,10 +197,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
amountForDeposit.getAmount(), paymentDetail); amountForDeposit.getAmount(), paymentDetail);
} else { } else {
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
boolean isRegularTransaction = false;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(),
amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
portfolioAccountData.accountId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null, portfolioAccountData.accountId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null,
null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, account, fromSavingsAccount); null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, account, fromSavingsAccount,
isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
final boolean isInterestTransfer = false; final boolean isInterestTransfer = false;
@@ -236,6 +238,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
@Transactional @Transactional
@Override @Override
public CommandProcessingResult activateRDAccount(final Long savingsId, final JsonCommand command) { public CommandProcessingResult activateRDAccount(final Long savingsId, final JsonCommand command) {
boolean isRegularTransaction = false;
final AppUser user = this.context.authenticatedUser(); final AppUser user = this.context.authenticatedUser();
@@ -260,13 +263,14 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
.retriveSavingsAssociation(savingsId); .retriveSavingsAssociation(savingsId);
if (portfolioAccountData == null) { if (portfolioAccountData == null) {
this.depositAccountDomainService.handleRDDeposit(account, fmt, account.getActivationLocalDate(), this.depositAccountDomainService.handleRDDeposit(account, fmt, account.getActivationLocalDate(),
amountForDeposit.getAmount(), null); amountForDeposit.getAmount(), null, isRegularTransaction);
} else { } else {
final SavingsAccount fromSavingsAccount = null; final SavingsAccount fromSavingsAccount = null;
final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(), final AccountTransferDTO accountTransferDTO = new AccountTransferDTO(account.getActivationLocalDate(),
amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS, amountForDeposit.getAmount(), PortfolioAccountType.SAVINGS, PortfolioAccountType.SAVINGS,
portfolioAccountData.accountId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null, portfolioAccountData.accountId(), account.getId(), "Account Transfer", locale, fmt, null, null, null, null,
null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, account, fromSavingsAccount); null, AccountTransferType.ACCOUNT_TRANSFER.getValue(), null, null, null, null, account, fromSavingsAccount,
isRegularTransaction);
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} }
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -329,6 +333,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
@Transactional @Transactional
@Override @Override
public CommandProcessingResult depositToRDAccount(final Long savingsId, final JsonCommand command) { public CommandProcessingResult depositToRDAccount(final Long savingsId, final JsonCommand command) {
boolean isRegularTransaction = true;
this.context.authenticatedUser(); this.context.authenticatedUser();
@@ -347,7 +352,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Map<String, Object> changes = new LinkedHashMap<String, Object>(); final Map<String, Object> changes = new LinkedHashMap<String, Object>();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final SavingsAccountTransaction deposit = this.depositAccountDomainService.handleRDDeposit(account, fmt, transactionDate, final SavingsAccountTransaction deposit = this.depositAccountDomainService.handleRDDeposit(account, fmt, transactionDate,
transactionAmount, paymentDetail); transactionAmount, paymentDetail, isRegularTransaction);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(deposit.getId()) // .withEntityId(deposit.getId()) //
@@ -368,10 +373,9 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
@Override @Override
public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, final DepositAccountType depositAccountType) { public CommandProcessingResult withdrawal(final Long savingsId, final JsonCommand command, final DepositAccountType depositAccountType) {
this.depositAccountTransactionDataValidator.validate(command, depositAccountType); boolean isRegularTransaction = true;
if (depositAccountType.isFixedDeposit()) { throw new DepositAccountTransactionNotAllowedException(savingsId, "withdrawal", this.depositAccountTransactionDataValidator.validate(command, depositAccountType);
depositAccountType); }
final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate"); final LocalDate transactionDate = command.localDateValueOfParameterNamed("transactionDate");
final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount"); final BigDecimal transactionAmount = command.bigDecimalValueOfParameterNamed("transactionAmount");
@@ -382,15 +386,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
final Map<String, Object> changes = new LinkedHashMap<String, Object>(); final Map<String, Object> changes = new LinkedHashMap<String, Object>();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(savingsId, final SavingsAccount account = this.depositAccountAssembler.assembleFrom(savingsId, depositAccountType);
depositAccountType);
if (!account.allowWithdrawal()) { throw new DepositAccountTransactionNotAllowedException(savingsId, "withdrawal",
depositAccountType); }
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
final SavingsAccountTransaction withdrawal = this.depositAccountDomainService.handleWithdrawal(account, fmt, transactionDate, final SavingsAccountTransaction withdrawal = this.depositAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail, true); transactionAmount, paymentDetail, true, isRegularTransaction);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(withdrawal.getId()) // .withEntityId(withdrawal.getId()) //
@@ -1169,11 +1170,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
@Transactional @Transactional
@Override @Override
public SavingsAccountTransaction mandatorySavingsAccountDeposit(final SavingsAccountTransactionDTO accountTransactionDTO) { public SavingsAccountTransaction mandatorySavingsAccountDeposit(final SavingsAccountTransactionDTO accountTransactionDTO) {
boolean isRegularTransaction = false;
final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom( final RecurringDepositAccount account = (RecurringDepositAccount) this.depositAccountAssembler.assembleFrom(
accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT); accountTransactionDTO.getSavingsAccountId(), DepositAccountType.RECURRING_DEPOSIT);
return this.depositAccountDomainService.handleRDDeposit(account, accountTransactionDTO.getFormatter(), return this.depositAccountDomainService.handleRDDeposit(account, accountTransactionDTO.getFormatter(),
accountTransactionDTO.getTransactionDate(), accountTransactionDTO.getTransactionAmount(), accountTransactionDTO.getTransactionDate(), accountTransactionDTO.getTransactionAmount(),
accountTransactionDTO.getPaymentDetail()); accountTransactionDTO.getPaymentDetail(), isRegularTransaction);
} }
} }
@@ -156,9 +156,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
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);
Money amountForDeposit = account.activateWithBalance(); Money amountForDeposit = account.activateWithBalance();
boolean isRegularTransaction = false;
if (amountForDeposit.isGreaterThanZero()) { if (amountForDeposit.isGreaterThanZero()) {
this.savingsAccountDomainService.handleDeposit(account, fmt, account.getActivationLocalDate(), this.savingsAccountDomainService.handleDeposit(account, fmt, account.getActivationLocalDate(),
amountForDeposit.getAmount(), null, isAccountTransfer); amountForDeposit.getAmount(), null, isAccountTransfer, isRegularTransaction);
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
} }
account.processAccountUponActivation(); account.processAccountUponActivation();
@@ -199,8 +200,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
final Map<String, Object> changes = new LinkedHashMap<String, Object>(); final Map<String, Object> changes = new LinkedHashMap<String, Object>();
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes); final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createAndPersistPaymentDetail(command, changes);
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
boolean isRegularTransaction = true;
final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate, final SavingsAccountTransaction deposit = this.savingsAccountDomainService.handleDeposit(account, fmt, transactionDate,
transactionAmount, paymentDetail, isAccountTransfer); transactionAmount, paymentDetail, isAccountTransfer, isRegularTransaction);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(deposit.getId()) // .withEntityId(deposit.getId()) //
@@ -236,8 +238,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
checkClientOrGroupActive(account); checkClientOrGroupActive(account);
boolean isInterestTransfer = false; boolean isInterestTransfer = false;
boolean isAccountTransfer = false; boolean isAccountTransfer = false;
boolean isRegularTransaction = true;
final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate, final SavingsAccountTransaction withdrawal = this.savingsAccountDomainService.handleWithdrawal(account, fmt, transactionDate,
transactionAmount, paymentDetail, true, isInterestTransfer, isAccountTransfer); transactionAmount, paymentDetail, true, isInterestTransfer, isAccountTransfer, isRegularTransaction);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(withdrawal.getId()) // .withEntityId(withdrawal.getId()) //
@@ -362,6 +365,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
"error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId "error.msg.saving.account.transfer.transaction.update.not.allowed", "Savings account transaction:" + transactionId
+ " update not allowed as it involves in account transfer", transactionId); } + " update not allowed as it involves in account transfer", transactionId); }
if (!account.allowModify()) { throw new PlatformServiceUnavailableException(
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId
+ " update not allowed for this savings type", transactionId); }
final LocalDate today = DateUtils.getLocalDateOfTenant(); final LocalDate today = DateUtils.getLocalDateOfTenant();
final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN); final MathContext mc = new MathContext(15, RoundingMode.HALF_EVEN);
@@ -422,6 +429,9 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
if (account.isNotActive()) { if (account.isNotActive()) {
throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction); throwValidationForActiveStatus(SavingsApiConstants.adjustTransactionAction);
} }
if (!account.allowModify()) { throw new PlatformServiceUnavailableException(
"error.msg.saving.account.transaction.update.not.allowed", "Savings account transaction:" + transactionId
+ " update not allowed for this savings type", transactionId); }
final Set<Long> existingTransactionIds = new HashSet<Long>(); final Set<Long> existingTransactionIds = new HashSet<Long>();
final Set<Long> existingReversedTransactionIds = new HashSet<Long>(); final Set<Long> existingReversedTransactionIds = new HashSet<Long>();
updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds);
@@ -457,8 +457,9 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl
// save account entity before performing deposit transaction, as // save account entity before performing deposit transaction, as
// accountId is required for persist transaction entity. // accountId is required for persist transaction entity.
this.savingAccountRepository.save(account); this.savingAccountRepository.save(account);
boolean isRegularTransaction = false;
this.savingsAccountDomainService.handleDeposit(account, savingsAccountDataDTO.getFmt(), account.getActivationLocalDate(), this.savingsAccountDomainService.handleDeposit(account, savingsAccountDataDTO.getFmt(), account.getActivationLocalDate(),
amountForDeposit.getAmount(), null, isAccountTransfer); amountForDeposit.getAmount(), null, isAccountTransfer, isRegularTransaction);
} }
account.processAccountUponActivation(); account.processAccountUponActivation();
account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name()); account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name());