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

Completed Take-Home Code Test #337

Open
wants to merge 2 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
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>

<dependencies>
Expand Down
183 changes: 139 additions & 44 deletions src/main/java/com/abc/Account.java
Original file line number Diff line number Diff line change
@@ -1,73 +1,168 @@
package com.abc;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class Account {
/**
* Represents a bank account with various types (CHECKING, SAVINGS,
* MAXI_SAVINGS).
*/
public abstract class Account {

public static final int CHECKING = 0;
public static final int SAVINGS = 1;
public static final int MAXI_SAVINGS = 2;
/**
* Enumeration representing the type of the account (CHECKING, SAVINGS,
* MAXI_SAVINGS).
*/
public enum AccountType {
CHECKING,
SAVINGS,
MAXI_SAVINGS
}

private final int accountType;
private final AccountType accountType;
private LocalDate openedDate;
private BigDecimal balance;
private LocalDate lastWithdrawalDate;
public List<Transaction> transactions;

public Account(int accountType) {
// Interest rates
public static final BigDecimal CHECKING_INTEREST_RATE = new BigDecimal("0.001");
public static final BigDecimal SAVINGS_LOW_INTEREST_RATE = new BigDecimal("0.001");
public static final BigDecimal SAVINGS_HIGH_INTEREST_RATE = new BigDecimal("0.002");
public static final BigDecimal MAXI_SAVINGS_LOW_INTEREST_RATE = new BigDecimal("0.001");
public static final BigDecimal MAXI_SAVINGS_HIGH_INTEREST_RATE = new BigDecimal("0.05");

// Interest rate thresholds
public static final BigDecimal SAVINGS_THRESHOLD = new BigDecimal("1000.00");
public static final BigDecimal MAXI_SAVINGS_FIRST_THRESHOLD = new BigDecimal("1000.00");
public static final BigDecimal MAXI_SAVINGS_SECOND_THRESHOLD = new BigDecimal("2000.00");

// Number of days for Maxi-Savings interest rate calculation
public static final int MAXI_SAVINGS_WITHDRAWAL_DAYS = 10;

/**
* Constructs an Account with the specified account type.
*
* @param accountType The type of the account (CHECKING, SAVINGS, MAXI_SAVINGS).
*/
public Account(AccountType accountType) {
this.accountType = accountType;
this.openedDate = LocalDate.now(); // Set the opened date to the current date
this.balance = BigDecimal.ZERO;
this.lastWithdrawalDate = null;
this.transactions = new ArrayList<Transaction>();
}

public void deposit(double amount) {
if (amount <= 0) {
throw new IllegalArgumentException("amount must be greater than zero");
/**
* Deposits the specified amount into the account.
*
* @param amount The amount to deposit. Must be greater than zero.
* @throws IllegalArgumentException if the amount is not greater than zero.
*/
public void deposit(BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Invalid deposit amount");
} else {
transactions.add(new Transaction(amount));
balance = balance.add(amount);
}
}

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

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;
/**
* Withdraws the specified amount from the account.
*
* @param amount The amount to withdraw. Must be greater than zero.
* @throws IllegalArgumentException if the amount is not greater than zero or
* exceeds the balance.
*/
public void withdraw(BigDecimal amount) {
if (amount.compareTo(BigDecimal.ZERO) <= 0 || amount.compareTo(balance) > 0) {
throw new IllegalArgumentException("Invalid withdrawal amount");
} else {
transactions.add(new Transaction(amount.negate()));
balance = balance.subtract(amount);
lastWithdrawalDate = LocalDate.now();
}
}

public double sumTransactions() {
return checkIfTransactionsExist(true);
/**
* Calculates the interest earned on the account based on its type and balance.
*
* @param balance The current balance of the account.
* @return The interest earned.
*/
public abstract BigDecimal getInterestRate(BigDecimal balance);

/**
* Calculates the compounded interest earned over a specified number of days.
*
* @param numberOfDays The number of days to calculate interest for.
* @return The compounded interest earned.
*/
public BigDecimal compoundedInterestEarned(int numberOfDays) {
LocalDate date = LocalDate.now();
int daysInCurrentYear = date.lengthOfYear();

BigDecimal annualInterestRate = getInterestRate(balance);
int compoundingFrequency = daysInCurrentYear;
BigDecimal one = new BigDecimal("1.00");

BigDecimal dailyInterestRate = annualInterestRate.divide(new BigDecimal(compoundingFrequency), 10,
RoundingMode.HALF_UP);
BigDecimal accruedInterest = balance
.multiply(one.add(dailyInterestRate).pow(numberOfDays))
.subtract(balance);

return (accruedInterest.setScale(2, RoundingMode.HALF_UP));
}

private double checkIfTransactionsExist(boolean checkAll) {
double amount = 0.0;
for (Transaction t: transactions)
amount += t.amount;
return amount;
/**
* Calculates the sum of all transactions associated with the account.
*
* @return The sum of all transactions.
*/
public BigDecimal sumTransactions() {
return transactions.stream()
.map(Transaction::getAmount)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}

public int getAccountType() {
/**
* Gets the account type.
*
* @return The account type (CHECKING, SAVINGS, MAXI_SAVINGS).
*/
public AccountType getAccountType() {
return accountType;
}

/**
* Gets the current balance of the account.
*
* @return The account balance.
*/
public BigDecimal getBalance() {
return balance;
}

/**
* Gets the date when the account was opened.
*
* @return The opened date.
*/
public LocalDate getOpenedDate() {
return openedDate;
}

/**
* Gets the date of the last withdrawal from the account.
*
* @return The last withdrawal date, or null if no withdrawals have been made.
*/
public LocalDate getLastWithdrawalDate() {
return lastWithdrawalDate;
}
}
77 changes: 62 additions & 15 deletions src/main/java/com/abc/Bank.java
Original file line number Diff line number Diff line change
@@ -1,46 +1,93 @@
package com.abc;

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

/**
* Represents a bank with a list of customers.
*/
public class Bank {

/**
* The list of customers associated with the bank.
*/
private List<Customer> customers;

/**
* Constructs a new Bank instance with an empty list of customers.
*/
public Bank() {
customers = new ArrayList<Customer>();
customers = new ArrayList<>();
}

/**
* Adds a customer to the bank's list of customers.
*
* @param customer The customer to add.
*/
public void addCustomer(Customer customer) {
customers.add(customer);
}

/**
* Generates a summary of the bank's customers and their accounts.
*
* @return A summary of customers and their accounts.
*/
public String customerSummary() {
String summary = "Customer Summary";
StringBuilder summary = new StringBuilder("Customer Summary");
for (Customer c : customers)
summary += "\n - " + c.getName() + " (" + format(c.getNumberOfAccounts(), "account") + ")";
return summary;
summary.append("\n - ").append(c.getName()).append(" (")
.append(format(c.getNumberOfAccounts(), "account")).append(")");
return summary.toString();
}

//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
/**
* Formats a number and word into a grammatically correct phrase.
*
* @param number The number to format.
* @param word The word to format.
* @return A formatted string.
*/
private String format(int number, String word) {
return number + " " + (number == 1 ? word : word + "s");
}

public double totalInterestPaid() {
double total = 0;
for(Customer c: customers)
total += c.totalInterestEarned();
/**
* Calculates the total interest paid by all customers.
*
* @param noOfDays The number of days for interest calculation.
* @return The total interest paid.
*/
public BigDecimal totalInterestPaid(int noOfDays) {
BigDecimal total = BigDecimal.ZERO;
for (Customer c : customers) {
total = total.add(c.totalInterestEarned(noOfDays));
}
return total;
}

/**
* Retrieves the name of the first customer in the bank's customer list.
*
* @return The name of the first customer or "No customers found." if the list
* is empty.
*/
public String getFirstCustomer() {
try {
customers = null;
if (customers.isEmpty()) {
return "No customers found.";
} else {
return customers.get(0).getName();
} catch (Exception e){
e.printStackTrace();
return "Error";
}
}

/**
* Gets the number of customers in the bank.
*
* @return The number of customers.
*/
public int getNumberOfCustomers() {
return customers.size();
}
}
27 changes: 27 additions & 0 deletions src/main/java/com/abc/CheckingAccount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.abc;

import java.math.BigDecimal;

/**
* Represents a checking account.
*/
public class CheckingAccount extends Account {

/**
* Constructs a new CheckingAccount instance.
*/
public CheckingAccount() {
super(AccountType.CHECKING);
}

/**
* Gets the interest rate for a checking account.
*
* @param balance The balance of the account (not used for checking accounts).
* @return The interest rate for a checking account.
*/
@Override
public BigDecimal getInterestRate(BigDecimal balance) {
return CHECKING_INTEREST_RATE;
}
}
Loading