/**
* Write a description of class ATM here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class ATM
{
private boolean userAuthenticated;
private int currentAccountNumber;
private Screen screen;
private Keypad keypad;
private CashDispenser cashDispenser;
private DepositSlot depositSlot;
private BankDatabase bankDatabase;
private static final int BALANCE_INQUIRY = 1;
private static final int WITHDRAWAL = 2;
private static final int DEPOSIT = 3;
private static final int EXIT = 4;
public ATM(){
userAuthenticated = false;
currentAccountNumber = 0;
screen = new Screen();
keypad = new Keypad();
cashDispenser = new CashDispenser();
depositSlot = new DepositSlot();
bankDatabase = new BankDatabase();
}
public void run(){
while(true){
while(!userAuthenticated){
screen.displayMessageLine("\nWelcome!");
authenticateUser();
}
performTransactions();
userAuthenticated = false;
currentAccountNumber = 0;
screen.displayMessageLine("\nThank you! Goodbye!");
}
}
private void authenticateUser(){
screen.displayMessage("\nPlease enter your account number: ");
int accountNumber = keypad.getInput();
screen.displayMessage("\nEnter your PIN: ");
int pin = keypad.getInput();
userAuthenticated = bankDatabase.authenticateUser(accountNumber, pin);
if(userAuthenticated){
currentAccountNumber = accountNumber;
}
else
screen.displayMessageLine("Invalid account number or PIN. Please try again.");
}
private void performTransactions(){
Transaction currentTransaction = null;
boolean userExited = false;
while(!userExited){
int mainMenuSelection = displayMainMenu();
switch(mainMenuSelection){
case BALANCE_INQUIRY:
case WITHDRAWAL:
case DEPOSIT:
currentTransaction = createTransaction(mainMenuSelection);
currentTransaction.execute();
break;
case EXIT:
screen.displayMessageLine("\nExiting the system...");
userExited = true;
break;
default:
screen.displayMessageLine("\nYou did not enter a valid selection. Try again.");
break;
}
}
}
private int displayMainMenu(){
screen.displayMessageLine("\nMain menu:");
screen.displayMessageLine("1 - View my balance");
screen.displayMessageLine("2 - Withdraw cash");
screen.displayMessageLine("3 - Deposit funds");
screen.displayMessageLine("4 - Exit\n");
screen.displayMessage("Enter a choice: ");
return keypad.getInput();
}
private Transaction createTransaction( int type ){
Transaction temp = null;
switch(type){
case BALANCE_INQUIRY:
temp = new BalanceInquiry(currentAccountNumber, screen, bankDatabase);
break;
case WITHDRAWAL:
temp = new Withdrawal(currentAccountNumber, screen, bankDatabase, keypad, cashDispenser);
break;
case DEPOSIT:
temp = new Deposit(currentAccountNumber, screen, bankDatabase, keypad, depositSlot);
break;
}
return temp;
}
}
Source code: Screen
/**
* Write a description of class Screen here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class Screen
{
public void displayMessage(String message){
System.out.print(message);
}
public void displayMessageLine(String message){
System.out.println(message);
}
public void displayDollarAmount(double amount){
System.out.printf("$%,.2f", amount);
}
}
Source code: Keypad
/**
* Write a description of class Keypad here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
import java.util.Scanner;
public class Keypad
{
private Scanner input;
public Keypad(){
input = new Scanner(System.in);
}
public int getInput(){
return input.nextInt();
}
}
Source code: CashDispenser
/**
* Write a description of class CashDispenser here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class CashDispenser
{
private final static int INITIAL_COUNT = 500;
private int count;
public CashDispenser(){
count = INITIAL_COUNT;
}
public void dispenseCash(int amount){
int billsRequired = amount/20;
count -= billsRequired;
}
public boolean isSufficientCashAvailable(int amount){
int billsRequired = amount/20;
if(count>=billsRequired)
return true;
else
return false;
}
}
Source code: DepositSlot
/**
* Write a description of class DepositSlot here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class DepositSlot
{
public boolean isEnvelopeReceived(){
return true;
}
}
Source code: Account
/**
* Write a description of class Account here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class Account
{
private int accountNumber;
private int pin;
private double availableBalance;
private double totalBalance;
public Account(int theAccountNumber, int thePIN, double theAvailableBalance, double theTotalBalance){
accountNumber = theAccountNumber;
pin = thePIN;
availableBalance = theAvailableBalance;
totalBalance = theTotalBalance;
}
public boolean validatePIN(int userPIN){
if(userPIN==pin)
return true;
else
return false;
}
public double getAvailableBalance(){
return availableBalance;
}
public double getTotalBalance(){
return totalBalance;
}
public void credit(double amount){
totalBalance += amount;
}
public void debit(double amount){
availableBalance -= amount;
totalBalance -= amount;
}
public int getAccountNumber(){
return accountNumber;
}
}
Source code: BankDatabase
/**
* Write a description of class BankDatabase here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class BankDatabase
{
private Account[] accounts;
public BankDatabase(){
accounts = new Account[2];
accounts[0] = new Account(12345, 54321, 1000.0, 1200.0);
accounts[1] = new Account(98765, 56789, 200.0, 200.0);
}
private Account getAccount(int accountNumber){
for(Account currentAccount:accounts){
if(currentAccount.getAccountNumber()==accountNumber)
return currentAccount;
}
return null;
}
public boolean authenticateUser(int userAccountNumber, int userPIN){
Account userAccount = getAccount(userAccountNumber);
if(userAccount != null)
return userAccount.validatePIN(userPIN);
else
return false;
}
public double getAvailableBalance(int userAccountNumber){
return getAccount(userAccountNumber).getAvailableBalance();
}
public double getTotalBalance(int userAccountNumber){
return getAccount(userAccountNumber).getTotalBalance();
}
public void credit(int userAccountNumber, double amount){
getAccount(userAccountNumber).credit(amount);
}
public void debit(int userAccountNumber, double amount){
getAccount(userAccountNumber).debit(amount);
}
}
Source code: Transaction
/**
* Write a description of class Transaction here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public abstract class Transaction
{
private int accountNumber;
private Screen screen;
private BankDatabase bankDatabase;
public Transaction(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){
accountNumber = userAccountNumber;
screen = atmScreen;
bankDatabase = atmBankDatabase;
}
public int getAccountNumber(){
return accountNumber;
}
public Screen getScreen(){
return screen;
}
public BankDatabase getBankDatabase(){
return bankDatabase;
}
abstract public void execute();
}
Source code: BalanceInquiry
/**
* Write a description of class BalanceInquiry here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class BalanceInquiry extends Transaction
{
public BalanceInquiry(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase){
super( userAccountNumber, atmScreen, atmBankDatabase );
}
@Override
public void execute()
{
BankDatabase bankDatabase = getBankDatabase();
Screen screen = getScreen();
double availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());
double totalBalance = bankDatabase.getTotalBalance(getAccountNumber());
screen.displayMessageLine("\nBalance Information:");
screen.displayMessage(" - Available balance: ");
screen.displayDollarAmount(availableBalance);
screen.displayMessage("\n - Total balance: ");
screen.displayDollarAmount(totalBalance);
screen.displayMessageLine("");
}
}
Source code: Withdrawal
/**
* Write a description of class Withdrawal here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class Withdrawal extends Transaction
{
private int amount;
private Keypad keypad;
private CashDispenser cashDispenser;
private final static int CANCELED = 6;
public Withdrawal(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, CashDispenser atmCashDispenser){
super(userAccountNumber, atmScreen, atmBankDatabase);
keypad = atmKeypad;
cashDispenser = atmCashDispenser;
}
@Override
public void execute(){
boolean cashDispensed = false;
double availableBalance;
BankDatabase bankDatabase = getBankDatabase();
Screen screen = getScreen();
do{
amount = displayMenuOfAmounts();
if(amount!=CANCELED){
availableBalance = bankDatabase.getAvailableBalance(getAccountNumber());
if(amount<=availableBalance ){
if(cashDispenser.isSufficientCashAvailable(amount)){
bankDatabase.debit(getAccountNumber(), amount);
cashDispenser.dispenseCash(amount);
cashDispensed = true;
screen.displayMessageLine("\nYour cash has been dispensed. Please take your cash now.");
}
else
screen.displayMessageLine("\nInsufficient cash available in the ATM.\n\nPlease choose a smaller amount.");
}
else{
screen.displayMessageLine("\nInsufficient funds in your account.\n\nPlease choose a smaller amount.");
}
}
else{
screen.displayMessageLine("\nCanceling transaction...");
return;
}
}
while(!cashDispensed);
}
private int displayMenuOfAmounts(){
int userChoice = 0;
Screen screen = getScreen();
int[] amounts = {0, 20, 40, 60, 100, 200};
while(userChoice==0){
screen.displayMessageLine("\nWithdrawal Menu:");
screen.displayMessageLine("1 - $20");
screen.displayMessageLine("2 - $40");
screen.displayMessageLine("3 - $60");
screen.displayMessageLine("4 - $100");
screen.displayMessageLine("5 - $200");
screen.displayMessageLine("6 - Cancel transaction");
screen.displayMessage("\nChoose a withdrawal amount: ");
int input = keypad.getInput();
switch(input){
case 1:
case 2:
case 3:
case 4:
case 5:
userChoice = amounts[input];
break;
case CANCELED:
userChoice = CANCELED;
break;
default:
screen.displayMessageLine("\nInvalid selection. Try again.");
}
}
return userChoice;
}
}
Source code: Deposit
/**
* Write a description of class Deposit here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class Deposit extends Transaction
{
private double amount;
private Keypad keypad;
private DepositSlot depositSlot;
private final static int CANCELED = 0;
public Deposit(int userAccountNumber, Screen atmScreen, BankDatabase atmBankDatabase, Keypad atmKeypad, DepositSlot atmDepositSlot){
super(userAccountNumber, atmScreen, atmBankDatabase);
keypad = atmKeypad;
depositSlot = atmDepositSlot;
}
@Override
public void execute(){
BankDatabase bankDatabase = getBankDatabase();
Screen screen = getScreen();
amount = promptForDepositAmount();
if(amount!=CANCELED){
screen.displayMessage("\nPlease insert a deposit envelope containing ");
screen.displayDollarAmount(amount);
screen.displayMessageLine(".");
boolean envelopeReceived = depositSlot.isEnvelopeReceived();
if(envelopeReceived){
screen.displayMessageLine("\nYour envelope has been received.\nNOTE: The money just deposited will not be available until we verify the amount of any enclosed cash and your checks clear.");
bankDatabase.credit(getAccountNumber(), amount);
}
else{
screen.displayMessageLine("\nYou did not insert an envelope, so the ATM has canceled your transaction.");
}
}
else{
screen.displayMessageLine("\nCanceling transaction...");
}
}
private double promptForDepositAmount(){
Screen screen = getScreen();
screen.displayMessage("\nPlease enter a deposit amount in CENTS (or 0 to cancel): ");
int input = keypad.getInput();
if(input==CANCELED)
return CANCELED;
else{
return(double) input/100;
}
}
}
Source code: ATMCaseStudy
/**
* Write a description of class ATMCaseStudy here.
*
* @author Davin Masasih - 5115100113
* @version 0.1
*/
public class ATMCaseStudy
{
public static void main(String[] args){
ATM theATM = new ATM();
theATM.run();
}
}