Skip to content
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
68 changes: 45 additions & 23 deletions src/main/scala/com/abc/Account.scala
Original file line number Diff line number Diff line change
@@ -1,44 +1,66 @@
package com.abc

import scala.collection.mutable.ListBuffer
import java.util.Calendar
import java.util.Calendar._

object Account {
final val CHECKING: Int = 0
final val SAVINGS: Int = 1
final val MAXI_SAVINGS: Int = 2
}
abstract class Account() {
val transactions: ListBuffer[Transaction] = ListBuffer()
private var total = 0.0

class Account(val accountType: Int, var transactions: ListBuffer[Transaction] = ListBuffer()) {
def description: String
def interestEarned: Double

def deposit(amount: Double) {
if (amount <= 0)
throw new IllegalArgumentException("amount must be greater than zero")
else
transactions += Transaction(amount)

transactions += Transaction(amount)
total += amount
}

def withdraw(amount: Double) {
if (amount <= 0)
throw new IllegalArgumentException("amount must be greater than zero")
else
transactions += Transaction(-amount)

transactions += Transaction(-amount)
total -= amount
}

def sumTransactions(checkAllTransactions: Boolean = true): Double = total

}

class CheckingAccount extends Account {
def description = "Checking Account"
def interestEarned: Double = {
val amount: Double = sumTransactions()
accountType match {
case Account.SAVINGS =>
if (amount <= 1000) amount * 0.001
else 1 + (amount - 1000) * 0.002
case Account.MAXI_SAVINGS =>
if (amount <= 1000) return amount * 0.02
if (amount <= 2000) return 20 + (amount - 1000) * 0.05
70 + (amount - 2000) * 0.1
case _ =>
amount * 0.001
}
amount * 0.001
}
}

def sumTransactions(checkAllTransactions: Boolean = true): Double = transactions.map(_.amount).sum
class SavingAccount extends Account {
def description = "Savings Account"
def interestEarned: Double = {
val amount: Double = sumTransactions()

}
if (amount <= 1000) amount * 0.001
else 1 + (amount - 1000) * 0.002
}
}

class MaxiSavingAccount extends Account {
def description = "Maxi Savings Account"
def interestEarned: Double = {
val amount: Double = sumTransactions()

val calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -10)
val tenDaysAgo = calendar.getTime

if (!transactions.exists(t => t.date.after(tenDaysAgo) && t.amount < 0))
amount * 0.05
else
amount * 0.001
}
}
36 changes: 21 additions & 15 deletions src/main/scala/com/abc/Customer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.abc

import scala.collection.mutable.ListBuffer

class Customer(val name: String, var accounts: ListBuffer[Account] = ListBuffer()) {
class Customer(val name: String, val accounts: ListBuffer[Account] = ListBuffer()) {

def openAccount(account: Account): Customer = {
accounts += account
Expand All @@ -13,32 +13,38 @@ class Customer(val name: String, var accounts: ListBuffer[Account] = ListBuffer(

def totalInterestEarned: Double = accounts.map(_.interestEarned).sum

/**
* This method gets a statement
*/
def getStatement: String = {
//JIRA-123 Change by Joe Bloggs 29/7/1988 start
var statement: String = null //reset statement to null here
//JIRA-123 Change by Joe Bloggs 29/7/1988 end


val totalAcrossAllAccounts = accounts.map(_.sumTransactions()).sum

statement = f"Statement for $name\n" +
accounts.map(statementForAccount).mkString("\n", "\n\n", "\n") +
s"\nTotal In All Accounts ${toDollars(totalAcrossAllAccounts)}"
statement
}

private def statementForAccount(a: Account): String = {
val accountType = a.accountType match {
case Account.CHECKING =>
"Checking Account\n"
case Account.SAVINGS =>
"Savings Account\n"
case Account.MAXI_SAVINGS =>
"Maxi Savings Account\n"
}
val transactionSummary = a.transactions.map(t => withdrawalOrDepositText(t) + " " + toDollars(t.amount.abs))
def transfer(amount: Double, target: Account, destination: Account) {
if (amount <= 0)
throw new IllegalArgumentException("amount must be greater than zero")
if (target == destination)
throw new IllegalArgumentException("target and destination must be different")

target.withdraw(amount)
destination.deposit(amount)
}

private def statementForAccount(account: Account): String = {
val accountType = account.description + "\n"

val transactionSummary = account.transactions.map(t => withdrawalOrDepositText(t) + " " + toDollars(t.amount.abs))
.mkString(" ", "\n ", "\n")
val totalSummary = s"Total ${toDollars(a.transactions.map(_.amount).sum)}"

val totalSummary = s"Total ${toDollars(account.transactions.map(_.amount).sum)}"

accountType + transactionSummary + totalSummary
}

Expand Down
20 changes: 0 additions & 20 deletions src/main/scala/com/abc/DateProvider.scala

This file was deleted.

5 changes: 4 additions & 1 deletion src/main/scala/com/abc/Transaction.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.abc

import java.util.Calendar

case class Transaction(var amount: Double) {
val transactionDate = DateProvider.getInstance.now
val date = Calendar.getInstance.getTime
}


30 changes: 20 additions & 10 deletions src/test/scala/com/abc/BankTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ class BankTest extends FlatSpec with Matchers {

"Bank" should "customer summary" in {
val bank: Bank = new Bank
var john: Customer = new Customer("John").openAccount(new Account(Account.CHECKING))
var john: Customer = new Customer("John").openAccount(new CheckingAccount)
bank.addCustomer(john)
bank.customerSummary should be("Customer Summary\n - John (1 account)")
}

it should "checking account" in {
val bank: Bank = new Bank
val checkingAccount: Account = new Account(Account.CHECKING)
val checkingAccount: Account = new CheckingAccount
val bill: Customer = new Customer("Bill").openAccount(checkingAccount)
bank.addCustomer(bill)
checkingAccount.deposit(100.0)
Expand All @@ -22,18 +22,28 @@ class BankTest extends FlatSpec with Matchers {

it should "savings account" in {
val bank: Bank = new Bank
val checkingAccount: Account = new Account(Account.SAVINGS)
bank.addCustomer(new Customer("Bill").openAccount(checkingAccount))
checkingAccount.deposit(1500.0)
val savingAccount: Account = new SavingAccount
bank.addCustomer(new Customer("Bill").openAccount(savingAccount))
savingAccount.deposit(1500.0)
bank.totalInterestPaid should be(2.0)
}

it should "maxi savings account" in {
it should "maxi savings account without withdrawal in the last 10 days" in {
val bank: Bank = new Bank
val checkingAccount: Account = new Account(Account.MAXI_SAVINGS)
bank.addCustomer(new Customer("Bill").openAccount(checkingAccount))
checkingAccount.deposit(3000.0)
bank.totalInterestPaid should be(170.0)
val maxiAccount: Account = new MaxiSavingAccount
bank.addCustomer(new Customer("Bill").openAccount(maxiAccount))
maxiAccount.deposit(3000.0)
bank.totalInterestPaid should be(150.0)
}

it should "maxi savings account with recent withdrawal" in {
val bank: Bank = new Bank
val maxiAccount: Account = new MaxiSavingAccount
bank.addCustomer(new Customer("Bill").openAccount(maxiAccount))
maxiAccount.deposit(3000.0)
maxiAccount.withdraw(100.0)

bank.totalInterestPaid should be(2.9)
}

}
25 changes: 13 additions & 12 deletions src/test/scala/com/abc/CustomerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,33 @@ import org.scalatest.{Matchers, FlatSpec}

class CustomerTest extends FlatSpec with Matchers {
"Customer" should "statement" in {
val checkingAccount: Account = new Account(Account.CHECKING)
val savingsAccount: Account = new Account(Account.SAVINGS)
val checkingAccount: Account = new CheckingAccount
val savingsAccount: Account = new SavingAccount
val henry: Customer = new Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount)
checkingAccount.deposit(100.0)
savingsAccount.deposit(4000.0)
savingsAccount.withdraw(200.0)
henry.transfer(300.0, savingsAccount, checkingAccount)

// henry.getStatement should be("Statement for Henry\n" +
// "\nChecking Account\n deposit $100.00\nTotal $100.00\n" +
// "\nSavings Account\n deposit $4000.00\n withdrawal $200.00\nTotal $3800.00\n" +
// "\nTotal In All Accounts $3900.00")
henry.getStatement should be("Statement for Henry\n" +
"\nChecking Account\n deposit $100.00\nTotal $100.00\n" +
"\nSavings Account\n deposit $4000.00\n withdrawal $200.00\nTotal $3800.00\n" +
"\nChecking Account\n deposit $100.00\n deposit $300.00\nTotal $400.00\n" +
"\nSavings Account\n deposit $4000.00\n withdrawal $200.00\n withdrawal $300.00\nTotal $3500.00\n" +
"\nTotal In All Accounts $3900.00")
}

it should "testOneAccount" in {
val oscar: Customer = new Customer("Oscar").openAccount(new Account(Account.SAVINGS))
val oscar: Customer = new Customer("Oscar").openAccount(new SavingAccount)
oscar.numberOfAccounts should be(1)
}

it should "testTwoAccount" in {
val oscar: Customer = new Customer("Oscar").openAccount(new Account(Account.SAVINGS))
oscar.openAccount(new Account(Account.CHECKING))
val oscar: Customer = new Customer("Oscar").openAccount(new SavingAccount)
oscar.openAccount(new CheckingAccount)
oscar.numberOfAccounts should be(2)
}

ignore should "testThreeAcounts" in {
val oscar: Customer = new Customer("Oscar").openAccount(new Account(Account.SAVINGS))
oscar.openAccount(new Account(Account.CHECKING))
oscar.numberOfAccounts should be(3)
}
}