Skip to content

Commit

Permalink
add and test the interest on the savings accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreybakker committed Aug 12, 2017
1 parent 511fae0 commit 24b3491
Show file tree
Hide file tree
Showing 8 changed files with 293 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ public Object closeAccount(String authToken, String iBAN) throws NotAuthorizedEr
}

Account savingsAccount = account.getSavingAccount();
if (savingsAccount != null && !savingsAccount.getBalance().equals(BigDecimal.ZERO)) {
if (savingsAccount != null && savingsAccount.getBalance().compareTo(BigDecimal.ZERO) != 0) {
throw new InvalidParamValueError("Account balance needs to be cleared");
}

Account checkingAccount = account.getCheckingAccount();
if (checkingAccount != null && !checkingAccount.getBalance().equals(BigDecimal.ZERO)) {
if (checkingAccount != null && checkingAccount.getBalance().compareTo(BigDecimal.ZERO) != 0) {
throw new InvalidParamValueError("Account balance needs to be cleared");
}

Expand Down
29 changes: 29 additions & 0 deletions src/main/java/honours/ing/banq/event/InterestEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package honours.ing.banq.event;

import java.util.Calendar;
import java.util.Date;

import static java.util.Calendar.*;
import static java.util.Calendar.DAY_OF_MONTH;

/**
* @author jeffrey
* @since 12-8-17
*/
public abstract class InterestEvent implements Event {

@Override
public long nextIteration(long lastIteration) {
Calendar c = Calendar.getInstance();
c.setTime(new Date(lastIteration));

c.set(HOUR_OF_DAY, 0);
c.set(MINUTE, 0);
c.set(SECOND, 0);
c.set(MILLISECOND, 0);

c.add(DAY_OF_MONTH, 1);
return c.getTimeInMillis();
}

}
27 changes: 8 additions & 19 deletions src/main/java/honours/ing/banq/event/OverdraftInterestEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import honours.ing.banq.account.BankAccount;
import honours.ing.banq.account.BankAccountRepository;
import honours.ing.banq.account.CheckingAccount;
import honours.ing.banq.transaction.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
Expand All @@ -19,7 +20,7 @@
* @since 5-8-17
*/
@Component
public class OverdraftInterestEvent implements Event {
public class OverdraftInterestEvent extends InterestEvent {

private static final BigDecimal INTEREST = new BigDecimal("0.10");
private static final BigDecimal MONTHLY_RATE = new BigDecimal(Math.pow(INTEREST.doubleValue() + 1.0, 1.0 / 12.0))
Expand Down Expand Up @@ -59,33 +60,21 @@ public void execute(long time) {
continue;
}

account.getCheckingAccount().addInterest(account.getCheckingAccount().getLowestBalance().multiply(interest).multiply(new BigDecimal(-1.0)));
account.getCheckingAccount().resetLowestBalance();
CheckingAccount ca = account.getCheckingAccount();

ca.addInterest(ca.getLowestBalance().multiply(interest).multiply(new BigDecimal(-1.0)));
ca.resetLowestBalance();

if (firstOfMonth) {
transactionService.forceTransactionAccount(
account.getCheckingAccount(), account.getCheckingAccount().getInterest()
ca, ca.getInterest()
.multiply(new BigDecimal("-1.0"))
.setScale(2, BigDecimal.ROUND_HALF_UP), "Interest");
account.getCheckingAccount().resetInterest();
ca.resetInterest();
}

accountRepository.save(account);
}
}

@Override
public long nextIteration(long lastIteration) {
Calendar c = Calendar.getInstance();
c.setTime(new Date(lastIteration));

c.set(HOUR_OF_DAY, 0);
c.set(MINUTE, 0);
c.set(SECOND, 0);
c.set(MILLISECOND, 0);

c.add(DAY_OF_MONTH, 1);
return c.getTimeInMillis();
}

}
117 changes: 117 additions & 0 deletions src/main/java/honours/ing/banq/event/SavingsInterestEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package honours.ing.banq.event;

import honours.ing.banq.account.BankAccount;
import honours.ing.banq.account.BankAccountRepository;
import honours.ing.banq.account.SavingAccount;
import honours.ing.banq.transaction.TransactionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static java.util.Calendar.*;

/**
* @author Jeffrey Bakker
* @since 5-8-17
*/
@Component
public class SavingsInterestEvent extends InterestEvent {

private static final InterestRate[] RATES = {
new InterestRate(new BigDecimal("0.0015"), new BigDecimal("25000")),
new InterestRate(new BigDecimal("0.0015"), new BigDecimal("75000")),
new InterestRate(new BigDecimal("0.0020"), new BigDecimal("1000000")),
};

// Services
private TransactionService transactionService;

// Repositories
private BankAccountRepository accountRepository;

@Autowired
public SavingsInterestEvent(TransactionService transactionService, BankAccountRepository accountRepository) {
this.transactionService = transactionService;
this.accountRepository = accountRepository;
}

@Override
public void execute(long time) {
final Calendar c = Calendar.getInstance();
c.setTime(new Date(time));

//noinspection MagicConstant
final boolean firstOfYear = c.get(DAY_OF_MONTH) == 1 && c.get(MONTH) == 0;
final InterestRate[] rates = calcDailyRates(c, RATES);

List<BankAccount> accounts = accountRepository.findAll();

for (BankAccount account : accounts) {
SavingAccount sa = account.getSavingAccount();
if (sa == null) {
continue;
}

BigDecimal balance = sa.getLowestBalance();
BigDecimal lastMax = new BigDecimal("0.00");
BigDecimal interest = new BigDecimal("0.00");

for (InterestRate rate : rates) {
balance = balance.subtract(lastMax);
if (balance.compareTo(BigDecimal.ZERO) <= 0) {
break;
}

BigDecimal delta = rate.maxBalance.subtract(lastMax);
lastMax = rate.maxBalance;

BigDecimal rateAmt = balance.min(delta);
interest = interest.add(rateAmt.multiply(rate.interest));
}

sa.addInterest(interest);
sa.resetLowestBalance();

if (firstOfYear) {
transactionService.forceTransactionAccount(
sa, sa.getInterest()
.setScale(2, BigDecimal.ROUND_HALF_UP), "Interest");
sa.resetInterest();
}

accountRepository.save(account);
}
}

private static InterestRate[] calcDailyRates(Calendar now, InterestRate[] yearlyRates) {
InterestRate[] res = new InterestRate[yearlyRates.length];

final int daysInYear = now.getActualMaximum(DAY_OF_YEAR);

for (int i = 0; i < res.length; i++) {
res[i] = new InterestRate(
yearlyRates[i].interest.divide(new BigDecimal((double) daysInYear), 7, RoundingMode.HALF_UP),
yearlyRates[i].maxBalance
);
}

return res;
}

private static class InterestRate {

public BigDecimal interest;
public BigDecimal maxBalance;

public InterestRate(BigDecimal interest, BigDecimal maxBalance) {
this.interest = interest;
this.maxBalance = maxBalance;
}
}

}
7 changes: 7 additions & 0 deletions src/main/java/honours/ing/banq/info/bean/BalanceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
public class BalanceBean {

private Double balance;
private Double savingsAccountBalance;

public BalanceBean(BankAccount bankAccount) {
balance = bankAccount.getCheckingAccount().getBalance().doubleValue();
savingsAccountBalance = bankAccount.getSavingAccount() == null
? 0.0d : bankAccount.getSavingAccount().getBalance().doubleValue();
}

public Double getBalance() {
return balance;
}

public Double getSavingsAccountBalance() {
return savingsAccountBalance;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ public void depositIntoAccount(String iBAN, String pinCard, String pinCode, Doub
throw new InvalidParamValueError("Amount should be greater than 0.");
}

CheckingAccount account = bankAccount.getCheckingAccount();
Account account = iBAN.endsWith("S")
? bankAccount.getSavingAccount() : bankAccount.getCheckingAccount();
if (account == null) {
throw new InvalidParamValueError("The account does not exist");
}

// Update balance
account.addBalance(new BigDecimal(amount));
account.addBalance(new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP));
bankAccountRepository.save(bankAccount);

// Save transaction
Expand All @@ -87,10 +91,17 @@ public void payFromAccount(String sourceIBAN, String targetIBAN, String pinCard,
sourceBankAccount.getSavingAccount() : sourceBankAccount.getCheckingAccount();

BankAccount destBankAccount = bankAccountRepository.findOne((int) IBANUtil.getAccountNumber(targetIBAN));
Account destAccount = targetIBAN.endsWith("S") ?
destBankAccount.getSavingAccount() : destBankAccount.getCheckingAccount();
Account destAccount = null;
String destName = "";

if (destBankAccount != null) {
destAccount = targetIBAN.endsWith("S") ?
destBankAccount.getSavingAccount() : destBankAccount.getCheckingAccount();
destName = destBankAccount.getPrimaryHolder().getName() + " "
+ destBankAccount.getPrimaryHolder().getSurname();
}

BigDecimal amt = new BigDecimal(amount);
BigDecimal amt = new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP);

// Check balance
if (amount <= 0.0d) {
Expand All @@ -103,20 +114,23 @@ public void payFromAccount(String sourceIBAN, String targetIBAN, String pinCard,

// Update balance
sourceAccount.addBalance(amt.multiply(new BigDecimal(-1.0)));
destAccount.addBalance(amt);
bankAccountRepository.save(sourceBankAccount);
bankAccountRepository.save(destBankAccount);

if (destBankAccount != null) {
destAccount.addBalance(amt);
bankAccountRepository.save(destBankAccount);
}

// Save Transaction
Transaction transaction = new Transaction(
sourceIBAN, targetIBAN, destBankAccount.getPrimaryHolder().getName(),
sourceIBAN, targetIBAN, destName,
timeService.getDate().getDate(), amount, "Payment with debit card.");
transactionRepository.save(transaction);
}

@Override
public void forceTransactionAccount(Account account, BigDecimal amount, String description) {
account.addBalance(amount);
account.addBalance(amount.setScale(2, BigDecimal.ROUND_HALF_UP));
bankAccountRepository.save(account.getAccount());

String iBAN = IBANUtil.generateIBAN(account.getAccount()) + (account instanceof CheckingAccount ? "S" : "");
Expand Down Expand Up @@ -154,7 +168,7 @@ public void transferMoney(String authToken, String sourceIBAN, String targetIBAN
BankAccount destBankAccount = bankAccountRepository.findOne((int) IBANUtil.getAccountNumber(targetIBAN));
Account destAccount = destBankAccount.getCheckingAccount();

BigDecimal amt = new BigDecimal(amount);
BigDecimal amt = new BigDecimal(amount).setScale(2, BigDecimal.ROUND_HALF_UP);

// Check balance
if (amount <= 0.0d) {
Expand Down
Loading

0 comments on commit 24b3491

Please sign in to comment.