Merge pull request #578 from vishwasbabu/develop

map savings account transactions to an Office in preparation for savings...
This commit is contained in:
Vishwas Babu A J
2013-09-09 20:32:50 -07:00
4 changed files with 94 additions and 53 deletions
@@ -0,0 +1,15 @@
ALTER TABLE `m_savings_account_transaction`
ADD COLUMN `office_id` BIGINT(20) NULL DEFAULT NULL AFTER `savings_account_id`;
/**update client savings**/
UPDATE m_savings_account_transaction st set st.office_id = (SELECT c.office_id AS officeId FROM m_savings_account sa JOIN m_client c on sa.client_id=c.id where sa.id=st.savings_account_id) where st.savings_account_id in (Select sa.id from m_savings_account sa where sa.client_id is not null);
/**update group savings**/
UPDATE m_savings_account_transaction st set st.office_id = (SELECT g.office_id AS officeId FROM m_savings_account sa JOIN m_group g on sa.group_id=g.id where sa.id=st.savings_account_id) where st.savings_account_id in (Select sa.id from m_savings_account sa where sa.group_id is not null);
/**Add foreign key constraints**/
ALTER TABLE `m_savings_account_transaction`
CHANGE COLUMN `office_id` `office_id` BIGINT(20) NOT NULL AFTER `savings_account_id`;
ALTER TABLE `m_savings_account_transaction`
ADD CONSTRAINT `FK_m_savings_account_transaction_m_office` FOREIGN KEY (`office_id`) REFERENCES `m_office` (`id`);
@@ -12,8 +12,8 @@ import static org.mifosplatform.portfolio.savings.SavingsApiConstants.localePara
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeAmountParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeTypeParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName;
import static org.mifosplatform.portfolio.savings.SavingsApiConstants.withdrawalFeeTypeParamName;
import java.math.BigDecimal;
import java.math.MathContext;
@@ -59,6 +59,7 @@ import org.mifosplatform.infrastructure.security.service.RandomPasswordGenerator
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.portfolio.accountdetails.domain.AccountType;
import org.mifosplatform.portfolio.client.domain.Client;
@@ -376,7 +377,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
final SavingsAccountTransaction postingTransaction = findInterestPostingTransactionFor(interestPostingTransactionDate);
if (postingTransaction == null) {
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this,
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
@@ -384,7 +385,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
final boolean correctionRequired = postingTransaction.hasNotAmount(interestEarnedToBePostedForPeriod);
if (correctionRequired) {
postingTransaction.reverse();
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this,
final SavingsAccountTransaction newPostingTransaction = SavingsAccountTransaction.interestPosting(this, office(),
interestPostingTransactionDate, interestEarnedToBePostedForPeriod);
this.transactions.add(newPostingTransaction);
recalucateDailyBalanceDetails = true;
@@ -590,7 +591,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
final Money amount = Money.of(this.currency, transactionDTO.getTransactionAmount());
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, transactionDTO.getPaymentDetail(),
final SavingsAccountTransaction transaction = SavingsAccountTransaction.deposit(this, office(), transactionDTO.getPaymentDetail(),
transactionDTO.getTransactionDate(), amount);
this.transactions.add(transaction);
@@ -663,8 +664,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
transactionDTO.getExistingReversedTransactionIds().addAll(findExistingReversedTransactionIds());
final Money transactionAmountMoney = Money.of(this.currency, transactionDTO.getTransactionAmount());
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, transactionDTO.getPaymentDetail(),
transactionDTO.getTransactionDate(), transactionAmountMoney);
final SavingsAccountTransaction transaction = SavingsAccountTransaction.withdrawal(this, office(),
transactionDTO.getPaymentDetail(), transactionDTO.getTransactionDate(), transactionAmountMoney);
this.transactions.add(transaction);
if (applyWithdrawFee && isAutomaticWithdrawalFee()) {
@@ -676,14 +677,16 @@ public class SavingsAccount extends AbstractPersistable<Long> {
break;
case FLAT:
feeAmount = Money.of(this.currency, this.withdrawalFeeAmount);
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDTO.getTransactionDate(), feeAmount);
withdrawalFeeTransaction = SavingsAccountTransaction
.fee(this, office(), transactionDTO.getTransactionDate(), feeAmount);
this.transactions.add(withdrawalFeeTransaction);
break;
case PERCENT_OF_AMOUNT:
final BigDecimal feeAmountDecimal = transactionDTO.getTransactionAmount().multiply(this.withdrawalFeeAmount)
.divide(BigDecimal.valueOf(100l));
feeAmount = Money.of(this.currency, feeAmountDecimal);
withdrawalFeeTransaction = SavingsAccountTransaction.fee(this, transactionDTO.getTransactionDate(), feeAmount);
withdrawalFeeTransaction = SavingsAccountTransaction
.fee(this, office(), transactionDTO.getTransactionDate(), feeAmount);
this.transactions.add(withdrawalFeeTransaction);
break;
}
@@ -722,8 +725,7 @@ public class SavingsAccount extends AbstractPersistable<Long> {
if (runningBalance.isLessThanZero()) {
//
final BigDecimal withdrawalFee = null;
throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), withdrawalFee,
transactionAmount);
throw new InsufficientAccountBalanceException("transactionAmount", getAccountBalance(), withdrawalFee, transactionAmount);
}
}
}
@@ -806,8 +808,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
final Money annualFee = Money.of(this.currency, this.annualFeeAmount);
final SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, annualFeeTransactionDate,
annualFee);
final SavingsAccountTransaction annualFeeTransaction = SavingsAccountTransaction.annualFee(this, office(),
annualFeeTransactionDate, annualFee);
this.transactions.add(annualFeeTransaction);
validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.applyAnnualFeeTransactionAction);
@@ -1247,6 +1249,16 @@ public class SavingsAccount extends AbstractPersistable<Long> {
return officeId;
}
public Office office() {
Office office = null;
if (this.client != null) {
office = this.client.getOffice();
} else {
office = this.group.getOffice();
}
return office;
}
public Long clientId() {
Long id = null;
if (this.client != null) {
@@ -1669,8 +1681,8 @@ public class SavingsAccount extends AbstractPersistable<Long> {
// activating account.
final Money minRequiredOpeningBalance = Money.of(this.currency, this.minRequiredOpeningBalance);
if (minRequiredOpeningBalance.isGreaterThanZero()) {
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, activationDate, minRequiredOpeningBalance.getAmount(),
existingTransactionIds, existingReversedTransactionIds, null);
SavingsAccountTransactionDTO transactionDTO = new SavingsAccountTransactionDTO(fmt, activationDate,
minRequiredOpeningBalance.getAmount(), existingTransactionIds, existingReversedTransactionIds, null);
deposit(transactionDTO);
}
@@ -23,6 +23,7 @@ import org.mifosplatform.infrastructure.core.domain.LocalDateInterval;
import org.mifosplatform.organisation.monetary.data.CurrencyData;
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
import org.mifosplatform.portfolio.savings.SavingsAccountTransactionType;
import org.mifosplatform.portfolio.savings.data.SavingsAccountTransactionEnumData;
@@ -42,6 +43,10 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
@JoinColumn(name = "savings_account_id", nullable = false)
private SavingsAccount savingsAccount;
@ManyToOne
@JoinColumn(name = "office_id", nullable = false)
private Office office;
@ManyToOne(optional = true)
@JoinColumn(name = "payment_detail_id", nullable = true)
private PaymentDetail paymentDetail;
@@ -77,45 +82,50 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
this.typeOf = null;
}
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail,
final LocalDate date, final Money amount) {
public static SavingsAccountTransaction deposit(final SavingsAccount savingsAccount, final Office office,
final PaymentDetail paymentDetail, final LocalDate date, final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date, amount,
isReversed);
}
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail,
final LocalDate date, final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(), date,
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.DEPOSIT.getValue(), date,
amount, isReversed);
}
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
public static SavingsAccountTransaction withdrawal(final SavingsAccount savingsAccount, final Office office,
final PaymentDetail paymentDetail, final LocalDate date, final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date, amount,
return new SavingsAccountTransaction(savingsAccount, office, paymentDetail, SavingsAccountTransactionType.WITHDRAWAL.getValue(),
date, amount, isReversed);
}
public static SavingsAccountTransaction interestPosting(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.INTEREST_POSTING.getValue(), date,
amount, isReversed);
}
public static SavingsAccountTransaction fee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount,
isReversed);
}
public static SavingsAccountTransaction fee(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final Office office, final LocalDate date,
final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.WITHDRAWAL_FEE.getValue(), date, amount,
return new SavingsAccountTransaction(savingsAccount, office, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount,
isReversed);
}
public static SavingsAccountTransaction annualFee(final SavingsAccount savingsAccount, final LocalDate date, final Money amount) {
final boolean isReversed = false;
return new SavingsAccountTransaction(savingsAccount, SavingsAccountTransactionType.ANNUAL_FEE.getValue(), date, amount, isReversed);
}
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Integer typeOf, final LocalDate transactionLocalDate,
final Money amount, final boolean isReversed) {
this(savingsAccount, null, typeOf, transactionLocalDate, amount, isReversed);
}
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final PaymentDetail paymentDetail, final Integer typeOf,
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final Integer typeOf,
final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
this(savingsAccount, office, null, typeOf, transactionLocalDate, amount, isReversed);
}
private SavingsAccountTransaction(final SavingsAccount savingsAccount, final Office office, final PaymentDetail paymentDetail,
final Integer typeOf, final LocalDate transactionLocalDate, final Money amount, final boolean isReversed) {
this.savingsAccount = savingsAccount;
this.office = office;
this.typeOf = typeOf;
this.dateOf = transactionLocalDate.toDate();
this.amount = amount.getAmount();
@@ -302,15 +312,15 @@ public final class SavingsAccountTransaction extends AbstractPersistable<Long> {
numberOfDaysOfBalance = spanOfBalance.daysInPeriodInclusiveOfEndDate();
} else {
if (isDeposit()) {
// endOfDayBalance = openingBalance.plus(getAmount(currency));
// if (endOfDayBalance.isLessThanZero()) {
endOfDayBalance = Money.of(currency, this.runningBalance);
// }
// endOfDayBalance = openingBalance.plus(getAmount(currency));
// if (endOfDayBalance.isLessThanZero()) {
endOfDayBalance = Money.of(currency, this.runningBalance);
// }
} else if (isWithdrawal() || isWithdrawalFeeAndNotReversed()) {
// endOfDayBalance = openingBalance.minus(getAmount(currency));
// if (endOfDayBalance.isLessThanZero()) {
endOfDayBalance = Money.of(currency, this.runningBalance);
// }
// endOfDayBalance = openingBalance.minus(getAmount(currency));
// if (endOfDayBalance.isLessThanZero()) {
endOfDayBalance = Money.of(currency, this.runningBalance);
// }
}
}
@@ -409,16 +409,20 @@ public class TransferWritePlatformServiceJpaRepositoryImpl implements TransferWr
if (!client.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(client.getId()); }
}
private void validateGroupAwaitingTransferAcceptance(final Group group) {
if (!group.isTransferInProgress()) { throw new ClientNotAwaitingTransferApprovalException(group.getId()); }
}
/**
* private void validateGroupAwaitingTransferAcceptance(final Group group) {
* if (!group.isTransferInProgress()) { throw new
* ClientNotAwaitingTransferApprovalException(group.getId()); } }
**/
private void validateClientAwaitingTransferAcceptanceOnHold(final Client client) {
if (!client.isTransferInProgressOrOnHold()) { throw new ClientNotAwaitingTransferApprovalOrOnHoldException(client.getId()); }
}
private void validateGroupAwaitingTransferAcceptanceOnHold(final Group group) {
if (!group.isTransferInProgressOrOnHold()) { throw new ClientNotAwaitingTransferApprovalException(group.getId()); }
}
/**
* private void validateGroupAwaitingTransferAcceptanceOnHold(final Group
* group) { if (!group.isTransferInProgressOrOnHold()) { throw new
* ClientNotAwaitingTransferApprovalException(group.getId()); } }
**/
}