diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 942940a..2cb7a09 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -1,7 +1,10 @@ - + + + + @@ -156,8 +162,8 @@ - @@ -272,7 +278,7 @@ - + @@ -299,7 +305,59 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -719,26 +809,47 @@ - + + + + + + + - + - - + + + + + + + + + + + + + + + + + - - + @@ -750,13 +861,13 @@ - + - + @@ -779,7 +890,9 @@ - + + @@ -787,6 +900,16 @@ + + + + + + + + + + @@ -795,15 +918,17 @@ - + - - - + + + + + - + @@ -811,18 +936,18 @@ - + - + - + - - + + @@ -835,28 +960,26 @@ - + - - - - - + + + - + - + - - + + diff --git a/AccessControlLab.png b/AccessControlLab.png new file mode 100644 index 0000000..5b0f8b3 Binary files /dev/null and b/AccessControlLab.png differ diff --git a/src/main/java/squier/john/accessControl/ApprovalStatus.java b/src/main/java/squier/john/accessControl/ApprovalStatus.java index 391c8c4..f19a6b8 100644 --- a/src/main/java/squier/john/accessControl/ApprovalStatus.java +++ b/src/main/java/squier/john/accessControl/ApprovalStatus.java @@ -3,4 +3,4 @@ /** * Created by johnsquier on 1/17/17. */ -public enum ApprovalStatus {APPROVED, NOT_APPROVED, ZERO_TRANSACTION;} +public enum ApprovalStatus {APPROVED, NOT_APPROVED, ZERO_TRANSACTION, CANT_COMPLETE_DUE_TO_ACCT_STATUS;} diff --git a/src/main/java/squier/john/accessControl/BankAccount.java b/src/main/java/squier/john/accessControl/BankAccount.java index 2ddd6ca..9dec117 100644 --- a/src/main/java/squier/john/accessControl/BankAccount.java +++ b/src/main/java/squier/john/accessControl/BankAccount.java @@ -9,7 +9,7 @@ public class BankAccount { private BankAccountType accountType; private int accountNumber; - private static int nextAccoutNumber = 1; + private static int nextAccountNumber = 1; private double balance; private String accountHoldersName; private double interestRate; @@ -20,7 +20,7 @@ public class BankAccount { public BankAccount(BankAccountType accountType, double balance, String accountHoldersName, double interestRate, BankAccountStatus accountStatus, OverdraftProtection overdraftProtection) { this.accountType = accountType; - accountNumber = nextAccoutNumber++; + accountNumber = nextAccountNumber++; this.balance = balance; this.accountHoldersName = accountHoldersName; this.interestRate = interestRate; @@ -31,7 +31,6 @@ public BankAccount(BankAccountType accountType, double balance, String accountHo public Double getBalance() { if ( accountStatus.equals(BankAccountStatus.OFAC_FROZEN) ) { - // do nothing probably throw an expection at some point return null; } else { @@ -39,22 +38,167 @@ public Double getBalance() { } } + public String getAccountHoldersName() { + return accountHoldersName; + } + + public void setAccountHoldersName(String newName) { + if ( accountStatus.equals(BankAccountStatus.OPEN) ) { + accountHoldersName = newName; + + transactionRecord.add(new BankAccountTransaction(TransactionType.NAME_CHANGE, 0.0, + accountStatus, this.accountHoldersName)); + + return; + } + + public BankAccountStatus getAccountStatus() { + return accountStatus; + } + + public void setAccountStatus(BankAccountStatus accountStatus) { + if ( isAccountOpenOrFrozen() ) { + // check balance if trying to close + if ( isNewAccountStatusClose(accountStatus) ) { + if ( this.balance == 0.0 ) { + this.accountStatus = accountStatus; + + transactionRecord.add(new BankAccountTransaction(TransactionType.STATUS_CHANGE, 0.0, + this.accountStatus, accountHoldersName)); + } + } + else { + this.accountStatus = accountStatus; + + transactionRecord.add(new BankAccountTransaction(TransactionType.STATUS_CHANGE, 0.0, + this.accountStatus, accountHoldersName)); + } + } + + return; + } + + private boolean isAccountOpenOrFrozen() { + return !accountStatus.equals(BankAccountStatus.CLOSED); + } + + private boolean isNewAccountStatusClose(BankAccountStatus newStatus) { + return newStatus.equals(BankAccountStatus.CLOSED); + } + public ApprovalStatus updateBalanceWithCreditOrDebit(double amount) { + if ( accountStatus.equals(BankAccountStatus.OPEN) ) { + + if ( overdraftProtection.equals(OverdraftProtection.ENABLED) ) { + if ( isTransactionAnOverDraft(amount) ) { + return ApprovalStatus.NOT_APPROVED; + } + } + if ( amount > 0.0 ) { - credit(amount); + return credit(amount); + } + else if ( amount < 0.0 ) { + return debit(amount); } else { - debit(amount); + return ApprovalStatus.ZERO_TRANSACTION; + } + } + else { + return ApprovalStatus.CANT_COMPLETE_DUE_TO_ACCT_STATUS; + } + } + + private ApprovalStatus credit(double amountToCredit) { + Double previousBalance = getBalance(); + balance += amountToCredit; + + // check if balance updated + if ( (previousBalance + amountToCredit) == getBalance() ) { + // create new transaction record and add to list + transactionRecord.add(new BankAccountTransaction(TransactionType.DEPOSIT, + amountToCredit, accountStatus, accountHoldersName)); + return ApprovalStatus.APPROVED; + } + else { + return ApprovalStatus.NOT_APPROVED; + } + } + + private ApprovalStatus debit(double amountToDebit) { + Double previousBalance = getBalance(); + balance += amountToDebit; + + if ( (previousBalance - amountToDebit) == getBalance() ) { + // create new transaction record + transactionRecord.add(new BankAccountTransaction(TransactionType.WITHDRAWL, amountToDebit, + accountStatus, accountHoldersName)); + return ApprovalStatus.APPROVED; + } + else { + return ApprovalStatus.NOT_APPROVED; + } + } + + + private boolean isTransactionAnOverDraft(double amount) { + return (Math.abs(amount) > this.getBalance()); + } + + // refactor this and transferBalanceTo, gotta be some reapeat code + public ApprovalStatus transferBalanceFrom(BankAccount transferFrom, double amountToTransfer) { + if ( bothAccountsHaveSameOwner(this, transferFrom) ) { + + if ( doesAccountHaveSufficientBalance(transferFrom, amountToTransfer) ) { + ApprovalStatus debitApproval = transferFrom.updateBalanceWithCreditOrDebit(-amountToTransfer); + ApprovalStatus creditApproval = this.updateBalanceWithCreditOrDebit(amountToTransfer); + + transactionRecord.add(new BankAccountTransaction(TransactionType.TRANSFER, amountToTransfer, + accountStatus, accountHoldersName)); + + // pull out into check approvals method + if ( (debitApproval.equals(ApprovalStatus.APPROVED)) + && creditApproval.equals(ApprovalStatus.APPROVED) ) { + return ApprovalStatus.APPROVED; + } } } + + return ApprovalStatus.NOT_APPROVED; } - private ApprovalStatus credit(double amount) { + public ApprovalStatus transferBalanceTo(BankAccount transferTo, double amountToTransfer) { + // check if both accts have the same owener + if ( bothAccountsHaveSameOwner(this, transferTo) ) { + + // check if from has enough money + if (doesAccountHaveSufficientBalance(this, amountToTransfer)) { + // do the transfer + ApprovalStatus debitApproval = this.updateBalanceWithCreditOrDebit(-amountToTransfer); + ApprovalStatus creditApproval = transferTo.updateBalanceWithCreditOrDebit(amountToTransfer); + + transactionRecord.add(new BankAccountTransaction(TransactionType.TRANSFER, amountToTransfer, + accountStatus, accountHoldersName)); + + + if ((debitApproval.equals(ApprovalStatus.APPROVED)) + && creditApproval.equals(ApprovalStatus.APPROVED)) { + return ApprovalStatus.APPROVED; + } + } + } + + return ApprovalStatus.NOT_APPROVED; } - private ApprovalStatus debit(double amount) { + private boolean bothAccountsHaveSameOwner(BankAccount transferFrom, BankAccount transferTo) { + return transferFrom.getAccountHoldersName().equals(transferTo.accountHoldersName); + } + private boolean doesAccountHaveSufficientBalance(BankAccount acct, double amount) { + return acct.getBalance() >= amount; } } diff --git a/src/main/java/squier/john/accessControl/BankAccountTransaction.java b/src/main/java/squier/john/accessControl/BankAccountTransaction.java index eb0b243..ac50910 100644 --- a/src/main/java/squier/john/accessControl/BankAccountTransaction.java +++ b/src/main/java/squier/john/accessControl/BankAccountTransaction.java @@ -5,7 +5,7 @@ */ public class BankAccountTransaction { private TransactionType transactionType; - private double transactionAmount; + private Double transactionAmount; private BankAccountStatus newStatus; private String newName; @@ -16,4 +16,9 @@ public BankAccountTransaction(TransactionType transactionType, double transactio this.newStatus = newStatus; this.newName = newName; } + + public TransactionType getTransactionType() { return transactionType; } + public Double getTransactionAmount() { return transactionAmount; } + public BankAccountStatus getBankAccountStatus() { return newStatus; } + public String getName() { return newName} } diff --git a/src/test/java/squier/john/accessControl/BankAccountTest.java b/src/test/java/squier/john/accessControl/BankAccountTest.java index 8967c33..c92c2fc 100644 --- a/src/test/java/squier/john/accessControl/BankAccountTest.java +++ b/src/test/java/squier/john/accessControl/BankAccountTest.java @@ -29,19 +29,57 @@ public void getBalanceAccountFrozenTest() { bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, "John", 10.0, BankAccountStatus.OFAC_FROZEN, OverdraftProtection.ENABLED); - Double expected = null; + + // using null to indicate frozen acct status Double actual = bankAccount.getBalance(); - Assert.assertEquals(expected, actual, delta); + Assert.assertNull(actual); } @Test - public void updateBalanceAccountClosedTest() { + public void getAccountHoldersNameTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OFAC_FROZEN, + OverdraftProtection.ENABLED); + + String expected = "John"; + String actual = bankAccount.getAccountHoldersName(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setAccountHoldersNameOpenTest() { bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, "John", 10.0, BankAccountStatus.OPEN, OverdraftProtection.ENABLED); + + String expected = "Bob"; + bankAccount.setAccountHoldersName("Bob"); + String actual = bankAccount.getAccountHoldersName(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setAccountHoldersNameClosedTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.CLOSED, + OverdraftProtection.ENABLED); + + String expected = "John"; + bankAccount.setAccountHoldersName("Bob"); + String actual = bankAccount.getAccountHoldersName(); + Assert.assertEquals(expected, actual); + } + + @Test + public void updateBalanceAccountClosedTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.CLOSED, + OverdraftProtection.ENABLED); + Double expected = 100.0; bankAccount.updateBalanceWithCreditOrDebit(5.0); Double actual = bankAccount.getBalance(); + Assert.assertEquals(expected, actual, delta); } @Test @@ -49,9 +87,220 @@ public void updateBalancePositiveTest() { bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, "John", 10.0, BankAccountStatus.OPEN, OverdraftProtection.ENABLED); + Double expected = 200.0; bankAccount.updateBalanceWithCreditOrDebit(100.0); Double actual = bankAccount.getBalance(); + Assert.assertEquals(expected, actual, delta); + } + + @Test + public void updateBalanceNegativeTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + Double expected = 50.0; + bankAccount.updateBalanceWithCreditOrDebit(-50.0); + Double actual = bankAccount.getBalance(); + Assert.assertEquals(expected, actual, delta); + } + + @Test + public void transferBalanceFromTestBothEndAboveZeroTest() { + BankAccount transferFrom = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + BankAccount transferTo = new BankAccount(BankAccountType.CHECKING, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + transferTo.transferBalanceFrom(transferFrom, 50.0); + + Double[] expected = {150.0, 50.0}; + Double[] actual = {transferTo.getBalance(), transferFrom.getBalance()}; + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void transferBalanceToTestBothEndAboveZeroTest() { + BankAccount transferFrom = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + BankAccount transferTo = new BankAccount(BankAccountType.CHECKING, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + transferFrom.transferBalanceTo(transferTo, 50.0); + + Double[] expected = {150.0, 50.0}; + Double[] actual = {transferTo.getBalance(), transferFrom.getBalance()}; + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void transferBalanceFromTestNotEnoughInFromTest() { + BankAccount transferFrom = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + BankAccount transferTo = new BankAccount(BankAccountType.CHECKING, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + transferTo.transferBalanceFrom(transferFrom, 500.0); + + Double[] expected = {100.0, 100.0}; + Double[] actual = {transferTo.getBalance(), transferFrom.getBalance()}; + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void transferBalanceToTestNotEnoughInFromTest() { + BankAccount transferFrom = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + BankAccount transferTo = new BankAccount(BankAccountType.CHECKING, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + transferFrom.transferBalanceTo(transferTo, 500.0); + + Double[] expected = {100.0, 100.0}; + Double[] actual = {transferTo.getBalance(), transferFrom.getBalance()}; + Assert.assertArrayEquals(expected, actual); + } + + @Test + public void overdrawWithProtectionOnTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + Double expected = 100.0; + bankAccount.updateBalanceWithCreditOrDebit(-500.0); + Double actual = bankAccount.getBalance(); + + Assert.assertEquals(expected, actual); + } + + @Test + public void overdrawWithProtectOffTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.DISABLED); + + Double expected = -400.0; + bankAccount.updateBalanceWithCreditOrDebit(-500.0); + Double actual = bankAccount.getBalance(); + + Assert.assertEquals(expected, actual); + } + + @Test + public void getBankAccountStatusTest() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 100.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.OPEN; + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusClosedFromOpen() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.CLOSED; + bankAccount.setAccountStatus(BankAccountStatus.CLOSED); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); } + @Test + public void setBankAccountStatusClosedFromFrozen() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.OFAC_FROZEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.CLOSED; + bankAccount.setAccountStatus(BankAccountStatus.CLOSED); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusOpenFromFrozen() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.OFAC_FROZEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.OPEN; + bankAccount.setAccountStatus(BankAccountStatus.OPEN); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusOpenFromClosed() { + // needs to fail + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.CLOSED, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.CLOSED; + bankAccount.setAccountStatus(BankAccountStatus.OPEN); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusFrozenFromOpen() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.OFAC_FROZEN; + bankAccount.setAccountStatus(BankAccountStatus.OFAC_FROZEN); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusFrozenFromClosed() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.CLOSED, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.CLOSED; + bankAccount.setAccountStatus(BankAccountStatus.OFAC_FROZEN); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusClosedWithZeroBalance() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 0.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.CLOSED; + bankAccount.setAccountStatus(BankAccountStatus.CLOSED); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void setBankAccountStatusClosedWithNonZeroBalance() { + bankAccount = new BankAccount(BankAccountType.SAVINGS, 10.0, + "John", 10.0, BankAccountStatus.OPEN, + OverdraftProtection.ENABLED); + + BankAccountStatus expected = BankAccountStatus.OPEN; + bankAccount.setAccountStatus(BankAccountStatus.CLOSED); + BankAccountStatus actual = bankAccount.getAccountStatus(); + Assert.assertEquals(expected, actual); + } } diff --git a/src/test/java/squier/john/accessControl/BankAccountTransactionTest.java b/src/test/java/squier/john/accessControl/BankAccountTransactionTest.java new file mode 100644 index 0000000..b6952eb --- /dev/null +++ b/src/test/java/squier/john/accessControl/BankAccountTransactionTest.java @@ -0,0 +1,47 @@ +package squier.john.accessControl; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * Created by johnsquier on 1/17/17. + */ +public class BankAccountTransactionTest { + + BankAccountTransaction bankAccountTransaction; + + @Before + public void setup() { + bankAccountTransaction = new BankAccountTransaction(TransactionType.DEPOSIT, 100.0, + BankAccountStatus.OPEN, "John"); + } + + @Test + public void getTransactionTypeTest() { + TransactionType expected = TransactionType.DEPOSIT; + TransactionType actual = bankAccountTransaction.getTransactionType(); + Assert.assertEquals(expected, actual); + } + + @Test + public void getTransactionAmountTest() { + Double expected = 100.0; + Double actual = bankAccountTransaction.getTransactionAmount(); + Assert.assertEquals(expected, actual); + } + + @Test + public void getBankAccountStatusTest() { + BankAccountStatus expected = BankAccountStatus.OPEN; + BankAccountStatus actual = bankAccountTransaction.getBankAccountStatus(); + Assert.assertEquals(expected, actual); + } + + @Test + public void getNameTest() { + String expected = "John"; + String actual = bankAccountTransaction.getName(); + Assert.assertEquals(expected, actual); + } +} diff --git a/target/classes/squier/john/accessControl/ApprovalStatus.class b/target/classes/squier/john/accessControl/ApprovalStatus.class new file mode 100644 index 0000000..e4a65af Binary files /dev/null and b/target/classes/squier/john/accessControl/ApprovalStatus.class differ diff --git a/target/classes/squier/john/accessControl/BankAccount.class b/target/classes/squier/john/accessControl/BankAccount.class index 57af82f..befddc3 100644 Binary files a/target/classes/squier/john/accessControl/BankAccount.class and b/target/classes/squier/john/accessControl/BankAccount.class differ diff --git a/target/classes/squier/john/accessControl/BankAccountTransaction.class b/target/classes/squier/john/accessControl/BankAccountTransaction.class index 796b764..bbff429 100644 Binary files a/target/classes/squier/john/accessControl/BankAccountTransaction.class and b/target/classes/squier/john/accessControl/BankAccountTransaction.class differ diff --git a/target/test-classes/squier/john/accessControl/BankAccountTest.class b/target/test-classes/squier/john/accessControl/BankAccountTest.class index 57ee278..d7539f1 100644 Binary files a/target/test-classes/squier/john/accessControl/BankAccountTest.class and b/target/test-classes/squier/john/accessControl/BankAccountTest.class differ diff --git a/target/test-classes/squier/john/accessControl/BankAccountTransactionTest.class b/target/test-classes/squier/john/accessControl/BankAccountTransactionTest.class new file mode 100644 index 0000000..29052cb Binary files /dev/null and b/target/test-classes/squier/john/accessControl/BankAccountTransactionTest.class differ