11package com .codedifferently .lesson17 .bank ;
22
3+ import com .codedifferently .lesson17 .bank .audit .TransactionObserver ;
34import com .codedifferently .lesson17 .bank .exceptions .AccountNotFoundException ;
5+ import java .util .ArrayList ;
46import java .util .HashMap ;
7+ import java .util .List ;
58import java .util .Map ;
69import java .util .Set ;
710import java .util .UUID ;
811
9- /** Represents a bank ATM. */
12+ /** Represents a bank ATM that supports multiple account types and audit logging . */
1013public class BankAtm {
1114
1215 private final Map <UUID , Customer > customerById = new HashMap <>();
13- private final Map <String , CheckingAccount > accountByNumber = new HashMap <>();
16+ private final Map <String , Account > accountByNumber = new HashMap <>();
17+ private final List <TransactionObserver > observers = new ArrayList <>();
18+
19+ /** Adds a transaction observer for audit logging. */
20+ public void addObserver (TransactionObserver observer ) {
21+ if (observer != null && !observers .contains (observer )) {
22+ observers .add (observer );
23+ }
24+ }
25+
26+ /** Removes a transaction observer. */
27+ public void removeObserver (TransactionObserver observer ) {
28+ observers .remove (observer );
29+ }
30+
31+ /** Notifies all observers about a transaction. */
32+ private void notifyObservers (
33+ String transactionType , double amount , String accountNumber , String description ) {
34+ for (TransactionObserver observer : observers ) {
35+ observer .onTransaction (transactionType , amount , accountNumber , description );
36+ }
37+ }
1438
1539 /**
16- * Adds a checking account to the bank.
40+ * Adds an account to the bank. This method now accepts any Account type, supporting both
41+ * CheckingAccount and SavingsAccount while maintaining backward compatibility.
1742 *
1843 * @param account The account to add.
1944 */
@@ -27,6 +52,22 @@ public void addAccount(CheckingAccount account) {
2752 });
2853 }
2954
55+ /**
56+ * Adds a savings account to the bank. This overloaded method allows adding SavingsAccount objects
57+ * while maintaining the same public interface.
58+ *
59+ * @param account The savings account to add.
60+ */
61+ public void addAccount (SavingsAccount account ) {
62+ accountByNumber .put (account .getAccountNumber (), account );
63+ account
64+ .getOwners ()
65+ .forEach (
66+ owner -> {
67+ customerById .put (owner .getId (), owner );
68+ });
69+ }
70+
3071 /**
3172 * Finds all accounts owned by a customer.
3273 *
@@ -40,36 +81,68 @@ public Set<CheckingAccount> findAccountsByCustomerId(UUID customerId) {
4081 }
4182
4283 /**
43- * Deposits funds into an account.
84+ * Deposits funds into an account using cash .
4485 *
4586 * @param accountNumber The account number.
4687 * @param amount The amount to deposit.
4788 */
4889 public void depositFunds (String accountNumber , double amount ) {
49- CheckingAccount account = getAccountOrThrow (accountNumber );
50- account .deposit (amount );
90+ try {
91+ Account account = getAccountOrThrow (accountNumber );
92+ account .deposit (amount );
93+ notifyObservers ("CREDIT" , amount , accountNumber , "Cash deposit" );
94+ } catch (Exception e ) {
95+ notifyObservers ("CREDIT" , amount , accountNumber , "Failed: " + e .getMessage ());
96+ throw e ;
97+ }
5198 }
5299
53100 /**
54- * Deposits funds into an account using a check.
101+ * Deposits funds into an account using a check. This method validates that the account supports
102+ * check transactions.
55103 *
56104 * @param accountNumber The account number.
57105 * @param check The check to deposit.
106+ * @throws IllegalStateException if the account doesn't support check transactions.
58107 */
59108 public void depositFunds (String accountNumber , Check check ) {
60- CheckingAccount account = getAccountOrThrow (accountNumber );
61- check .depositFunds (account );
109+ try {
110+ Account account = getAccountOrThrow (accountNumber );
111+
112+ // Check if account supports check transactions (Open/Closed Principle)
113+ if (account instanceof SavingsAccount savingsAccount
114+ && !savingsAccount .supportsCheckTransactions ()) {
115+ throw new IllegalStateException ("Savings accounts do not support check transactions" );
116+ }
117+
118+ // For checking accounts or accounts that support checks, proceed with deposit
119+ if (account instanceof CheckingAccount checkingAccount ) {
120+ check .depositFunds (checkingAccount );
121+ notifyObservers ("CREDIT" , 0.0 , accountNumber , "Check deposit: " + check .toString ());
122+ } else {
123+ throw new IllegalStateException ("Account type does not support check deposits" );
124+ }
125+ } catch (Exception e ) {
126+ notifyObservers ("CREDIT" , 0.0 , accountNumber , "Failed check deposit: " + e .getMessage ());
127+ throw e ;
128+ }
62129 }
63130
64131 /**
65- * Withdraws funds from an account.
132+ * Withdraws funds from an account using cash .
66133 *
67- * @param accountNumber
68- * @param amount
134+ * @param accountNumber The account number.
135+ * @param amount The amount to withdraw.
69136 */
70137 public void withdrawFunds (String accountNumber , double amount ) {
71- CheckingAccount account = getAccountOrThrow (accountNumber );
72- account .withdraw (amount );
138+ try {
139+ Account account = getAccountOrThrow (accountNumber );
140+ account .withdraw (amount );
141+ notifyObservers ("DEBIT" , amount , accountNumber , "Cash withdrawal" );
142+ } catch (Exception e ) {
143+ notifyObservers ("DEBIT" , amount , accountNumber , "Failed: " + e .getMessage ());
144+ throw e ;
145+ }
73146 }
74147
75148 /**
@@ -78,8 +151,8 @@ public void withdrawFunds(String accountNumber, double amount) {
78151 * @param accountNumber The account number.
79152 * @return The account.
80153 */
81- private CheckingAccount getAccountOrThrow (String accountNumber ) {
82- CheckingAccount account = accountByNumber .get (accountNumber );
154+ private Account getAccountOrThrow (String accountNumber ) {
155+ Account account = accountByNumber .get (accountNumber );
83156 if (account == null || account .isClosed ()) {
84157 throw new AccountNotFoundException ("Account not found" );
85158 }
0 commit comments