From 9e4cb99853cb95545213778cd275efbc7658b56b Mon Sep 17 00:00:00 2001 From: andrew-dzak Date: Tue, 17 Nov 2015 09:35:58 +0100 Subject: [PATCH] MIFOSX-2348 fixed Insufficient account balance due to guarantors funds onhold --- .../DepositAccountOnHoldTransaction.java | 26 +++- ...sitAccountOnHoldTransactionRepository.java | 3 + .../savings/domain/SavingsAccount.java | 141 +++++++++++------- .../SavingsAccountDomainServiceJpa.java | 26 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 82 ++++++---- ...WritePlatformServiceJpaRepositoryImpl.java | 73 ++++++--- 6 files changed, 233 insertions(+), 118 deletions(-) mode change 100644 => 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java mode change 100644 => 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java mode change 100644 => 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java mode change 100644 => 100755 mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java index 99db4bd5a..3cf65eef7 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransaction.java @@ -5,8 +5,12 @@ */ package org.mifosplatform.portfolio.savings.domain; -import java.math.BigDecimal; -import java.util.Date; +import org.joda.time.LocalDate; +import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; +import org.mifosplatform.organisation.monetary.domain.Money; +import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction; +import org.mifosplatform.portfolio.savings.DepositAccountOnHoldTransactionType; +import org.springframework.data.jpa.domain.AbstractPersistable; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -17,11 +21,8 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; - -import org.joda.time.LocalDate; -import org.mifosplatform.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction; -import org.mifosplatform.portfolio.savings.DepositAccountOnHoldTransactionType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import java.math.BigDecimal; +import java.util.Date; @Entity @Table(name = "m_deposit_account_on_hold_transaction") @@ -81,6 +82,10 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistable { return this.amount; } + public Money getAmountMoney(final MonetaryCurrency currency) { + return Money.of(currency, this.amount); + } + public void reverseTransaction() { this.reversed = true; if (this.getTransactionType().isHold()) { @@ -92,7 +97,14 @@ public class DepositAccountOnHoldTransaction extends AbstractPersistable { public DepositAccountOnHoldTransactionType getTransactionType() { return DepositAccountOnHoldTransactionType.fromInt(this.transactionType); + } + public LocalDate getTransactionDate() { + LocalDate transactionDate = null; + if(this.transactionDate !=null){ + transactionDate = LocalDate.fromDateFields(this.transactionDate); + } + return transactionDate; } } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransactionRepository.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransactionRepository.java index 3b0259354..e476824df 100755 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransactionRepository.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/DepositAccountOnHoldTransactionRepository.java @@ -8,7 +8,10 @@ package org.mifosplatform.portfolio.savings.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import java.util.List; + public interface DepositAccountOnHoldTransactionRepository extends JpaRepository, JpaSpecificationExecutor { + List findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(SavingsAccount account); } diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java old mode 100644 new mode 100755 index fabb39e56..0fa7a0ab1 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccount.java @@ -5,52 +5,7 @@ */ package org.mifosplatform.portfolio.savings.domain; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.allowOverdraftParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localeParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.overdraftLimitParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.DiscriminatorColumn; -import javax.persistence.DiscriminatorType; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.persistence.Version; - +import com.google.gson.JsonArray; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.hibernate.annotations.LazyCollection; @@ -96,7 +51,50 @@ import org.mifosplatform.useradministration.domain.AppUser; import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.util.CollectionUtils; -import com.google.gson.JsonArray; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.DiscriminatorColumn; +import javax.persistence.DiscriminatorType; +import javax.persistence.DiscriminatorValue; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OrderBy; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.persistence.Version; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.allowOverdraftParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localeParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.minRequiredBalanceParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.overdraftLimitParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName; @Entity @Table(name = "m_savings_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "sa_account_no_UNIQUE"), @@ -859,10 +857,11 @@ public class SavingsAccount extends AbstractPersistable { return transactionBeforeLastInterestPosting; } - public void validateAccountBalanceDoesNotBecomeNegative(final BigDecimal transactionAmount, final boolean isException) { + public void validateAccountBalanceDoesNotBecomeNegative(final BigDecimal transactionAmount, final boolean isException,final List depositAccountOnHoldTransactions) { final List transactionsSortedByDate = retreiveListOfTransactions(); Money runningBalance = Money.zero(this.currency); Money minRequiredBalance = minRequiredBalanceDerived(getCurrency()); + LocalDate lastSavingsDate = null; for (final SavingsAccountTransaction transaction : transactionsSortedByDate) { if (transaction.isNotReversed() && transaction.isCredit()) { runningBalance = runningBalance.plus(transaction.getAmount(this.currency)); @@ -872,22 +871,44 @@ public class SavingsAccount extends AbstractPersistable { continue; } + + final BigDecimal withdrawalFee = null; + + /* Loop through the onHold funds and see if we need to deduct or add to minimum required balance + and the point in time the transaction was made: */ + if(depositAccountOnHoldTransactions !=null){ + for(final DepositAccountOnHoldTransaction onHoldTransaction: depositAccountOnHoldTransactions) { + // Compare the balance of the on hold: + if((onHoldTransaction.getTransactionDate().isBefore(transaction.transactionLocalDate()) || onHoldTransaction.getTransactionDate().isEqual(transaction.transactionLocalDate())) + && (lastSavingsDate == null || onHoldTransaction.getTransactionDate().isAfter(lastSavingsDate))) { + if(onHoldTransaction.getTransactionType().isHold()) { + minRequiredBalance = minRequiredBalance.plus(onHoldTransaction.getAmountMoney(this.currency)); + }else{ + minRequiredBalance = minRequiredBalance.minus(onHoldTransaction.getAmountMoney(this.currency)); + } + } + } + } + + // deal with potential minRequiredBalance and // enforceMinRequiredBalance if (!isException && transaction.canProcessBalanceCheck()) { if (runningBalance.minus(minRequiredBalance).isLessThanZero()) { throw new InsufficientAccountBalanceException( "transactionAmount", getAccountBalance(), withdrawalFee, transactionAmount); } } + lastSavingsDate = transaction.transactionLocalDate(); } } - public void validateAccountBalanceDoesNotBecomeNegative(final String transactionAction) { + public void validateAccountBalanceDoesNotBecomeNegative(final String transactionAction,final List depositAccountOnHoldTransactions) { final List transactionsSortedByDate = retreiveListOfTransactions(); Money runningBalance = Money.zero(this.currency); Money minRequiredBalance = minRequiredBalanceDerived(getCurrency()); + LocalDate lastSavingsDate = null; for (final SavingsAccountTransaction transaction : transactionsSortedByDate) { if (transaction.isNotReversed() && transaction.isCredit()) { runningBalance = runningBalance.plus(transaction.getAmount(this.currency)); @@ -895,6 +916,22 @@ public class SavingsAccount extends AbstractPersistable { runningBalance = runningBalance.minus(transaction.getAmount(this.currency)); } + /* Loop through the onHold funds and see if we need to deduct or add to minimum required balance + and the point in time the transaction was made: */ + if(depositAccountOnHoldTransactions !=null){ + for(final DepositAccountOnHoldTransaction onHoldTransaction: depositAccountOnHoldTransactions) { + // Compare the balance of the on hold: + if((onHoldTransaction.getTransactionDate().isBefore(transaction.transactionLocalDate()) || onHoldTransaction.getTransactionDate().isEqual(transaction.transactionLocalDate())) + && (lastSavingsDate == null || onHoldTransaction.getTransactionDate().isAfter(lastSavingsDate))) { + if(onHoldTransaction.getTransactionType().isHold()) { + minRequiredBalance = minRequiredBalance.plus(onHoldTransaction.getAmountMoney(this.currency)); + }else{ + minRequiredBalance = minRequiredBalance.minus(onHoldTransaction.getAmountMoney(this.currency)); + } + } + } + } + // enforceMinRequiredBalance if (transaction.canProcessBalanceCheck()) { if (runningBalance.minus(minRequiredBalance).isLessThanZero()) { @@ -910,6 +947,8 @@ public class SavingsAccount extends AbstractPersistable { } } + lastSavingsDate = transaction.transactionLocalDate(); + } } @@ -2454,7 +2493,7 @@ public class SavingsAccount extends AbstractPersistable { } private Money minRequiredBalanceDerived(final MonetaryCurrency currency) { - Money minReqBalance = Money.of(currency, this.onHoldFunds); + Money minReqBalance = Money.zero(currency); if (this.enforceMinRequiredBalance) { minReqBalance = minReqBalance.plus(this.minRequiredBalance); } @@ -2477,6 +2516,6 @@ public class SavingsAccount extends AbstractPersistable { } public BigDecimal getWithdrawableBalance() { - return getAccountBalance().subtract(minRequiredBalanceDerived(getCurrency()).getAmount()); + return getAccountBalance().subtract(minRequiredBalanceDerived(getCurrency()).getAmount()).subtract(this.getOnHoldFunds()); } } \ No newline at end of file diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java old mode 100644 new mode 100755 index b4753400e..fa36b4ff3 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/domain/SavingsAccountDomainServiceJpa.java @@ -5,13 +5,6 @@ */ package org.mifosplatform.portfolio.savings.domain; -import java.math.BigDecimal; -import java.math.MathContext; -import java.util.Date; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormatter; import org.mifosplatform.accounting.journalentry.service.JournalEntryWritePlatformService; @@ -30,6 +23,14 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + @Service public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainService { @@ -39,19 +40,22 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper; private final JournalEntryWritePlatformService journalEntryWritePlatformService; private final ConfigurationDomainService configurationDomainService; + private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository; @Autowired public SavingsAccountDomainServiceJpa(final SavingsAccountRepositoryWrapper savingsAccountRepository, final SavingsAccountTransactionRepository savingsAccountTransactionRepository, final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepositoryWrapper, final JournalEntryWritePlatformService journalEntryWritePlatformService, - final ConfigurationDomainService configurationDomainService, final PlatformSecurityContext context) { + final ConfigurationDomainService configurationDomainService, final PlatformSecurityContext context, + final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) { this.savingsAccountRepository = savingsAccountRepository; this.savingsAccountTransactionRepository = savingsAccountTransactionRepository; this.applicationCurrencyRepositoryWrapper = applicationCurrencyRepositoryWrapper; this.journalEntryWritePlatformService = journalEntryWritePlatformService; this.configurationDomainService = configurationDomainService; this.context = context; + this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository; } @Transactional @@ -84,7 +88,11 @@ public class SavingsAccountDomainServiceJpa implements SavingsAccountDomainServi account.calculateInterestUsing(mc, today, transactionBooleanValues.isInterestTransfer(), isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } - account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount, transactionBooleanValues.isExceptionForBalanceCheck()); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + account.validateAccountBalanceDoesNotBecomeNegative(transactionAmount, transactionBooleanValues.isExceptionForBalanceCheck(), depositAccountOnHoldTransactions); saveTransactionToGenerateTransactionId(withdrawal); this.savingsAccountRepository.save(account); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java old mode 100644 new mode 100755 index 770b50890..6d787f2f7 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -5,24 +5,6 @@ */ package org.mifosplatform.portfolio.savings.service; -import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; @@ -42,7 +24,6 @@ import org.mifosplatform.infrastructure.jobs.exception.JobExecutionException; import org.mifosplatform.infrastructure.jobs.service.JobName; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.organisation.holiday.domain.HolidayRepositoryWrapper; -import org.mifosplatform.organisation.holiday.service.HolidayWritePlatformService; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency; import org.mifosplatform.organisation.monetary.domain.ApplicationCurrencyRepositoryWrapper; import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency; @@ -51,7 +32,6 @@ import org.mifosplatform.organisation.monetary.domain.MoneyHelper; import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper; -import org.mifosplatform.organisation.workingdays.service.WorkingDaysWritePlatformService; import org.mifosplatform.portfolio.account.PortfolioAccountType; import org.mifosplatform.portfolio.account.data.AccountTransferDTO; import org.mifosplatform.portfolio.account.data.PortfolioAccountData; @@ -86,6 +66,8 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeDataValidato import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO; import org.mifosplatform.portfolio.savings.domain.DepositAccountAssembler; import org.mifosplatform.portfolio.savings.domain.DepositAccountDomainService; +import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransaction; +import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository; import org.mifosplatform.portfolio.savings.domain.DepositAccountRecurringDetail; import org.mifosplatform.portfolio.savings.domain.FixedDepositAccount; import org.mifosplatform.portfolio.savings.domain.RecurringDepositAccount; @@ -105,6 +87,23 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import static org.mifosplatform.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_ACCOUNT_RESOURCE_NAME; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; + @Service public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements DepositAccountWritePlatformService { @@ -129,6 +128,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo private final ConfigurationDomainService configurationDomainService; private final HolidayRepositoryWrapper holidayRepository; private final WorkingDaysRepositoryWrapper workingDaysRepository; + private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository; + @Autowired public DepositAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, @@ -147,7 +148,8 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, final AccountTransfersWritePlatformService accountTransfersWritePlatformService, final DepositAccountReadPlatformService depositAccountReadPlatformService, - final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService) { + final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService, + final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) { this.context = context; this.savingAccountRepository = savingAccountRepository; @@ -170,6 +172,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo this.depositAccountReadPlatformService = depositAccountReadPlatformService; this.calendarInstanceRepository = calendarInstanceRepository; this.configurationDomainService = configurationDomainService; + this.depositAccountOnHoldTransactionRepository =depositAccountOnHoldTransactionRepository; } @Transactional @@ -235,7 +238,11 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final boolean isPreMatureClosure = false; account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); - account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name()); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); this.savingAccountRepository.save(account); } @@ -327,8 +334,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name()); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); this.savingAccountRepository.save(account); } @@ -586,7 +597,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions); // account.activateAccountBasedOnBalance(); final boolean isPreMatureClosure = false; account.updateMaturityDateAndAmount(mc, isPreMatureClosure, isSavingsInterestPostingAtCurrentPeriodEnd, @@ -682,8 +698,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); if (savingsAccountTransaction.isDeposit()) { @@ -1118,8 +1138,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions); this.savingAccountRepository.saveAndFlush(account); @@ -1245,8 +1269,12 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode()); + account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions); this.savingAccountRepository.save(account); diff --git a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java old mode 100644 new mode 100755 index 6a2faae29..ad8520938 --- a/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/mifosng-provider/src/main/java/org/mifosplatform/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -5,24 +5,6 @@ */ package org.mifosplatform.portfolio.savings.service; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; -import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName; - -import java.math.BigDecimal; -import java.math.MathContext; -import java.math.RoundingMode; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - import org.apache.commons.lang.StringUtils; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; @@ -68,6 +50,8 @@ import org.mifosplatform.portfolio.savings.data.SavingsAccountChargeDataValidato import org.mifosplatform.portfolio.savings.data.SavingsAccountDataValidator; import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDTO; import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionDataValidator; +import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransaction; +import org.mifosplatform.portfolio.savings.domain.DepositAccountOnHoldTransactionRepository; import org.mifosplatform.portfolio.savings.domain.SavingsAccount; import org.mifosplatform.portfolio.savings.domain.SavingsAccountAssembler; import org.mifosplatform.portfolio.savings.domain.SavingsAccountCharge; @@ -89,6 +73,23 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; +import java.math.BigDecimal; +import java.math.MathContext; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_CHARGE_RESOURCE_NAME; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.amountParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.chargeIdParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.dueAsOfDateParamName; +import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawBalanceParamName; + @Service public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements SavingsAccountWritePlatformService { @@ -113,6 +114,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi private final HolidayRepositoryWrapper holidayRepository; private final WorkingDaysRepositoryWrapper workingDaysRepository; private final ConfigurationDomainService configurationDomainService; + private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository; + @Autowired public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, @@ -130,7 +133,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService, final ChargeRepositoryWrapper chargeRepository, final SavingsAccountChargeRepositoryWrapper savingsAccountChargeRepository, final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountRepositoryWrapper savingsRepository, - final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService) { + final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService, + final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository) { this.context = context; this.savingAccountRepository = savingAccountRepository; this.savingsAccountTransactionRepository = savingsAccountTransactionRepository; @@ -152,6 +156,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi this.savingsRepository = savingsRepository; this.staffRepository = staffRepository; this.configurationDomainService = configurationDomainService; + this.depositAccountOnHoldTransactionRepository= depositAccountOnHoldTransactionRepository; } @Transactional @@ -208,7 +213,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); } account.processAccountUponActivation(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth, user); - account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name()); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); } @Transactional @@ -440,7 +449,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction,depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); @@ -525,7 +538,11 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction); + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction,depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // @@ -869,8 +886,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction); + account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.waiveChargeTransactionAction,depositAccountOnHoldTransactions); this.savingAccountRepository.saveAndFlush(account); @@ -995,8 +1016,12 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi account.calculateInterestUsing(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } + List depositAccountOnHoldTransactions = null; + if(account.getOnHoldFunds().compareTo(BigDecimal.ZERO) == 1){ + depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); + } - account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode()); + account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions); this.savingAccountRepository.save(account);