Skip to content

John Squier Final Submission #5

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

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
.idea/
AccessControl.iml
1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/libraries/Maven__junit_junit_4_12.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,003 changes: 1,003 additions & 0 deletions .idea/workspace.xml

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions AccessControl.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: junit:junit:4.12" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
</component>
</module>
Binary file added AccessControlLab.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions Access_Control_Lab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Access Control Lab - Bank Account

## Description

This lab focuses on implementing a simulated bank account and practicing using access control features of the Java language. By the end of this lab students should feel comfortable setting class members to be private or public, creating accessor and mutator functions for fields as needed, and using those methods to access the underlying fields.

The bank account functionality produced in this lab will be integrated into the weekly project and may be further enhanced during the project.

## Testing

All features should be developed following a Test-Driven Development methodology. All features should be thoroughly tested and demonstrated through unit tests.

## Instructions

Create a class for bank accounts.

Accounts must have:

- Account type (Checking, Savings, Investment, etc.)
- Account number (Must be unique for each account created)
- Balance
- Account Holder's name
- Interest rate (some accounts may not draw interest)
- Status (Open, Closed, [OFAC](https://www.treasury.gov/about/organizational-structure/offices/Pages/Office-of-Foreign-Assets-Control.aspx) Freeze...)
- Overdraft prevention (enabled, disabled, or automatic account transfer*)
- A record of all transactions that have taken place on the accounts (withdrawals, deposits, transfers, and changes to the status, name, or interest rate)


Code that uses the Account class should not be able to change the properties of an account directly; this should be something handled by methods provided by the account class. The methods should enforce the following behavior:

- Account type and account number must be set during account creation (in the constructor) and cannot be changed afterward.
- Balance inquiries are allowed at any time except while an account is under an OFAC freeze
- The balance can be changed with a credit (add money) or debit (remove money)
- Balance changes can only occur on `Open` accounts.
- The `debit` and `credit` methods should return an approval status indicating whether the transaction was approved.
- Accounts can transfer funds to or from another account with the same account holder -- Neither account's balance should fall below zero as a result of a transfer.
- Account holder's name must be set during account creation. It can be changed later (but not on closed accounts)
- Accounts with overdraft prevention enabled cannot over-draw (a debit that is greater than the account balance will be declined and the balance will not change)
- Accounts, once closed, cannot be reopened (frozen accounts can be unfrozen).
- No changes to the balance of an account can take place while it is closed or frozen
- Accounts must have a zero balance before they can be closed.
34 changes: 34 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>squier.john</groupId>
<artifactId>AccessControlLab</artifactId>
<version>1.0-SNAPSHOT</version>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>


<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>

</project>
6 changes: 6 additions & 0 deletions src/main/java/squier/john/accessControl/ApprovalStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package squier.john.accessControl;

/**
* Created by johnsquier on 1/17/17.
*/
public enum ApprovalStatus {APPROVED, NOT_APPROVED, ZERO_TRANSACTION, CANT_COMPLETE_DUE_TO_ACCT_STATUS;}
205 changes: 205 additions & 0 deletions src/main/java/squier/john/accessControl/BankAccount.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
package squier.john.accessControl;

import java.util.ArrayList;

/**
* Created by johnsquier on 1/17/17.
*/
public class BankAccount {

private BankAccountType accountType;
private int accountNumber;
private static int nextAccountNumber = 1;
private double balance;
private String accountHoldersName;
private double interestRate;
private BankAccountStatus accountStatus;
private OverdraftProtection overdraftProtection;
private ArrayList<BankAccountTransaction> transactionRecord;

public BankAccount(BankAccountType accountType, double balance, String accountHoldersName, double interestRate,
BankAccountStatus accountStatus, OverdraftProtection overdraftProtection) {
this.accountType = accountType;
accountNumber = nextAccountNumber++;
this.balance = balance;
this.accountHoldersName = accountHoldersName;
this.interestRate = interestRate;
this.accountStatus = accountStatus;
this.overdraftProtection = overdraftProtection;
transactionRecord = new ArrayList<BankAccountTransaction>();
}

public Double getBalance() {
if ( accountStatus.equals(BankAccountStatus.OFAC_FROZEN) ) {
return null;
}
else {
return balance;
}
}

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 ) {
return credit(amount);
}
else if ( amount < 0.0 ) {
return debit(amount);
}
else {
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;
}

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 boolean bothAccountsHaveSameOwner(BankAccount transferFrom, BankAccount transferTo) {
return transferFrom.getAccountHoldersName().equals(transferTo.accountHoldersName);
}

private boolean doesAccountHaveSufficientBalance(BankAccount acct, double amount) {
return acct.getBalance() >= amount;
}
}
Loading