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

Joseph Liang's change #15

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
246 changes: 246 additions & 0 deletions .cache-main

Large diffs are not rendered by default.

245 changes: 245 additions & 0 deletions .cache-tests

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<classpath>
<classpathentry kind="src" path="src\main\scala"/>
<classpathentry kind="src" path="src\test\scala"/>
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"/>
<classpathentry kind="lib" path="C:\Users\Joseph\.ivy2\cache\org.scalatest\scalatest_2.11\jars\scalatest_2.11-2.1.6.jar"/>
<classpathentry kind="lib" path="C:\Users\Joseph\.ivy2\cache\org.scala-lang.modules\scala-parser-combinators_2.11\bundles\scala-parser-combinators_2.11-1.0.1.jar"/>
<classpathentry kind="lib" path="C:\Users\Joseph\.ivy2\cache\org.scala-lang.modules\scala-xml_2.11\bundles\scala-xml_2.11-1.0.1.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ project/plugins/project/

# IntelliJ
.idea
*.iml
*.iml
/bin/
13 changes: 13 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<projectDescription>
<name>abc-bank-scala</name>
<buildSpec>
<buildCommand>
<name>org.scala-ide.sdt.core.scalabuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.scala-ide.sdt.core.scalanature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
<linkedResources> </linkedResources>
</projectDescription>
3 changes: 3 additions & 0 deletions .settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#Generated by sbteclipse
#Mon Jul 25 22:38:58 EDT 2016
encoding/<project>=UTF-8
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.3.5")
9 changes: 9 additions & 0 deletions src/main/scala/com/abc/AccountType.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.abc


object AccountType {
sealed trait AccountType
case object CHECKING extends AccountType
case object SAVINGS extends AccountType
case object MAXI_SAVINGS extends AccountType
}
16 changes: 9 additions & 7 deletions src/main/scala/com/abc/Customer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.abc

import scala.collection.mutable.ListBuffer

class Customer(val name: String, var accounts: ListBuffer[Account] = ListBuffer()) {
import com.abc.AccountType._

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

def openAccount(account: MyAccount): Customer = {
accounts += account
this
}
Expand All @@ -27,13 +29,13 @@ class Customer(val name: String, var accounts: ListBuffer[Account] = ListBuffer(
statement
}

private def statementForAccount(a: Account): String = {
private def statementForAccount(a: MyAccount): String = {
val accountType = a.accountType match {
case Account.CHECKING =>
case CHECKING =>
"Checking Account\n"
case Account.SAVINGS =>
case SAVINGS =>
"Savings Account\n"
case Account.MAXI_SAVINGS =>
case MAXI_SAVINGS =>
"Maxi Savings Account\n"
}
val transactionSummary = a.transactions.map(t => withdrawalOrDepositText(t) + " " + toDollars(t.amount.abs))
Expand All @@ -42,7 +44,7 @@ class Customer(val name: String, var accounts: ListBuffer[Account] = ListBuffer(
accountType + transactionSummary + totalSummary
}

private def withdrawalOrDepositText(t: Transaction) =
private def withdrawalOrDepositText(t: MyTransaction) =
t.amount match {
case a if a < 0 => "withdrawal"
case a if a > 0 => "deposit"
Expand Down
136 changes: 136 additions & 0 deletions src/main/scala/com/abc/MyAccount.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package com.abc

import scala.collection.mutable.ListBuffer
import com.abc.AccountType._

import java.util.Date

class MyAccount(val accountType: AccountType, var transactions: ListBuffer[MyTransaction] = ListBuffer[MyTransaction]()) {
var balance: Double = 0.0d

def deposit(amount: Double) {
require(amount>0)
transactions += new MyTransaction(amount)
balance+=amount;
}

def deposit(amount: Double, transactionDate: Date= new Date): Unit ={
require(amount>0)
transactions += new MyTransaction(amount,transactionDate)
balance+=amount;
}

def withdraw(amount: Double) {
require(amount>0)
transactions += new MyTransaction(-amount)
balance-=amount;
}

def withdraw(amount: Double, transactionDate: Date= new Date) : Unit= {
require(amount>0)
transactions += new MyTransaction(-amount, transactionDate)
balance-=amount;
}

def interestEarned: Double = {
//val amount: Double = sumTransactions()
accountType match {
case SAVINGS =>
savingsAccountInterest
case MAXI_SAVINGS =>
maxiSavingsAccountInterest
case CHECKING =>
checkingAccountInterest
}
}

def checkingAccountInterest: Double = {
var totalCheckingInterest=0d;
val tArray: Array[MyTransaction]=transactions.sortBy(_.transactionDate).toArray
var balance : Double =0.0d;
if(tArray.size>=2){
for(i<- 1 until tArray.size-1){
balance+=tArray(i-1).amount
val days : Long = (tArray(i).transactionDate.getTime-tArray(i-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
totalCheckingInterest += balance * 0.001*(days/365d);
}
}

//last transaction to today/report date interest
if(tArray.size>=1){
balance+=tArray(tArray.size-1).amount
val d : Long = ((new Date).getTime-tArray(tArray.size-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
totalCheckingInterest += balance * 0.001*(d/365d);
}

totalCheckingInterest
}

def savingsAccountInterest: Double = {
var totalSavingsInterest=0d;
val tArray: Array[MyTransaction]=transactions.sortBy(_.transactionDate).toArray
var balance : Double =0.0d;
if(tArray.size>=2){
for(i<- 1 until tArray.size-1){
balance+=tArray(i-1).amount
val d : Long = (tArray(i).transactionDate.getTime-tArray(i-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
if (balance <= 1000) {
totalSavingsInterest += balance * 0.001*(d/365d);
}else {
totalSavingsInterest += 1*(d/365d) + (balance - 1000) * 0.002*(d/365d)
}
}
}

//last transaction to today/report date interest
if(tArray.size>=1){
balance+=tArray(tArray.size-1).amount
val d : Long = ((new Date).getTime-tArray(tArray.size-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
if (balance <= 1000) {
totalSavingsInterest += balance * 0.001*(d/365d);
}else {
totalSavingsInterest += 1*(d/365d) + (balance - 1000) * 0.002*(d/365d)
}
}

totalSavingsInterest
}

def maxiSavingsAccountInterest: Double = {
var totalSavingsInterest=0d;
val tArray: Array[MyTransaction]=transactions.sortBy(_.transactionDate).toArray
var balance : Double =0.0d;
if(tArray.size>=2){
for(i<- 1 until tArray.size-1){
balance+=tArray(i-1).amount
val d : Long = (tArray(i).transactionDate.getTime-tArray(i-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
if (balance <= 1000) {
totalSavingsInterest += balance * 0.02*(d/365d);
}else if(balance>1000 && balance<=2000){
totalSavingsInterest += 20*(d/365d) + (balance - 1000) * 0.05*(d/365d)
}else{
totalSavingsInterest += 70*(d/365d) + (balance - 2000) * 0.1*(d/365d)
}
}
}

//last transaction to today/report date interest
if(tArray.size>=1){
balance+=tArray(tArray.size-1).amount
val d : Long = ((new Date).getTime-tArray(tArray.size-1).transactionDate.getTime)/(24 * 60 * 60 * 1000);
if (balance <= 1000) {
totalSavingsInterest += balance * 0.02*(d/365d);
}else if(balance>1000 && balance<=2000){
totalSavingsInterest += 20*(d/365d) + (balance - 1000) * 0.05*(d/365d)
}else{
totalSavingsInterest += 70*(d/365d) + (balance - 2000) * 0.1*(d/365d)
}
}

totalSavingsInterest
}

//def sumTransactions(checkAllTransactions: Boolean = true): Double = transactions.map(_.amount).sum
def sumTransactions(): Double = balance

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

import java.util.Date
import java.util.Calendar
import java.text.SimpleDateFormat

class MyTransaction(var amount: Double, var transactionDate: Date= new Date){

def this(amount: Double){
this(amount, new Date())
}

override def toString = {
val formatter: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd")
val dateString = formatter.format(transactionDate)
val amountString: String = "$%.2f".format(amount)

s"Transaction amount: $amountString, on date: $dateString"
}
}
15 changes: 8 additions & 7 deletions src/test/scala/com/abc/BankTest.scala
Original file line number Diff line number Diff line change
@@ -1,39 +1,40 @@
package com.abc

import org.scalatest.{Matchers, FlatSpec}
import com.abc.AccountType._

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 MyAccount(CHECKING))
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: MyAccount = new MyAccount(CHECKING)
val bill: Customer = new Customer("Bill").openAccount(checkingAccount)
bank.addCustomer(bill)
checkingAccount.deposit(100.0)
bank.totalInterestPaid should be(0.1)
bank.totalInterestPaid should be(0.0)
}

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

it should "maxi savings account" in {
val bank: Bank = new Bank
val checkingAccount: Account = new Account(Account.MAXI_SAVINGS)
val checkingAccount: MyAccount = new MyAccount(MAXI_SAVINGS)
bank.addCustomer(new Customer("Bill").openAccount(checkingAccount))
checkingAccount.deposit(3000.0)
bank.totalInterestPaid should be(170.0)
bank.totalInterestPaid should be(0.0)
}

}
30 changes: 17 additions & 13 deletions src/test/scala/com/abc/CustomerTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ package com.abc

import org.scalatest.{Matchers, FlatSpec}

import com.abc.AccountType._


class CustomerTest extends FlatSpec with Matchers {
"Customer" should "statement" in {
val checkingAccount: Account = new Account(Account.CHECKING)
val savingsAccount: Account = new Account(Account.SAVINGS)

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

ignore should "statement" in {
val checkingAccount: MyAccount = new MyAccount(CHECKING)
val savingsAccount: MyAccount = new MyAccount(SAVINGS)
val henry: Customer = new Customer("Henry").openAccount(checkingAccount).openAccount(savingsAccount)
checkingAccount.deposit(100.0)
savingsAccount.deposit(4000.0)
Expand All @@ -14,22 +23,17 @@ class CustomerTest extends FlatSpec with Matchers {
"\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")
}

it should "testOneAccount" in {
val oscar: Customer = new Customer("Oscar").openAccount(new Account(Account.SAVINGS))
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 MyAccount(SAVINGS))
oscar.openAccount(new MyAccount(CHECKING))
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))
val oscar: Customer = new Customer("Oscar").openAccount(new MyAccount(SAVINGS))
oscar.openAccount(new MyAccount(CHECKING))
oscar.numberOfAccounts should be(3)
}
}
42 changes: 42 additions & 0 deletions src/test/scala/com/abc/DateProviderTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.abc

import org.scalatest.{FlatSpec, Matchers}
import java.util.Date
import java.text.SimpleDateFormat
import java.util.Calendar

class DateProviderTest extends FlatSpec with Matchers{
"DateProvider" should "instance not null" in {
assert(DateProvider.getInstance != null)
}

it should "singleton constructor work" in {
val dateProvider1 : DateProvider = DateProvider.getInstance
val dateProvider2 : DateProvider = DateProvider.getInstance

assert(dateProvider1 === dateProvider2)
}

it should "get current date correctly" in {
val format: SimpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");

val dateProviderDate : Date = DateProvider.getInstance.now
val javaCalendarDate : Date = Calendar.getInstance.getTime

//format.format(dateProviderDate) should be format.format(javaCalendarDate)

//assert(dateProviderDate === javaCalendarDate)
assert(format.format(dateProviderDate) === format.format(javaCalendarDate))

}

ignore should "get today's date correctly" in {
val format: SimpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");

val dateProviderDate : Date = DateProvider.getInstance.now
val javaCalendarDate : Date = Calendar.getInstance.getTime

format.format(dateProviderDate) should be ("2016/07/23")

}
}
Loading