Skip to content

Feat: adds amiyah's lesson 17 Bank ATM enhancements #543

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

Closed
wants to merge 110 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
110 commits
Select commit Hold shift + click to select a range
8cc92d0
Create README.md
AmiyahJo Sep 24, 2024
50b1861
Delete lesson_00/amiyahjones/README.md
AmiyahJo Sep 24, 2024
27d57c0
Merge branch 'code-differently:main' into main
AmiyahJo Sep 25, 2024
fa3c700
Merge branch 'code-differently:main' into main
AmiyahJo Sep 26, 2024
7c2d053
Merge branch 'code-differently:main' into main
AmiyahJo Sep 26, 2024
faedd1b
Merge branch 'code-differently:main' into main
AmiyahJo Sep 26, 2024
19a4187
Merge branch 'code-differently:main' into main
AmiyahJo Sep 26, 2024
7711266
Merge branch 'code-differently:main' into main
AmiyahJo Sep 27, 2024
9a10c4c
Merge branch 'code-differently:main' into main
AmiyahJo Sep 27, 2024
3ea50c4
Merge branch 'code-differently:main' into main
AmiyahJo Sep 27, 2024
d7b772d
Merge branch 'code-differently:main' into main
AmiyahJo Sep 27, 2024
de46b67
Merge branch 'code-differently:main' into main
AmiyahJo Sep 27, 2024
b891561
Merge branch 'code-differently:main' into main
AmiyahJo Sep 28, 2024
7c9f2db
Merge branch 'code-differently:main' into main
AmiyahJo Sep 30, 2024
ff3ba35
Merge branch 'code-differently:main' into main
AmiyahJo Sep 30, 2024
457feea
Merge branch 'code-differently:main' into main
AmiyahJo Sep 30, 2024
5868f9d
Merge branch 'code-differently:main' into main
AmiyahJo Oct 1, 2024
28eacd4
Merge branch 'code-differently:main' into main
AmiyahJo Oct 1, 2024
bca4933
Merge branch 'code-differently:main' into main
AmiyahJo Oct 1, 2024
9ff0f9e
Merge branch 'code-differently:main' into main
AmiyahJo Oct 1, 2024
8d02849
Merge branch 'code-differently:main' into main
AmiyahJo Oct 2, 2024
6dd3a43
Merge branch 'code-differently:main' into main
AmiyahJo Oct 2, 2024
95f56a5
Merge branch 'code-differently:main' into main
AmiyahJo Oct 3, 2024
0f4dbac
Merge branch 'code-differently:main' into main
AmiyahJo Oct 4, 2024
a3b9984
Merge branch 'code-differently:main' into main
AmiyahJo Oct 4, 2024
54cd199
Merge branch 'code-differently:main' into main
AmiyahJo Oct 4, 2024
edbe7c0
Merge branch 'code-differently:main' into main
AmiyahJo Oct 4, 2024
7f0a084
Merge branch 'code-differently:main' into main
AmiyahJo Oct 7, 2024
a905b74
Merge branch 'code-differently:main' into main
AmiyahJo Oct 8, 2024
2d69531
Merge branch 'code-differently:main' into main
AmiyahJo Oct 8, 2024
df48fbd
Merge branch 'code-differently:main' into main
AmiyahJo Oct 8, 2024
c972d14
Merge branch 'code-differently:main' into main
AmiyahJo Oct 9, 2024
bc3907c
Merge branch 'code-differently:main' into main
AmiyahJo Oct 9, 2024
c3eabbb
Merge branch 'code-differently:main' into main
AmiyahJo Oct 9, 2024
9fff7d0
Merge branch 'code-differently:main' into main
AmiyahJo Oct 11, 2024
4c57926
Merge branch 'code-differently:main' into main
AmiyahJo Oct 11, 2024
8dd5d42
Merge branch 'code-differently:main' into main
AmiyahJo Oct 14, 2024
18f65ee
Merge branch 'code-differently:main' into main
AmiyahJo Oct 14, 2024
2dd1645
Merge branch 'code-differently:main' into main
AmiyahJo Oct 14, 2024
0de8601
Merge branch 'code-differently:main' into main
AmiyahJo Oct 14, 2024
85dd364
Merge branch 'code-differently:main' into main
AmiyahJo Oct 16, 2024
0afda26
Merge branch 'code-differently:main' into main
AmiyahJo Oct 16, 2024
f31e8d9
Merge branch 'code-differently:main' into main
AmiyahJo Oct 16, 2024
3e24069
Merge branch 'code-differently:main' into main
AmiyahJo Oct 17, 2024
8600f6c
Merge branch 'code-differently:main' into main
AmiyahJo Oct 17, 2024
563b076
Merge branch 'code-differently:main' into main
AmiyahJo Oct 18, 2024
b01a324
Merge branch 'code-differently:main' into main
AmiyahJo Oct 18, 2024
697a72d
Merge branch 'code-differently:main' into main
AmiyahJo Oct 21, 2024
92891f6
Merge branch 'code-differently:main' into main
AmiyahJo Oct 21, 2024
17fdee5
Merge branch 'code-differently:main' into main
AmiyahJo Oct 22, 2024
cf7e6f2
Merge branch 'code-differently:main' into main
AmiyahJo Oct 23, 2024
a131bdc
Merge branch 'code-differently:main' into main
AmiyahJo Oct 23, 2024
c46d32f
Merge branch 'code-differently:main' into main
AmiyahJo Oct 24, 2024
651fa01
Merge branch 'code-differently:main' into main
AmiyahJo Oct 26, 2024
e075fb7
Merge branch 'code-differently:main' into main
AmiyahJo Oct 27, 2024
ec7c3d1
Merge branch 'code-differently:main' into main
AmiyahJo Oct 28, 2024
186c10e
Merge branch 'code-differently:main' into main
AmiyahJo Oct 29, 2024
e13bae6
Merge remote-tracking branch 'refs/remotes/origin/main'
Oct 30, 2024
8f999c6
Merge remote-tracking branch 'refs/remotes/origin/main'
Oct 30, 2024
af811ee
Merge branch 'code-differently:main' into main
AmiyahJo Nov 1, 2024
8676657
Merge branch 'code-differently:main' into main
AmiyahJo Nov 1, 2024
d334d62
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 3, 2024
d4730b1
feat: adds template code (checking account) to savings account for re…
Nov 3, 2024
9a1f465
feat: adds savings account class and test implementations
Nov 3, 2024
bb54a4d
fix: withdraw_withNegativeAMount thrownby
Nov 3, 2024
db22829
fix: used 'extends' method for savingsAccoint
Nov 3, 2024
1e7b59e
feat: adds business checking account
Nov 3, 2024
010b8b6
feat: adds AuditLog and MoneyOrder classes
Nov 3, 2024
86c7783
feat: adds account interface , checkNotAllowedException , etc.
Nov 4, 2024
fbf2e14
mv: moves CheckNotAllowedException to the exceptions folder
Nov 4, 2024
48839ea
rm: remove checkNotAllowedException from the test/java/bank pathway
Nov 4, 2024
1ab73e9
feat: adds exception import to savings account
Nov 4, 2024
a6de887
fix: businessCheckingAccount allows the name of the business to be in…
Nov 4, 2024
c5edbfe
mv: moves all created class files to 'java/bank' folder
Nov 4, 2024
e8f7503
feat: adds business checking account boolean to customer, and excepti…
Nov 4, 2024
9746c24
feat: adds BusinessCheckingAccount tests
Nov 4, 2024
d306393
feat: adds testGetBusinessName
Nov 4, 2024
b39c805
feat: adds savinngsAccount overide methods
Nov 4, 2024
704b748
fix: customer java isBusiness boolean included , removes for loop of …
Nov 4, 2024
72243fc
rm: bankAtm.java business account enhancement
Nov 4, 2024
576826b
feat: adds getBusinessName getter
Nov 4, 2024
e55cbe2
feat: adds details to AuditLog , adds auditlog records to bankATM , a…
Nov 4, 2024
bd2aab0
fix: boolean parameter for customers
Nov 4, 2024
71e7dd2
feat: adds boolean businessCheckingAccount in the method 'addAccount'
Nov 4, 2024
f6868a2
feat: adds testBusinessCheckingAccount
Nov 4, 2024
5fa42dc
fix: changes the constructor code
Nov 5, 2024
fd08860
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 5, 2024
d8ebfc0
rm: testCreateCheckingWIthoutBusinessAccount
Nov 5, 2024
6446892
feat: adds testAddBusinessAccountWIthNoBusinessOwner
Nov 5, 2024
d98f0f7
rm: BusinessCheckingAccountTest
Nov 5, 2024
24ed85b
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 5, 2024
af06127
feat: adds savings account test
Nov 5, 2024
f3df9ad
feat: adds details to moneyOrder
Nov 5, 2024
e189f72
feat: adds accountNumber tracked in audit log and money order records…
Nov 5, 2024
02c2bf6
feat: adds moneyOrderTest
Nov 5, 2024
2a62bae
chore: spotless apply
Nov 5, 2024
5ae98c4
fix: bankAtm add arguments to auditLog
Nov 5, 2024
95bf7a1
chore: spotlessApply to BankAtm
Nov 5, 2024
8e82abd
chore: spotless apply + adds java documentation
Nov 5, 2024
2727d7f
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 6, 2024
b79b7a9
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 11, 2024
30fa61b
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 13, 2024
308e521
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 13, 2024
71b417f
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 14, 2024
2e7a7bf
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 18, 2024
8f8a444
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 19, 2024
6a2c545
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 20, 2024
227f49c
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 20, 2024
efc3061
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 20, 2024
21ac449
Merge branch 'code-differently:main' into feature/lesson_17
AmiyahJo Nov 22, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.codedifferently.lesson17.bank;

public interface Account {
void deposit(double account);

void withdraw(double amount);

double getBalance();

String getAccountNumber();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.codedifferently.lesson17.bank;

import java.util.ArrayList;
import java.util.List;

/** Records and prints transaction logs. */
public class AuditLog {
private final List<String> logEntries;

/** Creates a new, empty audit log. */
public AuditLog() {
logEntries = new ArrayList<>();
}

/**
* Adds a transaction entry to the log and prints it.
*
* @param accountNumber The account number involved.
* @param message A message describing the transaction.
* @param amount The amount of money in the transaction.
* @param type The type of transaction (e.g., Deposit, Withdrawal).
*/
public void logTransaction(String accountNumber, String message, double amount, String type) {
String logEntry =
String.format(
"Account: %s | Transaction: %s | Amount: %.2f | Type: %s",
accountNumber, message, amount, type);
logEntries.add(logEntry);
System.out.println(logEntry);
}

/**
* Returns all the transaction logs.
*
* @return A list of all log entries.
*/
public List<String> getLogEntries() {
return logEntries;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,27 @@ public class BankAtm {

private final Map<UUID, Customer> customerById = new HashMap<>();
private final Map<String, CheckingAccount> accountByNumber = new HashMap<>();
private final AuditLog auditLog = new AuditLog();

/**
* Adds a checking account to the bank.
* Adds a checking account to the bank. If the account is a BusinessCheckingAccount, it ensures
* that at least one of the account owners is a business.
*
* @param account The account to add.
* @throws IllegalArgumentException if the account is a BusinessCheckingAccount and none of its
* owners are business.
*/
public void addAccount(CheckingAccount account) {
if (account instanceof BusinessCheckingAccount) {
boolean hasBusinessAccount =
account.getOwners().stream().anyMatch(owner -> owner.isBusiness());

if (!hasBusinessAccount) {
throw new IllegalArgumentException(
"At least one owning account must be a business account.");
}
}

accountByNumber.put(account.getAccountNumber(), account);
account
.getOwners()
Expand Down Expand Up @@ -48,6 +62,8 @@ public Set<CheckingAccount> findAccountsByCustomerId(UUID customerId) {
public void depositFunds(String accountNumber, double amount) {
CheckingAccount account = getAccountOrThrow(accountNumber);
account.deposit(amount);
auditLog.logTransaction(
"Deposited to account: " + accountNumber, accountNumber, amount, "Deposit");
}

/**
Expand All @@ -59,6 +75,11 @@ public void depositFunds(String accountNumber, double amount) {
public void depositFunds(String accountNumber, Check check) {
CheckingAccount account = getAccountOrThrow(accountNumber);
check.depositFunds(account);
auditLog.logTransaction(
"Deposited check to account: " + accountNumber,
accountNumber,
check.getAmount(),
"Check Deposit");
}

/**
Expand All @@ -70,6 +91,8 @@ public void depositFunds(String accountNumber, Check check) {
public void withdrawFunds(String accountNumber, double amount) {
CheckingAccount account = getAccountOrThrow(accountNumber);
account.withdraw(amount);
auditLog.logTransaction(
"Withdrew from account: " + accountNumber, accountNumber, amount, "Withdrawal");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.codedifferently.lesson17.bank;

import java.util.Set;

public class BusinessCheckingAccount extends CheckingAccount {
private final String businessName;

/**
* Creates a new business checking account.
*
* @param accountNumber The account number.
* @param owners The owners of the account.
* @param businessName The name of the business.
* @param initialBalance The initial balance of the account.
* @throws IllegalArgumentException if no business owner is provided.
*/
public BusinessCheckingAccount(
String accountNumber, Set<Customer> owners, String businessName, double initialBalance) {
super(accountNumber, owners, initialBalance);
this.businessName = businessName;
}

public String getBusinessName() {
return businessName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ public void depositFunds(CheckingAccount toAccount) {
voidCheck();
}

public double getAmount() {
return amount;
}

@Override
public int hashCode() {
return checkNumber.hashCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ public class Customer {
private final UUID id;
private final String name;
private final Set<CheckingAccount> accounts = new HashSet<>();
private final 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) {
public Customer(UUID id, String name, boolean isBusiness) {
this.id = id;
this.name = name;
this.isBusiness = isBusiness;
}

/**
Expand All @@ -40,6 +42,10 @@ public String getName() {
return name;
}

public boolean isBusiness() {
return isBusiness;
}

/**
* Adds a checking account to the customer.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.codedifferently.lesson17.bank;

/** Represents a Money Order transaction. */
public class MoneyOrder {
private final CheckingAccount sourceAccount;
private final double amount;
private AuditLog auditLog;

/**
* Creates a new money order transaction by withdrawing the specified amount from the source
* account. The transaction is logged for auditing purposes.
*
* @param sourceAccount The account from which funds will be withdrawn.
* @param amount The amount to withdraw and transfer in the money order.
* @param auditLog The audit log used to record the transaction details.
*/
public MoneyOrder(CheckingAccount sourceAccount, double amount, AuditLog auditLog) {
this.sourceAccount = sourceAccount;
this.amount = amount;
this.auditLog = auditLog;

sourceAccount.withdraw(amount);

auditLog.logTransaction(
sourceAccount.getAccountNumber(), "MoneyOrder created", -amount, "MoneyOrder");
}

/**
* Gets the source account from which the money was withdrawn.
*
* @return The source checking account.
*/
public CheckingAccount getSourceAccount() {
return sourceAccount;
}

/**
* Gets the amount of money involved in the Money Order transaction.
*
* @return The amount of the money order.
*/
public double getAmount() {
return amount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.codedifferently.lesson17.bank;

import com.codedifferently.lesson17.bank.exceptions.CheckNotAllowedException;
import java.util.Set;

/** Represents a savings account. */
public class SavingsAccount extends CheckingAccount {

/**
* 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. If it's negative, it will be set to
* zero.
*/
public SavingsAccount(String accountNumber, Set<Customer> owners, double initialBalance) {
super(accountNumber, owners, Math.max(initialBalance, 0));
}

/**
* Deposits funds into the savings account.
*
* @param amount The amount to deposit.
*/
@Override
public void deposit(double amount) {
super.deposit(amount);
}

/**
* Withdraws funds from the savings account.
*
* @param amount The amount to withdraw.
*/
@Override
public void withdraw(double amount) {
super.withdraw(amount);
}

/**
* Throws an exception because savings accounts cannot write checks.
*
* @param amount The amount to write a check for.
* @throws CheckNotAllowedException if attempting to write a check.
*/
public void writeCheck(double amount) {
throw new CheckNotAllowedException("Savings account cannot write checks");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.codedifferently.lesson17.bank.exceptions;

public class CheckNotAllowedException extends RuntimeException {
public CheckNotAllowedException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.codedifferently.lesson17.bank.exceptions.AccountNotFoundException;
import com.codedifferently.lesson17.bank.exceptions.CheckVoidedException;
Expand All @@ -21,8 +22,8 @@ class BankAtmTest {
@BeforeEach
void setUp() {
classUnderTest = new BankAtm();
customer1 = new Customer(UUID.randomUUID(), "John Doe");
customer2 = new Customer(UUID.randomUUID(), "Jane Smith");
customer1 = new Customer(UUID.randomUUID(), "John Doe", true);
customer2 = new Customer(UUID.randomUUID(), "Jane Smith", true);
account1 = new CheckingAccount("123456789", Set.of(customer1), 100.0);
account2 = new CheckingAccount("987654321", Set.of(customer1, customer2), 200.0);
customer1.addAccount(account1);
Expand All @@ -35,7 +36,7 @@ void setUp() {
@Test
void testAddAccount() {
// Arrange
Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson");
Customer customer3 = new Customer(UUID.randomUUID(), "Alice Johnson", true);
CheckingAccount account3 = new CheckingAccount("555555555", Set.of(customer3), 300.0);
customer3.addAccount(account3);

Expand All @@ -47,6 +48,25 @@ void testAddAccount() {
assertThat(accounts).containsOnly(account3);
}

@Test
void testAddBusinessAccountWithNoBusinessOwner() {
// Arrange
Customer regularCustomer = new Customer(UUID.randomUUID(), "Bob's Bakery", false);
CheckingAccount businessAccount =
new BusinessCheckingAccount("666666666", Set.of(regularCustomer), "name", 500.0);

// Act & Assert
IllegalArgumentException thrown =
assertThrows(
IllegalArgumentException.class,
() -> {
classUnderTest.addAccount(businessAccount);
});

assertThat(thrown)
.hasMessageContaining("At least one owning account must be a business account.");
}

@Test
void testFindAccountsByCustomerId() {
// Act
Expand Down Expand Up @@ -107,4 +127,16 @@ void testWithdrawFunds_AccountNotFound() {
.isThrownBy(() -> classUnderTest.withdrawFunds(nonExistingAccountNumber, 50.0))
.withMessage("Account not found");
}

@Test
void testGetBusinessName() {
// Arrange
Customer businessOwner = new Customer(UUID.randomUUID(), "Business Owner", true);
Set<Customer> owners = Set.of(businessOwner);
BusinessCheckingAccount businessAccount =
new BusinessCheckingAccount("123456789", owners, "Business Inc.", 1000.0);

// Act & Assert
assertThat(businessAccount.getBusinessName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,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);
}

Expand Down
Loading