From 9cbe42bc5e2c2d70e60de039ec6d7e0d8cbcbd9c Mon Sep 17 00:00:00 2001 From: jxwatson251 Date: Mon, 14 Apr 2025 18:59:42 +0000 Subject: [PATCH 1/4] lesson_17 homework mark0 --- .../lesson17/bank/Account.java | 94 +++++++++++++ .../lesson17/bank/BankAtm.java | 26 ++-- .../bank/BusinessCheckingAccount.java | 16 +++ .../codedifferently/lesson17/bank/Check.java | 11 +- .../lesson17/bank/CheckingAccount.java | 128 +---------------- .../lesson17/bank/Customer.java | 36 ++--- .../lesson17/bank/SavingsAccount.java | 131 ++++++++++++++++++ .../InvalidBusinessAccountException.java | 10 ++ 8 files changed, 288 insertions(+), 164 deletions(-) create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/InvalidBusinessAccountException.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java new file mode 100644 index 000000000..587e54663 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java @@ -0,0 +1,94 @@ +package com.codedifferently.lesson17.bank; + +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; +import java.util.Set; + +public abstract class Account { + private final Set owners; + private final String accountNumber; + protected double balance; + protected boolean isActive; + + /** + * Constructs a new Account. + * + * @param accountNumber The account number. + * @param owners The owners of the account. + * @param initialBalance The starting balance. + */ + public Account(String accountNumber, Set owners, double initialBalance) { + this.accountNumber = accountNumber; + this.owners = owners; + this.balance = initialBalance; + this.isActive = true; + } + + public String getAccountNumber() { + return accountNumber; + } + + public Set getOwners() { + return owners; + } + + public void deposit(double amount) { + if (isClosed()) { + throw new IllegalStateException("Cannot deposit to a closed account"); + } + if (amount <= 0) { + throw new IllegalArgumentException("Deposit amount must be positive"); + } + balance += amount; + } + + public void withdraw(double amount) throws InsufficientFundsException { + if (isClosed()) { + throw new IllegalStateException("Cannot withdraw from a closed account"); + } + if (amount <= 0) { + throw new IllegalStateException("Withdrawal amount must be positive"); + } + if (balance < amount) { + throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); + } + balance -= amount; + } + + public double getBalance() { + return balance; + } + + public void closeAccount() { + if (balance > 0) { + throw new IllegalStateException("Cannot close account with a positive balance"); + } + isActive = false; + } + + public boolean isClosed() { + return !isActive; + } + + @Override + public int hashCode() { + return accountNumber.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Account other) { + return this.accountNumber.equals(other.accountNumber); + } + return false; + } + + @Override + public String toString() { + return getClass().getSimpleName() + + "{" + + "accountNumber='" + accountNumber + '\'' + + ", balance=" + balance + + ", isActive=" + isActive + + '}'; + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java index 8cbcd3cc0..b892b7e88 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java @@ -10,14 +10,24 @@ public class BankAtm { private final Map customerById = new HashMap<>(); - private final Map accountByNumber = new HashMap<>(); + private final Map accountByNumber = new HashMap<>(); /** - * Adds a checking account to the bank. + * Adds a checking or savings account to the bank. * * @param account The account to add. */ - public void addAccount(CheckingAccount account) { + public void addAccount(Account account) { + accountByNumber.put(account.getAccountNumber(), account); + account + .getOwners() + .forEach( + owner -> { + customerById.put(owner.getId(), owner); + }); + } + + public void addAccount(SavingsAccount account) { accountByNumber.put(account.getAccountNumber(), account); account .getOwners() @@ -46,7 +56,7 @@ public Set findAccountsByCustomerId(UUID customerId) { * @param amount The amount to deposit. */ public void depositFunds(String accountNumber, double amount) { - CheckingAccount account = getAccountOrThrow(accountNumber); + Account account = getAccountOrThrow(accountNumber); account.deposit(amount); } @@ -57,7 +67,7 @@ public void depositFunds(String accountNumber, double amount) { * @param check The check to deposit. */ public void depositFunds(String accountNumber, Check check) { - CheckingAccount account = getAccountOrThrow(accountNumber); + Account account = getAccountOrThrow(accountNumber); check.depositFunds(account); } @@ -68,7 +78,7 @@ public void depositFunds(String accountNumber, Check check) { * @param amount */ public void withdrawFunds(String accountNumber, double amount) { - CheckingAccount account = getAccountOrThrow(accountNumber); + Account account = getAccountOrThrow(accountNumber); account.withdraw(amount); } @@ -78,8 +88,8 @@ public void withdrawFunds(String accountNumber, double amount) { * @param accountNumber The account number. * @return The account. */ - private CheckingAccount getAccountOrThrow(String accountNumber) { - CheckingAccount account = accountByNumber.get(accountNumber); + private Account getAccountOrThrow(String accountNumber) { + Account account = accountByNumber.get(accountNumber); if (account == null || account.isClosed()) { throw new AccountNotFoundException("Account not found"); } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java new file mode 100644 index 000000000..a5944b38a --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java @@ -0,0 +1,16 @@ +package com.codedifferently.lesson17.bank; + +import java.util.Set; + +import com.codedifferently.lesson17.bank.exceptions.InvalidBusinessAccountException; + +public class BusinessCheckingAccount extends CheckingAccount { + public BusinessCheckingAccount(String accountNumber, Set owners, double initialBalance) { + super(accountNumber, owners, initialBalance); + + boolean hasBusinessOwner = owners.stream().anyMatch(Customer::isBusiness); + if (!hasBusinessOwner) { + throw new InvalidBusinessAccountException("At least one owner must be a business."); + } + } +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java index 061fa4a5c..d33c005b1 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java @@ -43,14 +43,14 @@ public void voidCheck() { /** * Deposits the check into an account. * - * @param toAccount The account to deposit the check into. + * @param account2 The account to deposit the check into. */ - public void depositFunds(CheckingAccount toAccount) { + public void depositFunds(Account account2) { if (isVoided) { throw new CheckVoidedException("Check is voided"); } account.withdraw(amount); - toAccount.deposit(amount); + account2.deposit(amount); voidCheck(); } @@ -79,4 +79,9 @@ public String toString() { + account.getAccountNumber() + '}'; } + + public double getAmount() { + // TODO Auto-generated method stub + throw new UnsupportedOperationException("Unimplemented method 'getAmount'"); + } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java index 5d8aeb74d..8498b1d15 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java @@ -1,131 +1,9 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; import java.util.Set; -/** Represents a checking account. */ -public class CheckingAccount { - - private final Set owners; - private final String accountNumber; - private double balance; - private boolean isActive; - - /** - * Creates a new checking account. - * - * @param accountNumber The account number. - * @param owners The owners of the account. - * @param initialBalance The initial balance of the account. - */ +public class CheckingAccount extends Account { public CheckingAccount(String accountNumber, Set owners, double initialBalance) { - this.accountNumber = accountNumber; - this.owners = owners; - this.balance = initialBalance; - isActive = true; - } - - /** - * Gets the account number. - * - * @return The account number. - */ - public String getAccountNumber() { - return accountNumber; - } - - /** - * Gets the owners of the account. - * - * @return The owners of the account. - */ - public Set getOwners() { - return owners; - } - - /** - * Deposits funds into the account. - * - * @param amount The amount to deposit. - */ - public void deposit(double amount) throws IllegalStateException { - if (isClosed()) { - throw new IllegalStateException("Cannot deposit to a closed account"); - } - if (amount <= 0) { - throw new IllegalArgumentException("Deposit amount must be positive"); - } - balance += amount; - } - - /** - * Withdraws funds from the account. - * - * @param amount - * @throws InsufficientFundsException - */ - public void withdraw(double amount) throws InsufficientFundsException { - if (isClosed()) { - throw new IllegalStateException("Cannot withdraw from a closed account"); - } - if (amount <= 0) { - throw new IllegalStateException("Withdrawal amount must be positive"); - } - if (balance < amount) { - throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); - } - balance -= amount; - } - - /** - * Gets the balance of the account. - * - * @return The balance of the account. - */ - public double getBalance() { - return balance; - } - - /** Closes the account. */ - public void closeAccount() throws IllegalStateException { - if (balance > 0) { - throw new IllegalStateException("Cannot close account with a positive balance"); - } - isActive = false; - } - - /** - * Checks if the account is closed. - * - * @return True if the account is closed, otherwise false. - */ - public boolean isClosed() { - return !isActive; - } - - @Override - public int hashCode() { - return accountNumber.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof CheckingAccount other) { - return accountNumber.equals(other.accountNumber); - } - return false; - } - - @Override - public String toString() { - return "CheckingAccount{" - + "accountNumber='" - + accountNumber - + '\'' - + ", balance=" - + balance - + ", isActive=" - + isActive - + '}'; + super(accountNumber, owners, initialBalance); } -} +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java index af0847134..ab1aad740 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java @@ -9,51 +9,31 @@ public class Customer { private final UUID id; private final String name; + private final boolean isBusiness; private final Set accounts = new HashSet<>(); - /** - * Creates a new customer. - * - * @param id The ID of the customer. - * @param name The name of the customer. - */ - public Customer(UUID id, String name) { + public Customer(UUID id, String name, boolean isBusiness) { this.id = id; this.name = name; + this.isBusiness = isBusiness; } - /** - * Gets the ID of the customer. - * - * @return The ID of the customer. - */ public UUID getId() { return id; } - /** - * Gets the name of the customer. - * - * @return The name of the customer. - */ public String getName() { return name; } - /** - * Adds a checking account to the customer. - * - * @param account The account to add. - */ + public boolean isBusiness() { + return isBusiness; + } + public void addAccount(CheckingAccount account) { accounts.add(account); } - /** - * Gets the accounts owned by the customer. - * - * @return The unique set of accounts owned by the customer. - */ public Set getAccounts() { return accounts; } @@ -73,6 +53,6 @@ public boolean equals(Object obj) { @Override public String toString() { - return "Customer{" + "id=" + id + ", name='" + name + '\'' + '}'; + return "Customer{" + "id=" + id + ", name='" + name + '\'' + ", isBusiness=" + isBusiness + '}'; } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java new file mode 100644 index 000000000..a1a637fa5 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -0,0 +1,131 @@ +package com.codedifferently.lesson17.bank; + +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; +import java.util.Set; + +/** Represents a savings account. */ +public class SavingsAccount { + + private final Set owners; + private final String accountNumber; + private double balance; + private boolean isActive; + + /** + * Creates a new savings account. + * + * @param accountNumber The account number. + * @param owners The owners of the account. + * @param initialBalance The initial balance of the account. + */ + public SavingsAccount(String accountNumber, Set owners, double initialBalance) { + this.accountNumber = accountNumber; + this.owners = owners; + this.balance = initialBalance; + isActive = true; + } + + /** + * Gets the account number. + * + * @return The account number. + */ + public String getAccountNumber() { + return accountNumber; + } + + /** + * Gets the owners of the account. + * + * @return The owners of the account. + */ + public Set getOwners() { + return owners; + } + + /** + * Deposits funds into the account. + * + * @param amount The amount to deposit. + */ + public void deposit(double amount) throws IllegalStateException { + if (isClosed()) { + throw new IllegalStateException("Cannot deposit to a closed account"); + } + if (amount <= 0) { + throw new IllegalArgumentException("Deposit amount must be positive"); + } + balance += amount; + } + + /** + * Withdraws funds from the account. + * + * @param amount + * @throws InsufficientFundsException + */ + public void withdraw(double amount) throws InsufficientFundsException { + if (isClosed()) { + throw new IllegalStateException("Cannot withdraw from a closed account"); + } + if (amount <= 0) { + throw new IllegalStateException("Withdrawal amount must be positive"); + } + if (balance < amount) { + throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); + } + balance -= amount; + } + + /** + * Gets the balance of the account. + * + * @return The balance of the account. + */ + public double getBalance() { + return balance; + } + + /** Closes the account. */ + public void closeAccount() throws IllegalStateException { + if (balance > 0) { + throw new IllegalStateException("Cannot close account with a positive balance"); + } + isActive = false; + } + + /** + * Checks if the account is closed. + * + * @return True if the account is closed, otherwise false. + */ + public boolean isClosed() { + return !isActive; + } + + @Override + public int hashCode() { + return accountNumber.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SavingsAccount other) { + return accountNumber.equals(other.accountNumber); + } + return false; + } + + @Override + public String toString() { + return "SavingsAccount{" + + "accountNumber='" + + accountNumber + + '\'' + + ", balance=" + + balance + + ", isActive=" + + isActive + + '}'; + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/InvalidBusinessAccountException.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/InvalidBusinessAccountException.java new file mode 100644 index 000000000..1449a583e --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/InvalidBusinessAccountException.java @@ -0,0 +1,10 @@ +package com.codedifferently.lesson17.bank.exceptions; + +public class InvalidBusinessAccountException extends RuntimeException { + + public InvalidBusinessAccountException() {} + + public InvalidBusinessAccountException(String message) { + super(message); + } +} From a399102aba93dfa754e85324a69911c5850f41fd Mon Sep 17 00:00:00 2001 From: jxwatson251 Date: Tue, 15 Apr 2025 00:44:18 +0000 Subject: [PATCH 2/4] lesson 17 homework mark1 --- .../lesson17/bank/BankAtm.java | 28 ++-- .../lesson17/bank/SavingsAccount.java | 129 +----------------- .../lesson17/bank/BankAtmTest.java | 118 +++++++++++----- .../lesson17/bank/CheckTest.java | 6 +- .../lesson17/bank/CheckingAccountTest.java | 15 +- 5 files changed, 109 insertions(+), 187 deletions(-) diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java index b892b7e88..c233abdbc 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java @@ -1,11 +1,12 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; +import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; + /** Represents a bank ATM. */ public class BankAtm { @@ -13,7 +14,7 @@ public class BankAtm { private final Map accountByNumber = new HashMap<>(); /** - * Adds a checking or savings account to the bank. + * Adds an account to the bank. * * @param account The account to add. */ @@ -27,16 +28,6 @@ public void addAccount(Account account) { }); } - public void addAccount(SavingsAccount account) { - accountByNumber.put(account.getAccountNumber(), account); - account - .getOwners() - .forEach( - owner -> { - customerById.put(owner.getId(), owner); - }); - } - /** * Finds all accounts owned by a customer. * @@ -44,9 +35,8 @@ public void addAccount(SavingsAccount account) { * @return The unique set of accounts owned by the customer. */ public Set findAccountsByCustomerId(UUID customerId) { - return customerById.containsKey(customerId) - ? customerById.get(customerId).getAccounts() - : Set.of(); + Customer customer = customerById.get(customerId); + return customer != null ? customer.getAccounts() : Set.of(); } /** @@ -65,8 +55,9 @@ public void depositFunds(String accountNumber, double amount) { * * @param accountNumber The account number. * @param check The check to deposit. + * @throws Exception */ - public void depositFunds(String accountNumber, Check check) { + public void depositFunds(String accountNumber, Check check) throws Exception { Account account = getAccountOrThrow(accountNumber); check.depositFunds(account); } @@ -76,8 +67,9 @@ public void depositFunds(String accountNumber, Check check) { * * @param accountNumber * @param amount + * @throws Exception */ - public void withdrawFunds(String accountNumber, double amount) { + public void withdrawFunds(String accountNumber, double amount) throws Exception { Account account = getAccountOrThrow(accountNumber); account.withdraw(amount); } @@ -95,4 +87,4 @@ private Account getAccountOrThrow(String accountNumber) { } return account; } -} +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java index a1a637fa5..e612faa22 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -1,131 +1,10 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; import java.util.Set; -/** Represents a savings account. */ -public class SavingsAccount { - - private final Set owners; - private final String accountNumber; - private double balance; - private boolean isActive; - - /** - * Creates a new savings account. - * - * @param accountNumber The account number. - * @param owners The owners of the account. - * @param initialBalance The initial balance of the account. - */ +public class SavingsAccount extends Account { public SavingsAccount(String accountNumber, Set owners, double initialBalance) { - this.accountNumber = accountNumber; - this.owners = owners; - this.balance = initialBalance; - isActive = true; - } - - /** - * Gets the account number. - * - * @return The account number. - */ - public String getAccountNumber() { - return accountNumber; - } - - /** - * Gets the owners of the account. - * - * @return The owners of the account. - */ - public Set getOwners() { - return owners; - } - - /** - * Deposits funds into the account. - * - * @param amount The amount to deposit. - */ - public void deposit(double amount) throws IllegalStateException { - if (isClosed()) { - throw new IllegalStateException("Cannot deposit to a closed account"); - } - if (amount <= 0) { - throw new IllegalArgumentException("Deposit amount must be positive"); - } - balance += amount; - } - - /** - * Withdraws funds from the account. - * - * @param amount - * @throws InsufficientFundsException - */ - public void withdraw(double amount) throws InsufficientFundsException { - if (isClosed()) { - throw new IllegalStateException("Cannot withdraw from a closed account"); - } - if (amount <= 0) { - throw new IllegalStateException("Withdrawal amount must be positive"); - } - if (balance < amount) { - throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); - } - balance -= amount; - } - - /** - * Gets the balance of the account. - * - * @return The balance of the account. - */ - public double getBalance() { - return balance; - } - - /** Closes the account. */ - public void closeAccount() throws IllegalStateException { - if (balance > 0) { - throw new IllegalStateException("Cannot close account with a positive balance"); - } - isActive = false; - } - - /** - * Checks if the account is closed. - * - * @return True if the account is closed, otherwise false. - */ - public boolean isClosed() { - return !isActive; - } - - @Override - public int hashCode() { - return accountNumber.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof SavingsAccount other) { - return accountNumber.equals(other.accountNumber); - } - return false; - } - - @Override - public String toString() { - return "SavingsAccount{" - + "accountNumber='" - + accountNumber - + '\'' - + ", balance=" - + balance - + ", isActive=" - + isActive - + '}'; + super(accountNumber, owners, initialBalance); } -} + +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java index fa4a913a2..99fcf1fc8 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java @@ -2,9 +2,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; +import com.codedifferently.lesson17.bank.exceptions.InvalidBusinessAccountException; import java.util.Set; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; @@ -13,89 +15,137 @@ class BankAtmTest { private BankAtm classUnderTest; - private CheckingAccount account1; - private CheckingAccount account2; + private CheckingAccount checkingAccount1; + private CheckingAccount checkingAccount2; + private SavingsAccount savingsAccount1; + private SavingsAccount savingsAccount2; private Customer customer1; private Customer customer2; @BeforeEach void setUp() { classUnderTest = new BankAtm(); - customer1 = new Customer(UUID.randomUUID(), "John Doe"); - customer2 = new Customer(UUID.randomUUID(), "Jane Smith"); - account1 = new CheckingAccount("123456789", Set.of(customer1), 100.0); - account2 = new CheckingAccount("987654321", Set.of(customer1, customer2), 200.0); - customer1.addAccount(account1); - customer1.addAccount(account2); - customer2.addAccount(account2); - classUnderTest.addAccount(account1); - classUnderTest.addAccount(account2); + customer1 = new Customer(UUID.randomUUID(), "John Doe", false); + customer2 = new Customer(UUID.randomUUID(), "Jane Smith", false); + checkingAccount1 = new CheckingAccount("12345", Set.of(customer1), 100.0); + checkingAccount2 = new CheckingAccount("54321", Set.of(customer1, customer2), 200.0); + savingsAccount1 = new SavingsAccount("56789", Set.of(customer1), 100.0); + savingsAccount2 = new SavingsAccount("98765", Set.of(customer1, customer2), 200.0); + customer1.addAccount(checkingAccount1); + customer1.addAccount(checkingAccount2); + customer2.addAccount(checkingAccount1); + customer2.addAccount(checkingAccount2); + customer1.addAccount(savingsAccount1); + customer1.addAccount(savingsAccount2); + customer2.addAccount(savingsAccount1); + customer2.addAccount(savingsAccount2); + classUnderTest.addAccount(checkingAccount1); + classUnderTest.addAccount(checkingAccount2); + classUnderTest.addAccount(savingsAccount1); + classUnderTest.addAccount(savingsAccount2); } @Test void testAddAccount() { // Arrange - Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson"); - CheckingAccount account3 = new CheckingAccount("555555555", Set.of(customer3), 300.0); - customer3.addAccount(account3); + Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson", false); + CheckingAccount checkingAccount3 = new CheckingAccount("555555555", Set.of(customer3), 300.0); + SavingsAccount savingsAccount3 = new SavingsAccount("666666666", Set.of(customer3), 300.0); + customer3.addAccount(checkingAccount3); + customer3.addAccount(savingsAccount3); // Act - classUnderTest.addAccount(account3); + classUnderTest.addAccount(checkingAccount3); + classUnderTest.addAccount(savingsAccount3); // Assert - Set accounts = classUnderTest.findAccountsByCustomerId(customer3.getId()); - assertThat(accounts).containsOnly(account3); + Set accounts = classUnderTest.findAccountsByCustomerId(customer3.getId()); + assertThat(accounts).contains(checkingAccount3); + assertThat(accounts).contains(savingsAccount3); + } + + @Test + void testBusinessCheckingAccount_WithBusinessOwner_Succeeds() { + // Arrange + Customer businessCustomer = new Customer(UUID.randomUUID(), "Business LLC", true); + Customer individualCustomer = new Customer(UUID.randomUUID(), "Regular Joe", false); + Set owners = Set.of(businessCustomer, individualCustomer); + + // Act + BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("BUS123", owners, 1000.0); + + // Assert + assertThat(businessAccount.getBalance()).isEqualTo(1000.0); + assertThat(businessAccount.getOwners()).contains(businessCustomer); + } + + @Test + void testBusinessCheckingAccount_WithoutBusinessOwner_ThrowsException() { + // Arrange + Customer c1 = new Customer(UUID.randomUUID(), "Person One", false); + Customer c2 = new Customer(UUID.randomUUID(), "Person Two", false); + Set owners = Set.of(c1, c2); + + // Act & Assert + assertThatThrownBy(() -> new BusinessCheckingAccount("BUS999", owners, 500.0)) + .isInstanceOf(InvalidBusinessAccountException.class) + .hasMessage("At least one owner must be a business."); } @Test void testFindAccountsByCustomerId() { // Act - Set accounts = classUnderTest.findAccountsByCustomerId(customer1.getId()); + Set accounts = classUnderTest.findAccountsByCustomerId(customer1.getId()); // Assert - assertThat(accounts).containsOnly(account1, account2); + assertThat(accounts).contains(checkingAccount1, checkingAccount2); + assertThat(accounts).contains(savingsAccount1, savingsAccount2); } @Test void testDepositFunds() { // Act - classUnderTest.depositFunds(account1.getAccountNumber(), 50.0); + classUnderTest.depositFunds(checkingAccount1.getAccountNumber(), 50.0); + classUnderTest.depositFunds(savingsAccount1.getAccountNumber(), 50.0); // Assert - assertThat(account1.getBalance()).isEqualTo(150.0); + assertThat(checkingAccount1.getBalance()).isEqualTo(150.0); + assertThat(savingsAccount1.getBalance()).isEqualTo(150.0); } @Test - void testDepositFunds_Check() { + void testDepositFunds_Check() throws Exception { // Arrange - Check check = new Check("987654321", 100.0, account1); + Check check = new Check("12345", 100.0, checkingAccount1); // Act - classUnderTest.depositFunds("987654321", check); + classUnderTest.depositFunds("54321", check); // Assert - assertThat(account1.getBalance()).isEqualTo(0); - assertThat(account2.getBalance()).isEqualTo(300.0); + assertThat(checkingAccount1.getBalance()).isEqualTo(0); + assertThat(checkingAccount2.getBalance()).isEqualTo(300.0); } @Test - void testDepositFunds_DoesntDepositCheckTwice() { - Check check = new Check("987654321", 100.0, account1); + void testDepositFunds_DoesntDepositCheckTwice() throws Exception { + Check check = new Check("987654321", 100.0, checkingAccount1); - classUnderTest.depositFunds("987654321", check); + classUnderTest.depositFunds("54321", check); assertThatExceptionOfType(CheckVoidedException.class) - .isThrownBy(() -> classUnderTest.depositFunds("987654321", check)) + .isThrownBy(() -> classUnderTest.depositFunds("54321", check)) .withMessage("Check is voided"); } @Test - void testWithdrawFunds() { + void testWithdrawFunds() throws Exception { // Act - classUnderTest.withdrawFunds(account2.getAccountNumber(), 50.0); + classUnderTest.withdrawFunds(checkingAccount2.getAccountNumber(), 50.0); + classUnderTest.withdrawFunds(savingsAccount2.getAccountNumber(), 50.0); // Assert - assertThat(account2.getBalance()).isEqualTo(150.0); + assertThat(checkingAccount2.getBalance()).isEqualTo(150.0); + assertThat(savingsAccount2.getBalance()).isEqualTo(150.0); } @Test @@ -107,4 +157,4 @@ void testWithdrawFunds_AccountNotFound() { .isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0)) .withMessage("Account not found"); } -} +} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java index 6b62d39ba..7131a8dac 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java @@ -2,11 +2,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; + class CheckTest { private CheckingAccount account1; @@ -21,7 +21,7 @@ void setUp() { } @Test - void testDepositFunds() { + void testDepositFunds() throws Exception { // Act classUnderTest.depositFunds(account2); diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java index f155d8e5b..f3901217d 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java @@ -1,17 +1,18 @@ package com.codedifferently.lesson17.bank; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; + class CheckingAccountTest { private CheckingAccount classUnderTest; @@ -20,8 +21,8 @@ class CheckingAccountTest { @BeforeEach void setUp() { owners = new HashSet<>(); - owners.add(new Customer(UUID.randomUUID(), "John Doe")); - owners.add(new Customer(UUID.randomUUID(), "Jane Smith")); + owners.add(new Customer(UUID.randomUUID(), "John Doe", false)); + owners.add(new Customer(UUID.randomUUID(), "Jane Smith", false)); classUnderTest = new CheckingAccount("123456789", owners, 100.0); } From 40abc44a083a1731d7024f20b61ab731533c3792 Mon Sep 17 00:00:00 2001 From: jxwatson251 Date: Tue, 15 Apr 2025 13:31:17 +0000 Subject: [PATCH 3/4] lesson 17 mark2 --- .../lesson17/bank/Account.java | 94 ------------- .../lesson17/bank/BankAtm.java | 32 ++--- .../bank/BusinessCheckingAccount.java | 16 --- .../bank/BusinessCheckingSavingsAccount.java | 10 ++ .../codedifferently/lesson17/bank/Check.java | 11 +- .../lesson17/bank/CheckingAccount.java | 128 +++++++++++++++++- .../lesson17/bank/Customer.java | 36 +++-- .../lesson17/bank/SavingsAccount.java | 15 +- .../lesson17/bank/BankAtmTest.java | 118 +++++----------- .../lesson17/bank/CheckTest.java | 6 +- .../lesson17/bank/CheckingAccountTest.java | 15 +- 11 files changed, 237 insertions(+), 244 deletions(-) delete mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java delete mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java deleted file mode 100644 index 587e54663..000000000 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.codedifferently.lesson17.bank; - -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; -import java.util.Set; - -public abstract class Account { - private final Set owners; - private final String accountNumber; - protected double balance; - protected boolean isActive; - - /** - * Constructs a new Account. - * - * @param accountNumber The account number. - * @param owners The owners of the account. - * @param initialBalance The starting balance. - */ - public Account(String accountNumber, Set owners, double initialBalance) { - this.accountNumber = accountNumber; - this.owners = owners; - this.balance = initialBalance; - this.isActive = true; - } - - public String getAccountNumber() { - return accountNumber; - } - - public Set getOwners() { - return owners; - } - - public void deposit(double amount) { - if (isClosed()) { - throw new IllegalStateException("Cannot deposit to a closed account"); - } - if (amount <= 0) { - throw new IllegalArgumentException("Deposit amount must be positive"); - } - balance += amount; - } - - public void withdraw(double amount) throws InsufficientFundsException { - if (isClosed()) { - throw new IllegalStateException("Cannot withdraw from a closed account"); - } - if (amount <= 0) { - throw new IllegalStateException("Withdrawal amount must be positive"); - } - if (balance < amount) { - throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); - } - balance -= amount; - } - - public double getBalance() { - return balance; - } - - public void closeAccount() { - if (balance > 0) { - throw new IllegalStateException("Cannot close account with a positive balance"); - } - isActive = false; - } - - public boolean isClosed() { - return !isActive; - } - - @Override - public int hashCode() { - return accountNumber.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof Account other) { - return this.accountNumber.equals(other.accountNumber); - } - return false; - } - - @Override - public String toString() { - return getClass().getSimpleName() + - "{" + - "accountNumber='" + accountNumber + '\'' + - ", balance=" + balance + - ", isActive=" + isActive + - '}'; - } -} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java index c233abdbc..8cbcd3cc0 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BankAtm.java @@ -1,24 +1,23 @@ package com.codedifferently.lesson17.bank; +import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.UUID; -import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; - /** Represents a bank ATM. */ public class BankAtm { private final Map customerById = new HashMap<>(); - private final Map accountByNumber = new HashMap<>(); + private final Map accountByNumber = new HashMap<>(); /** - * Adds an account to the bank. + * Adds a checking account to the bank. * * @param account The account to add. */ - public void addAccount(Account account) { + public void addAccount(CheckingAccount account) { accountByNumber.put(account.getAccountNumber(), account); account .getOwners() @@ -35,8 +34,9 @@ public void addAccount(Account account) { * @return The unique set of accounts owned by the customer. */ public Set findAccountsByCustomerId(UUID customerId) { - Customer customer = customerById.get(customerId); - return customer != null ? customer.getAccounts() : Set.of(); + return customerById.containsKey(customerId) + ? customerById.get(customerId).getAccounts() + : Set.of(); } /** @@ -46,7 +46,7 @@ public Set findAccountsByCustomerId(UUID customerId) { * @param amount The amount to deposit. */ public void depositFunds(String accountNumber, double amount) { - Account account = getAccountOrThrow(accountNumber); + CheckingAccount account = getAccountOrThrow(accountNumber); account.deposit(amount); } @@ -55,10 +55,9 @@ public void depositFunds(String accountNumber, double amount) { * * @param accountNumber The account number. * @param check The check to deposit. - * @throws Exception */ - public void depositFunds(String accountNumber, Check check) throws Exception { - Account account = getAccountOrThrow(accountNumber); + public void depositFunds(String accountNumber, Check check) { + CheckingAccount account = getAccountOrThrow(accountNumber); check.depositFunds(account); } @@ -67,10 +66,9 @@ public void depositFunds(String accountNumber, Check check) throws Exception { * * @param accountNumber * @param amount - * @throws Exception */ - public void withdrawFunds(String accountNumber, double amount) throws Exception { - Account account = getAccountOrThrow(accountNumber); + public void withdrawFunds(String accountNumber, double amount) { + CheckingAccount account = getAccountOrThrow(accountNumber); account.withdraw(amount); } @@ -80,11 +78,11 @@ public void withdrawFunds(String accountNumber, double amount) throws Exception * @param accountNumber The account number. * @return The account. */ - private Account getAccountOrThrow(String accountNumber) { - Account account = accountByNumber.get(accountNumber); + private CheckingAccount getAccountOrThrow(String accountNumber) { + CheckingAccount account = accountByNumber.get(accountNumber); if (account == null || account.isClosed()) { throw new AccountNotFoundException("Account not found"); } return account; } -} \ No newline at end of file +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java deleted file mode 100644 index a5944b38a..000000000 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.codedifferently.lesson17.bank; - -import java.util.Set; - -import com.codedifferently.lesson17.bank.exceptions.InvalidBusinessAccountException; - -public class BusinessCheckingAccount extends CheckingAccount { - public BusinessCheckingAccount(String accountNumber, Set owners, double initialBalance) { - super(accountNumber, owners, initialBalance); - - boolean hasBusinessOwner = owners.stream().anyMatch(Customer::isBusiness); - if (!hasBusinessOwner) { - throw new InvalidBusinessAccountException("At least one owner must be a business."); - } - } -} \ No newline at end of file diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java new file mode 100644 index 000000000..892e79008 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java @@ -0,0 +1,10 @@ +package com.codedifferently.lesson17.bank; + +import java.util.Set; + +public class BusinessCheckingSavingsAccount extends CheckingAccount { + public BusinessCheckingSavingsAccount( + String accountNumber, Set owners, double initialBalance) { + super(accountNumber, owners, initialBalance); + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java index d33c005b1..061fa4a5c 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Check.java @@ -43,14 +43,14 @@ public void voidCheck() { /** * Deposits the check into an account. * - * @param account2 The account to deposit the check into. + * @param toAccount The account to deposit the check into. */ - public void depositFunds(Account account2) { + public void depositFunds(CheckingAccount toAccount) { if (isVoided) { throw new CheckVoidedException("Check is voided"); } account.withdraw(amount); - account2.deposit(amount); + toAccount.deposit(amount); voidCheck(); } @@ -79,9 +79,4 @@ public String toString() { + account.getAccountNumber() + '}'; } - - public double getAmount() { - // TODO Auto-generated method stub - throw new UnsupportedOperationException("Unimplemented method 'getAmount'"); - } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java index 8498b1d15..343e58e6e 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java @@ -1,9 +1,131 @@ package com.codedifferently.lesson17.bank; +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; import java.util.Set; -public class CheckingAccount extends Account { +/** Represents a checking account. */ +public class CheckingAccount { + + private final Set owners; + private final String accountNumber; + protected double balance; + private boolean isActive; + + /** + * Creates a new checking account. + * + * @param accountNumber The account number. + * @param owners The owners of the account. + * @param initialBalance The initial balance of the account. + */ public CheckingAccount(String accountNumber, Set owners, double initialBalance) { - super(accountNumber, owners, initialBalance); + this.accountNumber = accountNumber; + this.owners = owners; + this.balance = initialBalance; + isActive = true; + } + + /** + * Gets the account number. + * + * @return The account number. + */ + public String getAccountNumber() { + return accountNumber; + } + + /** + * Gets the owners of the account. + * + * @return The owners of the account. + */ + public Set getOwners() { + return owners; + } + + /** + * Deposits funds into the account. + * + * @param amount The amount to deposit. + */ + public void deposit(double amount) throws IllegalStateException { + if (isClosed()) { + throw new IllegalStateException("Cannot deposit to a closed account"); + } + if (amount <= 0) { + throw new IllegalArgumentException("Deposit amount must be positive"); + } + balance += amount; + } + + /** + * Withdraws funds from the account. + * + * @param amount + * @throws InsufficientFundsException + */ + public void withdraw(double amount) throws InsufficientFundsException { + if (isClosed()) { + throw new IllegalStateException("Cannot withdraw from a closed account"); + } + if (amount <= 0) { + throw new IllegalStateException("Withdrawal amount must be positive"); + } + if (balance < amount) { + throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); + } + balance -= amount; + } + + /** + * Gets the balance of the account. + * + * @return The balance of the account. + */ + public double getBalance() { + return balance; + } + + /** Closes the account. */ + public void closeAccount() throws IllegalStateException { + if (balance > 0) { + throw new IllegalStateException("Cannot close account with a positive balance"); + } + isActive = false; + } + + /** + * Checks if the account is closed. + * + * @return True if the account is closed, otherwise false. + */ + public boolean isClosed() { + return !isActive; + } + + @Override + public int hashCode() { + return accountNumber.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof CheckingAccount other) { + return accountNumber.equals(other.accountNumber); + } + return false; + } + + @Override + public String toString() { + return "CheckingAccount{" + + "accountNumber='" + + accountNumber + + '\'' + + ", balance=" + + balance + + ", isActive=" + + isActive + + '}'; } -} \ No newline at end of file +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java index ab1aad740..af0847134 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Customer.java @@ -9,31 +9,51 @@ public class Customer { private final UUID id; private final String name; - private final boolean isBusiness; private final Set accounts = new HashSet<>(); - public Customer(UUID id, String name, boolean isBusiness) { + /** + * Creates a new customer. + * + * @param id The ID of the customer. + * @param name The name of the customer. + */ + public Customer(UUID id, String name) { this.id = id; this.name = name; - this.isBusiness = isBusiness; } + /** + * Gets the ID of the customer. + * + * @return The ID of the customer. + */ public UUID getId() { return id; } + /** + * Gets the name of the customer. + * + * @return The name of the customer. + */ public String getName() { return name; } - public boolean isBusiness() { - return isBusiness; - } - + /** + * Adds a checking account to the customer. + * + * @param account The account to add. + */ public void addAccount(CheckingAccount account) { accounts.add(account); } + /** + * Gets the accounts owned by the customer. + * + * @return The unique set of accounts owned by the customer. + */ public Set getAccounts() { return accounts; } @@ -53,6 +73,6 @@ public boolean equals(Object obj) { @Override public String toString() { - return "Customer{" + "id=" + id + ", name='" + name + '\'' + ", isBusiness=" + isBusiness + '}'; + return "Customer{" + "id=" + id + ", name='" + name + '\'' + '}'; } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java index e612faa22..0554df482 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -2,9 +2,18 @@ import java.util.Set; -public class SavingsAccount extends Account { +public class SavingsAccount extends CheckingAccount { public SavingsAccount(String accountNumber, Set owners, double initialBalance) { super(accountNumber, owners, initialBalance); } - -} \ No newline at end of file + + @Override + public void withdraw(double amount) { + String method = null; + if ("check".equalsIgnoreCase(method)) { + throw new UnsupportedOperationException("Cannot withdraw checks from the savings account"); + } + + this.balance += amount; + } +} diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java index 99fcf1fc8..fa4a913a2 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/BankAtmTest.java @@ -2,11 +2,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; -import com.codedifferently.lesson17.bank.exceptions.InvalidBusinessAccountException; import java.util.Set; import java.util.UUID; import org.junit.jupiter.api.BeforeEach; @@ -15,137 +13,89 @@ class BankAtmTest { private BankAtm classUnderTest; - private CheckingAccount checkingAccount1; - private CheckingAccount checkingAccount2; - private SavingsAccount savingsAccount1; - private SavingsAccount savingsAccount2; + private CheckingAccount account1; + private CheckingAccount account2; private Customer customer1; private Customer customer2; @BeforeEach void setUp() { classUnderTest = new BankAtm(); - customer1 = new Customer(UUID.randomUUID(), "John Doe", false); - customer2 = new Customer(UUID.randomUUID(), "Jane Smith", false); - checkingAccount1 = new CheckingAccount("12345", Set.of(customer1), 100.0); - checkingAccount2 = new CheckingAccount("54321", Set.of(customer1, customer2), 200.0); - savingsAccount1 = new SavingsAccount("56789", Set.of(customer1), 100.0); - savingsAccount2 = new SavingsAccount("98765", Set.of(customer1, customer2), 200.0); - customer1.addAccount(checkingAccount1); - customer1.addAccount(checkingAccount2); - customer2.addAccount(checkingAccount1); - customer2.addAccount(checkingAccount2); - customer1.addAccount(savingsAccount1); - customer1.addAccount(savingsAccount2); - customer2.addAccount(savingsAccount1); - customer2.addAccount(savingsAccount2); - classUnderTest.addAccount(checkingAccount1); - classUnderTest.addAccount(checkingAccount2); - classUnderTest.addAccount(savingsAccount1); - classUnderTest.addAccount(savingsAccount2); + customer1 = new Customer(UUID.randomUUID(), "John Doe"); + customer2 = new Customer(UUID.randomUUID(), "Jane Smith"); + account1 = new CheckingAccount("123456789", Set.of(customer1), 100.0); + account2 = new CheckingAccount("987654321", Set.of(customer1, customer2), 200.0); + customer1.addAccount(account1); + customer1.addAccount(account2); + customer2.addAccount(account2); + classUnderTest.addAccount(account1); + classUnderTest.addAccount(account2); } @Test void testAddAccount() { // Arrange - Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson", false); - CheckingAccount checkingAccount3 = new CheckingAccount("555555555", Set.of(customer3), 300.0); - SavingsAccount savingsAccount3 = new SavingsAccount("666666666", Set.of(customer3), 300.0); - customer3.addAccount(checkingAccount3); - customer3.addAccount(savingsAccount3); + Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson"); + CheckingAccount account3 = new CheckingAccount("555555555", Set.of(customer3), 300.0); + customer3.addAccount(account3); // Act - classUnderTest.addAccount(checkingAccount3); - classUnderTest.addAccount(savingsAccount3); + classUnderTest.addAccount(account3); // Assert - Set accounts = classUnderTest.findAccountsByCustomerId(customer3.getId()); - assertThat(accounts).contains(checkingAccount3); - assertThat(accounts).contains(savingsAccount3); - } - - @Test - void testBusinessCheckingAccount_WithBusinessOwner_Succeeds() { - // Arrange - Customer businessCustomer = new Customer(UUID.randomUUID(), "Business LLC", true); - Customer individualCustomer = new Customer(UUID.randomUUID(), "Regular Joe", false); - Set owners = Set.of(businessCustomer, individualCustomer); - - // Act - BusinessCheckingAccount businessAccount = new BusinessCheckingAccount("BUS123", owners, 1000.0); - - // Assert - assertThat(businessAccount.getBalance()).isEqualTo(1000.0); - assertThat(businessAccount.getOwners()).contains(businessCustomer); - } - - @Test - void testBusinessCheckingAccount_WithoutBusinessOwner_ThrowsException() { - // Arrange - Customer c1 = new Customer(UUID.randomUUID(), "Person One", false); - Customer c2 = new Customer(UUID.randomUUID(), "Person Two", false); - Set owners = Set.of(c1, c2); - - // Act & Assert - assertThatThrownBy(() -> new BusinessCheckingAccount("BUS999", owners, 500.0)) - .isInstanceOf(InvalidBusinessAccountException.class) - .hasMessage("At least one owner must be a business."); + Set accounts = classUnderTest.findAccountsByCustomerId(customer3.getId()); + assertThat(accounts).containsOnly(account3); } @Test void testFindAccountsByCustomerId() { // Act - Set accounts = classUnderTest.findAccountsByCustomerId(customer1.getId()); + Set accounts = classUnderTest.findAccountsByCustomerId(customer1.getId()); // Assert - assertThat(accounts).contains(checkingAccount1, checkingAccount2); - assertThat(accounts).contains(savingsAccount1, savingsAccount2); + assertThat(accounts).containsOnly(account1, account2); } @Test void testDepositFunds() { // Act - classUnderTest.depositFunds(checkingAccount1.getAccountNumber(), 50.0); - classUnderTest.depositFunds(savingsAccount1.getAccountNumber(), 50.0); + classUnderTest.depositFunds(account1.getAccountNumber(), 50.0); // Assert - assertThat(checkingAccount1.getBalance()).isEqualTo(150.0); - assertThat(savingsAccount1.getBalance()).isEqualTo(150.0); + assertThat(account1.getBalance()).isEqualTo(150.0); } @Test - void testDepositFunds_Check() throws Exception { + void testDepositFunds_Check() { // Arrange - Check check = new Check("12345", 100.0, checkingAccount1); + Check check = new Check("987654321", 100.0, account1); // Act - classUnderTest.depositFunds("54321", check); + classUnderTest.depositFunds("987654321", check); // Assert - assertThat(checkingAccount1.getBalance()).isEqualTo(0); - assertThat(checkingAccount2.getBalance()).isEqualTo(300.0); + assertThat(account1.getBalance()).isEqualTo(0); + assertThat(account2.getBalance()).isEqualTo(300.0); } @Test - void testDepositFunds_DoesntDepositCheckTwice() throws Exception { - Check check = new Check("987654321", 100.0, checkingAccount1); + void testDepositFunds_DoesntDepositCheckTwice() { + Check check = new Check("987654321", 100.0, account1); - classUnderTest.depositFunds("54321", check); + classUnderTest.depositFunds("987654321", check); assertThatExceptionOfType(CheckVoidedException.class) - .isThrownBy(() -> classUnderTest.depositFunds("54321", check)) + .isThrownBy(() -> classUnderTest.depositFunds("987654321", check)) .withMessage("Check is voided"); } @Test - void testWithdrawFunds() throws Exception { + void testWithdrawFunds() { // Act - classUnderTest.withdrawFunds(checkingAccount2.getAccountNumber(), 50.0); - classUnderTest.withdrawFunds(savingsAccount2.getAccountNumber(), 50.0); + classUnderTest.withdrawFunds(account2.getAccountNumber(), 50.0); // Assert - assertThat(checkingAccount2.getBalance()).isEqualTo(150.0); - assertThat(savingsAccount2.getBalance()).isEqualTo(150.0); + assertThat(account2.getBalance()).isEqualTo(150.0); } @Test @@ -157,4 +107,4 @@ void testWithdrawFunds_AccountNotFound() { .isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0)) .withMessage("Account not found"); } -} \ No newline at end of file +} diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java index 7131a8dac..6b62d39ba 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckTest.java @@ -2,10 +2,10 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class CheckTest { @@ -21,7 +21,7 @@ void setUp() { } @Test - void testDepositFunds() throws Exception { + void testDepositFunds() { // Act classUnderTest.depositFunds(account2); diff --git a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java index f3901217d..f155d8e5b 100644 --- a/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java +++ b/lesson_17/bank/bank_app/src/test/java/com/codedifferently/lesson17/bank/CheckingAccountTest.java @@ -1,17 +1,16 @@ package com.codedifferently.lesson17.bank; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; - import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class CheckingAccountTest { @@ -21,8 +20,8 @@ class CheckingAccountTest { @BeforeEach void setUp() { owners = new HashSet<>(); - owners.add(new Customer(UUID.randomUUID(), "John Doe", false)); - owners.add(new Customer(UUID.randomUUID(), "Jane Smith", false)); + owners.add(new Customer(UUID.randomUUID(), "John Doe")); + owners.add(new Customer(UUID.randomUUID(), "Jane Smith")); classUnderTest = new CheckingAccount("123456789", owners, 100.0); } From 3cae5548ae964e56b1bc24c68bc274aa8e641b8e Mon Sep 17 00:00:00 2001 From: jxwatson251 Date: Tue, 15 Apr 2025 18:51:29 +0000 Subject: [PATCH 4/4] lesson 17 homework mark3 --- .../lesson17/bank/Account.java | 140 ++++++++++++++++++ ...ount.java => BusinessCheckingAccount.java} | 4 +- .../lesson17/bank/CheckingAccount.java | 117 +-------------- .../lesson17/bank/SavingsAccount.java | 12 +- .../exceptions/IllegalStatementException.java | 10 ++ 5 files changed, 157 insertions(+), 126 deletions(-) create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java rename lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/{BusinessCheckingSavingsAccount.java => BusinessCheckingAccount.java} (64%) create mode 100644 lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/IllegalStatementException.java diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java new file mode 100644 index 000000000..d962b7c30 --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/Account.java @@ -0,0 +1,140 @@ +package com.codedifferently.lesson17.bank; + +import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; +import java.util.Set; + +/** Represents an account. */ +public class Account { + + private final Set owners; + private final String accountNumber; + protected double balance; + private boolean isActive; + + /** + * Creates a new account. + * + * @param accountNumber The account number. + * @param owners The owners of the account. + * @param initialBalance The initial balance of the account. + */ + public Account(String accountNumber, Set owners, double initialBalance) { + this.accountNumber = accountNumber; + this.owners = owners; + this.balance = initialBalance; + isActive = true; + } + + /** + * Gets the account number. + * + * @return The account number. + */ + public String getAccountNumber() { + return accountNumber; + } + + /** + * Gets the owners of the account. + * + * @return The owners of the account. + */ + public Set getOwners() { + return owners; + } + + /** + * Deposits funds into the account. + * + * @param amount The amount to deposit. + */ + public void deposit(double amount) throws IllegalStateException { + if (isClosed()) { + throw new IllegalStateException("Cannot deposit to a closed account"); + } + if (amount <= 0) { + throw new IllegalArgumentException("Deposit amount must be positive"); + } + balance += amount; + } + + /** + * Withdraws funds from the account. + * + * @param amount + * @throws InsufficientFundsException + */ + public void withdraw(double amount) throws InsufficientFundsException { + if (isClosed()) { + throw new IllegalStateException("Cannot withdraw from a closed account"); + } + if (amount <= 0) { + throw new IllegalStateException("Withdrawal amount must be positive"); + } + if (balance < amount) { + throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); + } + balance -= amount; + } + + /** + * Gets the balance of the account. + * + * @return The balance of the account. + */ + public double getBalance() { + return balance; + } + + /** Closes the account. */ + public void closeAccount() throws IllegalStateException { + if (balance > 0) { + throw new IllegalStateException("Cannot close account with a positive balance"); + } + isActive = false; + } + + /** + * Checks if the account is closed. + * + * @return True if the account is closed, otherwise false. + */ + public boolean isClosed() { + return !isActive; + } + + @Override + public int hashCode() { + return accountNumber.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Account other) { + return accountNumber.equals(other.accountNumber); + } + return false; + } + + @Override + public String toString() { + return "Account{" + + "accountNumber='" + + accountNumber + + '\'' + + ", balance=" + + balance + + ", isActive=" + + isActive + + '}'; + } + + /** + * Checks if the account is Active. + * + * @return True if the account is closed, otherwise false. + */ + public boolean isActive() { + return isActive; + } +} diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java similarity index 64% rename from lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java rename to lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java index 892e79008..c4b574e6f 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingSavingsAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/BusinessCheckingAccount.java @@ -2,8 +2,8 @@ import java.util.Set; -public class BusinessCheckingSavingsAccount extends CheckingAccount { - public BusinessCheckingSavingsAccount( +public class BusinessCheckingAccount extends CheckingAccount { + public BusinessCheckingAccount( String accountNumber, Set owners, double initialBalance) { super(accountNumber, owners, initialBalance); } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java index 343e58e6e..72b0cafec 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/CheckingAccount.java @@ -1,131 +1,22 @@ package com.codedifferently.lesson17.bank; -import com.codedifferently.lesson17.bank.exceptions.InsufficientFundsException; import java.util.Set; -/** Represents a checking account. */ -public class CheckingAccount { - - private final Set owners; - private final String accountNumber; - protected double balance; - private boolean isActive; - - /** - * Creates a new checking account. - * - * @param accountNumber The account number. - * @param owners The owners of the account. - * @param initialBalance The initial balance of the account. - */ +public class CheckingAccount extends Account { public CheckingAccount(String accountNumber, Set owners, double initialBalance) { - this.accountNumber = accountNumber; - this.owners = owners; - this.balance = initialBalance; - isActive = true; - } - - /** - * Gets the account number. - * - * @return The account number. - */ - public String getAccountNumber() { - return accountNumber; - } - - /** - * Gets the owners of the account. - * - * @return The owners of the account. - */ - public Set getOwners() { - return owners; - } - - /** - * Deposits funds into the account. - * - * @param amount The amount to deposit. - */ - public void deposit(double amount) throws IllegalStateException { - if (isClosed()) { - throw new IllegalStateException("Cannot deposit to a closed account"); - } - if (amount <= 0) { - throw new IllegalArgumentException("Deposit amount must be positive"); - } - balance += amount; - } - - /** - * Withdraws funds from the account. - * - * @param amount - * @throws InsufficientFundsException - */ - public void withdraw(double amount) throws InsufficientFundsException { - if (isClosed()) { - throw new IllegalStateException("Cannot withdraw from a closed account"); - } - if (amount <= 0) { - throw new IllegalStateException("Withdrawal amount must be positive"); - } - if (balance < amount) { - throw new InsufficientFundsException("Account does not have enough funds for withdrawal"); - } - balance -= amount; - } - - /** - * Gets the balance of the account. - * - * @return The balance of the account. - */ - public double getBalance() { - return balance; - } - - /** Closes the account. */ - public void closeAccount() throws IllegalStateException { - if (balance > 0) { - throw new IllegalStateException("Cannot close account with a positive balance"); - } - isActive = false; - } - - /** - * Checks if the account is closed. - * - * @return True if the account is closed, otherwise false. - */ - public boolean isClosed() { - return !isActive; - } - - @Override - public int hashCode() { - return accountNumber.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof CheckingAccount other) { - return accountNumber.equals(other.accountNumber); - } - return false; + super(accountNumber, owners, initialBalance); } @Override public String toString() { return "CheckingAccount{" + "accountNumber='" - + accountNumber + + getAccountNumber() + '\'' + ", balance=" + balance + ", isActive=" - + isActive + + isActive() + '}'; } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java index 0554df482..435659212 100644 --- a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/SavingsAccount.java @@ -2,18 +2,8 @@ import java.util.Set; -public class SavingsAccount extends CheckingAccount { +public class SavingsAccount extends Account { public SavingsAccount(String accountNumber, Set owners, double initialBalance) { super(accountNumber, owners, initialBalance); } - - @Override - public void withdraw(double amount) { - String method = null; - if ("check".equalsIgnoreCase(method)) { - throw new UnsupportedOperationException("Cannot withdraw checks from the savings account"); - } - - this.balance += amount; - } } diff --git a/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/IllegalStatementException.java b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/IllegalStatementException.java new file mode 100644 index 000000000..7a8737a2a --- /dev/null +++ b/lesson_17/bank/bank_app/src/main/java/com/codedifferently/lesson17/bank/exceptions/IllegalStatementException.java @@ -0,0 +1,10 @@ +package com.codedifferently.lesson17.bank.exceptions; + +public class IllegalStatementException extends RuntimeException { + + public IllegalStatementException() {} + + public IllegalStatementException(String message) { + super(message); + } +}