Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

abc-bank-feb2017 #120

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 95 additions & 54 deletions src/main/java/com/abc/Account.java
Original file line number Diff line number Diff line change
@@ -1,73 +1,114 @@
package com.abc;

import java.time.Duration;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

public class Account {

public static final int CHECKING = 0;
public static final int SAVINGS = 1;
public static final int MAXI_SAVINGS = 2;
public enum AccountType {
CHECKING, SAVINGS, MAXI_SAVINGS
};

private final int accountType;
public List<Transaction> transactions;
private final AccountType accountType;
public List<Transaction> transactions;
private LocalDate acctOpenDate = null;
private LocalDate withdrawalDate = null;

public Account(int accountType) {
this.accountType = accountType;
this.transactions = new ArrayList<Transaction>();
}
public LocalDate getAcctOpenDate() {
return acctOpenDate;
}

public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(amount));
}
}
public LocalDate getWithdrawalDate() {
return withdrawalDate;
}

public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(-amount));
}
}
public void setWithdrawalDate(LocalDate withdrawalDate) {
this.withdrawalDate = withdrawalDate;
}

// minusDays(36) was added to show interest rate calculations
// In production, acctOpenDate date will be set to LocalDate.now()
public Account(AccountType accountType) {
this.accountType = accountType;
this.acctOpenDate = LocalDate.now().minusDays(36);
this.transactions = new ArrayList<Transaction>();
}

public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(amount));
}
}

public double interestEarned() {
// minusDays(12) was added to show interest rate calculations
// In production, withdrawalDate will be set to LocalDate.now()
public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(-amount));
setWithdrawalDate(LocalDate.now().minusDays(12));
}
}

/*
* @param numOfDays - number of days for which account was held
*
* @param daysSinceLastWithdrawal - days since last withdrawal for
* maxi-savings
*/
public double interestEarned() {
long numOfDays = Duration.between(getAcctOpenDate().atTime(0, 0), LocalDate.now().atTime(0, 0)).toDays();
if (getWithdrawalDate() == null)
setWithdrawalDate(getAcctOpenDate());
long daysSinceLastWithdrawal = Duration.between(getWithdrawalDate().atTime(0, 0), LocalDate.now().atTime(0, 0))
.toDays();
double amount = sumTransactions();
switch(accountType){
case SAVINGS:
if (amount <= 1000)
return amount * 0.001;
else
return 1 + (amount-1000) * 0.002;
// case SUPER_SAVINGS:
// if (amount <= 4000)
// return 20;
case MAXI_SAVINGS:
if (amount <= 1000)
return amount * 0.02;
if (amount <= 2000)
return 20 + (amount-1000) * 0.05;
return 70 + (amount-2000) * 0.1;
default:
return amount * 0.001;
}
switch (accountType) {
case CHECKING:
return amount * 0.001 * numOfDays / 365;
case SAVINGS:
if (amount > 1000)
return (1000 * .001 + (amount - 1000) * .002) * numOfDays / 365;
else
return (amount * .001 * numOfDays / 365);
case MAXI_SAVINGS:
if (daysSinceLastWithdrawal > 10)
return amount * 0.05 * numOfDays / 365;
else
return amount * 0.001 * numOfDays / 365;
default:
return amount * 0.001;
}
}

public double sumTransactions() {
return checkIfTransactionsExist(true);
}
public double transfer(Account to, double amount) {

private double checkIfTransactionsExist(boolean checkAll) {
double amount = 0.0;
for (Transaction t: transactions)
amount += t.amount;
return amount;
}
if (sumTransactions() >= amount) {
this.withdraw(amount);
to.deposit(amount);
}
return sumTransactions();
}

public int getAccountType() {
return accountType;
}
public double sumTransactions() {
return checkIfTransactionsExist(true);
}

private double checkIfTransactionsExist(boolean checkAll) {
double amount = 0.0;
for (Transaction t : transactions)
amount += t.amount;
return amount;
}

public AccountType getAccountType() {
return accountType;
}

}
10 changes: 7 additions & 3 deletions src/main/java/com/abc/Bank.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ public Bank() {
customers = new ArrayList<Customer>();
}

public void addCustomer(Customer customer) {
customers.add(customer);
}
public void addCustomer(Customer customer) {
// prevent multi-threaded bank clients from adding duplicate customer IDs
synchronized (customers) {
if (!customers.contains(customer))
customers.add(customer);
}
}

public String customerSummary() {
String summary = "Customer Summary";
Expand Down
27 changes: 24 additions & 3 deletions src/main/java/com/abc/Customer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ public Customer(String name) {
public String getName() {
return name;
}

// assuming customer name is the unique identifier
public boolean equals(Customer c) {
return (this.name.equalsIgnoreCase(c.name)) ? true : false;
}

public int hashCode() {
return (this.name.length());
}

public Customer openAccount(Account account) {
accounts.add(account);
Expand Down Expand Up @@ -46,18 +55,30 @@ public String getStatement() {
return statement;
}

public double transfer(Account from, Account to, double amount) {
synchronized (this) {
return from.transfer(to, amount);
}
}

public void withdrwa(Account from, double amount) {
synchronized (this) {
from.withdraw(amount);
}
}

private String statementForAccount(Account a) {
String s = "";

//Translate to pretty account type
switch(a.getAccountType()){
case Account.CHECKING:
case CHECKING:
s += "Checking Account\n";
break;
case Account.SAVINGS:
case SAVINGS:
s += "Savings Account\n";
break;
case Account.MAXI_SAVINGS:
case MAXI_SAVINGS:
s += "Maxi Savings Account\n";
break;
}
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/abc/Transaction.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.abc;

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

public class Transaction {
Expand Down
33 changes: 17 additions & 16 deletions src/test/java/com/abc/BankTest.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package com.abc;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class BankTest {
private static final double DOUBLE_DELTA = 1e-15;
private static final double DOUBLE_DELTA = 0.05;

@Test
public void customerSummary() {
Bank bank = new Bank();
Customer john = new Customer("John");
john.openAccount(new Account(Account.CHECKING));
john.openAccount(new Account(Account.AccountType.CHECKING));
bank.addCustomer(john);

assertEquals("Customer Summary\n - John (1 account)", bank.customerSummary());
Expand All @@ -20,35 +20,36 @@ public void customerSummary() {
@Test
public void checkingAccount() {
Bank bank = new Bank();
Account checkingAccount = new Account(Account.CHECKING);
Customer bill = new Customer("Bill").openAccount(checkingAccount);
Account checking = new Account(Account.AccountType.CHECKING);
Customer bill = new Customer("Bill").openAccount(checking);
bank.addCustomer(bill);

checkingAccount.deposit(100.0);
checking.deposit(100.0);

assertEquals(0.1, bank.totalInterestPaid(), DOUBLE_DELTA);
assertEquals(0.0, checking.interestEarned(), DOUBLE_DELTA);
}

@Test
public void savings_account() {
Bank bank = new Bank();
Account checkingAccount = new Account(Account.SAVINGS);
bank.addCustomer(new Customer("Bill").openAccount(checkingAccount));
Account savings = new Account(Account.AccountType.SAVINGS);
bank.addCustomer(new Customer("Bill").openAccount(savings));

checkingAccount.deposit(1500.0);
savings.deposit(1500.0);

assertEquals(2.0, bank.totalInterestPaid(), DOUBLE_DELTA);
assertEquals(0.19, savings.interestEarned(), DOUBLE_DELTA);
}

@Test
public void maxi_savings_account() {
Bank bank = new Bank();
Account checkingAccount = new Account(Account.MAXI_SAVINGS);
bank.addCustomer(new Customer("Bill").openAccount(checkingAccount));
Account maxi_savings = new Account(Account.AccountType.MAXI_SAVINGS);
bank.addCustomer(new Customer("Bill").openAccount(maxi_savings));

checkingAccount.deposit(3000.0);
maxi_savings.deposit(3000.0);
maxi_savings.withdraw(100.0);

assertEquals(170.0, bank.totalInterestPaid(), DOUBLE_DELTA);
assertEquals(14.30, maxi_savings.interestEarned(), DOUBLE_DELTA);
}

}
27 changes: 20 additions & 7 deletions src/test/java/com/abc/CustomerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ public class CustomerTest {
@Test //Test customer statement generation
public void testApp(){

Account checkingAccount = new Account(Account.CHECKING);
Account savingsAccount = new Account(Account.SAVINGS);
Account checkingAccount = new Account(Account.AccountType.CHECKING);
Account savingsAccount = new Account(Account.AccountType.SAVINGS);

Customer henry = new Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount);

Expand All @@ -35,23 +35,36 @@ public void testApp(){

@Test
public void testOneAccount(){
Customer oscar = new Customer("Oscar").openAccount(new Account(Account.SAVINGS));
Customer oscar = new Customer("Oscar").openAccount(new Account(Account.AccountType.SAVINGS));
assertEquals(1, oscar.getNumberOfAccounts());
}

@Test
public void testTwoAccount(){
Customer oscar = new Customer("Oscar")
.openAccount(new Account(Account.SAVINGS));
oscar.openAccount(new Account(Account.CHECKING));
.openAccount(new Account(Account.AccountType.SAVINGS));
oscar.openAccount(new Account(Account.AccountType.CHECKING));
assertEquals(2, oscar.getNumberOfAccounts());
}

@Test
public void testTransfer(){
Customer oscar = new Customer("Oscar");
Account savings = new Account(Account.AccountType.SAVINGS);
Account checking = new Account(Account.AccountType.CHECKING);
oscar.openAccount(savings);
oscar.openAccount(checking);
checking.deposit(100.0);
savings.deposit(4000.0);
savings.withdraw(200.0);
assertEquals(3300.0, oscar.transfer(savings, checking, 500.0), 0.0);
}

@Ignore
public void testThreeAcounts() {
Customer oscar = new Customer("Oscar")
.openAccount(new Account(Account.SAVINGS));
oscar.openAccount(new Account(Account.CHECKING));
.openAccount(new Account(Account.AccountType.SAVINGS));
oscar.openAccount(new Account(Account.AccountType.CHECKING));
assertEquals(3, oscar.getNumberOfAccounts());
}
}