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

refactoring + one feature #335

Open
wants to merge 1 commit 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
14 changes: 13 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
119 changes: 71 additions & 48 deletions src/main/java/com/abc/Account.java
Original file line number Diff line number Diff line change
@@ -1,73 +1,96 @@
package com.abc;

import com.util.BigDecimalProvider;
import com.util.CurrencyStringFormatter;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
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 abstract class Account {
protected List<Transaction> transactions = new ArrayList<>();

abstract protected String getAccountTypeLabel();

abstract public BigDecimal getInterestEarned();

private final int accountType;
public List<Transaction> transactions;

public Account(int accountType) {
this.accountType = accountType;
this.transactions = new ArrayList<Transaction>();
protected Transaction deposit(BigDecimal amount) {
Account.validateAmount(amount);
return commitTransaction(BigDecimalProvider.format(amount));
}

protected Transaction withdraw(BigDecimal amount) {
Account.validateAmount(amount);
return commitTransaction(BigDecimalProvider.format(amount).negate());
}

public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(amount));
protected static void validateAmount(BigDecimal amount) {
if (amount.compareTo(java.math.BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Provided amount must be greater than zero");
}
}

public void withdraw(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
} else {
transactions.add(new Transaction(-amount));
protected Transaction commitTransaction(BigDecimal amount) {
Transaction transaction = new Transaction(amount);
transactions.add(transaction);
return transaction;
}

BigDecimal calculateInterest(BigDecimal amount, BigDecimal rate) {
return amount.multiply(rate).setScale(2, RoundingMode.HALF_EVEN);
}
}

public double interestEarned() {
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;
public BigDecimal sumTransactions() {
BigDecimal amount = BigDecimalProvider.getZero();

if (transactions.isEmpty()) {
return amount;
}

for (Transaction transaction : transactions)
amount = amount.add(transaction.getAmount());
return amount;
}

public double sumTransactions() {
return checkIfTransactionsExist(true);
public List<Transaction> getTransactions() {
return new ArrayList<>(transactions);
}

private double checkIfTransactionsExist(boolean checkAll) {
double amount = 0.0;
for (Transaction t: transactions)
amount += t.amount;
return amount;
public String getStatement() {
StringBuilder statement = new StringBuilder();
String accountTypeLabel = getAccountTypeLabel();
statement.append(accountTypeLabel);
statement.append("\n");

BigDecimal total = BigDecimalProvider.getZero();
for (Transaction transaction : this.getTransactions()) {
statement.append(" ");
statement.append(transaction.getAmount().compareTo(BigDecimal.ZERO) < 0 ? "withdrawal" : "deposit");
statement.append(" ");
statement.append(CurrencyStringFormatter.format(transaction.getAmount()));
statement.append("\n");
total = total.add(transaction.getAmount());
}
statement.append("Total ");
statement.append(CurrencyStringFormatter.format(total));

return statement.toString();
}

public int getAccountType() {
return accountType;
protected void verifyTransaction(Transaction transaction) {
if (!(transactions.contains(transaction))) {
throw new IllegalStateException("This account does not contain given transaction!");
}

}

protected void rollbackTransaction(Transaction transaction) {
verifyTransaction(transaction);
transactions.remove(transaction);
}


}
20 changes: 20 additions & 0 deletions src/main/java/com/abc/AccountChecking.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.abc;

import com.util.BigDecimalProvider;

import java.math.BigDecimal;

public class AccountChecking extends Account {
private final BigDecimal CHECKING_RATE = BigDecimalProvider.getInterestRateFormatted(0.001);

@Override
public BigDecimal getInterestEarned() {
BigDecimal amount = sumTransactions();
return calculateInterest(amount, CHECKING_RATE);
}

@Override
protected String getAccountTypeLabel() {
return "Checking Account";
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/abc/AccountMaxiSavings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.abc;

import com.util.BigDecimalProvider;

import java.math.BigDecimal;


public class AccountMaxiSavings extends Account {

private final BigDecimal MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT = BigDecimalProvider.format(1000);
private final BigDecimal MAXI_SAVINGS_MID_THRESHOLD_AMOUNT = BigDecimalProvider.format(2000);
private final BigDecimal MAXI_SAVINGS_RATE_LOW = BigDecimalProvider.getInterestRateFormatted(0.02);
private final BigDecimal MAXI_SAVINGS_RATE_MID = BigDecimalProvider.getInterestRateFormatted(0.05);
private final BigDecimal MAXI_SAVINGS_RATE_HIGH = BigDecimalProvider.getInterestRateFormatted(0.1);


@Override
public BigDecimal getInterestEarned() {
BigDecimal amount = sumTransactions();
BigDecimal belowThreshold1;
BigDecimal belowThreshold2;
BigDecimal aboveThreshold;

if (amount.compareTo(MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT) <= 0) {
return calculateInterest(amount, MAXI_SAVINGS_RATE_LOW);
}

if (amount.compareTo(MAXI_SAVINGS_MID_THRESHOLD_AMOUNT) <= 0) {
belowThreshold1 = calculateInterest(MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT, MAXI_SAVINGS_RATE_LOW);
aboveThreshold = calculateInterest(amount.subtract(MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT), MAXI_SAVINGS_RATE_MID);
return belowThreshold1.add(aboveThreshold);
}

belowThreshold1 = calculateInterest(MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT, MAXI_SAVINGS_RATE_LOW);
belowThreshold2 = calculateInterest(
MAXI_SAVINGS_MID_THRESHOLD_AMOUNT.subtract(MAXI_SAVINGS_LOW_THRESHOLD_AMOUNT),
MAXI_SAVINGS_RATE_MID);
aboveThreshold = calculateInterest(
amount.subtract(MAXI_SAVINGS_MID_THRESHOLD_AMOUNT),
MAXI_SAVINGS_RATE_HIGH);
return belowThreshold1.add(belowThreshold2).add(aboveThreshold);

}

@Override
protected String getAccountTypeLabel() {
return "Maxi Savings Account";
}
}
33 changes: 33 additions & 0 deletions src/main/java/com/abc/AccountSavings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.abc;

import com.util.BigDecimalProvider;

import java.math.BigDecimal;


public class AccountSavings extends Account {

private final BigDecimal SAVINGS_THRESHOLD_AMOUNT = BigDecimalProvider.format(1000);
private final BigDecimal SAVINGS_RATE_LOW = BigDecimalProvider.getInterestRateFormatted(0.001);
private final BigDecimal SAVINGS_RATE_HIGH = BigDecimalProvider.getInterestRateFormatted(0.002);

@Override
public BigDecimal getInterestEarned() {
BigDecimal amount = sumTransactions();
BigDecimal belowThreshold1;
BigDecimal aboveThreshold;

if (amount.compareTo(SAVINGS_THRESHOLD_AMOUNT) <= 0) {
return calculateInterest(amount, SAVINGS_RATE_LOW);
}

belowThreshold1 = calculateInterest(SAVINGS_THRESHOLD_AMOUNT, SAVINGS_RATE_LOW);
aboveThreshold = calculateInterest(amount.subtract(SAVINGS_THRESHOLD_AMOUNT), SAVINGS_RATE_HIGH);
return belowThreshold1.add(aboveThreshold);
}

@Override
protected String getAccountTypeLabel() {
return "Savings Account";
}
}
49 changes: 24 additions & 25 deletions src/main/java/com/abc/Bank.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
package com.abc;

import com.util.BigDecimalProvider;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class Bank {
private List<Customer> customers;
private final List<Customer> customers;

public Bank() {
customers = new ArrayList<Customer>();
customers = new ArrayList<>();
}

public void addCustomer(Customer customer) {
customers.add(customer);
}

public String customerSummary() {
String summary = "Customer Summary";
for (Customer c : customers)
summary += "\n - " + c.getName() + " (" + format(c.getNumberOfAccounts(), "account") + ")";
return summary;
}

//Make sure correct plural of word is created based on the number passed in:
//If number passed in is 1 just return the word otherwise add an 's' at the end
private String format(int number, String word) {
return number + " " + (number == 1 ? word : word + "s");
public String getAllCustomersSummary() {
StringBuilder summary = new StringBuilder("Customer Summary");
for (Customer customer : customers) {
summary.append("\n - ");
summary.append(customer.getName());
summary.append(" (");
int numberOfAccounts = customer.getNumberOfAccounts();
summary.append(numberOfAccounts);
summary.append(" ");
summary.append(numberOfAccounts == 1 ? "account" : "accounts");
summary.append(")");
}
return summary.toString();
}

public double totalInterestPaid() {
double total = 0;
for(Customer c: customers)
total += c.totalInterestEarned();
public BigDecimal getTotalInterestsPaid() {
BigDecimal total = BigDecimalProvider.getZero();
for (Customer customer : customers)
total = total.add(customer.totalInterestEarned());
return total;
}

public String getFirstCustomer() {
try {
customers = null;
return customers.get(0).getName();
} catch (Exception e){
e.printStackTrace();
return "Error";
}
public boolean hasCustomer(Customer customer) {
return customers.contains(customer);
}
}
Loading