//
/* * Example ATM simulation - file transaction.cc * * This file implements the classes that represent the various kinds of * transactions that the ATM can perform, declared in transaction.h * * Copyright (c) 1996,1997 - Russell C. Bjork * */ #include#include "sysdep.h" #include "status.h" #include "money.h" #include "bank.h" #include "session.h" #include "transaction.h" #include "atmparts.h" #include "atm.h" //
Transaction::Transaction(Session & session, ATM & atm, Bank & bank) : _session(session), _atm(atm), _bank(bank), _serialNumber(++ _lastSerialNumberAssigned) { } //
int Transaction::_lastSerialNumberAssigned = 0; //
Transaction * Transaction::chooseTransaction(Session & session, ATM & atm, Bank & bank) { const char * transactionMenu[] = { "Cash Withdrawl", "Deposit", "Transfer Funds Between Accounts", "Balance Inquiry" }; switch (atm.getMenuChoice("Please choose a transaction type:", 4, transactionMenu)) { case 1: return new WithdrawlTransaction(session, atm, bank); case 2: return new DepositTransaction(session, atm, bank); case 3: return new TransferTransaction(session, atm, bank); case 4: return new InquiryTransaction(session, atm, bank); } } //
Status::Code Transaction::doTransactionUseCase() { Status::Code code; code = getTransactionSpecificsFromCustomer(); if (code != Status::SUCCESS) return code; code = sendToBank(); if (code == Status::INVALID_PIN) { code = _session.doInvalidPINExtension(); if (code == Status::INVALID_PIN) return code; } if (code == Status::SUCCESS) code = finishApprovedTransaction(); return code; } //
// getTransactionSpecificsFromCustomer() is abstract for class Transaction:: Status::Code WithdrawlTransaction::getTransactionSpecificsFromCustomer() { _fromAccount = _bank.chooseAccountType("withdraw from", _atm); const char * menu[] = { "$ 20", "$ 40", "$ 60", "$ 80", "$ 100", "$ 200", "$ 300" }; switch (_atm.getMenuChoice("Please choose an amount:", 7, menu)) { case 1: _amount = Money(20); break; case 2: _amount = Money(40); break; case 3: _amount = Money(60); break; case 4: _amount = Money(80); break; case 5: _amount = Money(100); break; case 6: _amount = Money(200); break; case 7: _amount = Money(300); break; } if (_atm.checkIfCashAvailable(_amount)) return Status::SUCCESS; else return Status::TOO_LITTLE_CASH; } Status::Code DepositTransaction::getTransactionSpecificsFromCustomer() { _toAccount = _bank.chooseAccountType("deposit to", _atm); _amount = _atm.getAmountEntry(); return Status::SUCCESS; } Status::Code TransferTransaction::getTransactionSpecificsFromCustomer() { _fromAccount = _bank.chooseAccountType("transfer from", _atm); _toAccount = _bank.chooseAccountType("transfer to", _atm); _amount = _atm.getAmountEntry(); return Status::SUCCESS; } Status::Code InquiryTransaction::getTransactionSpecificsFromCustomer() { _fromAccount = _bank.chooseAccountType("balance for", _atm); return Status::SUCCESS; } //
// sendToBank() is abstract for class Transaction:: Status::Code WithdrawlTransaction::sendToBank() { return _bank.initiateWithdrawl(_session.cardNumber(), _session.PIN(), _atm.number(), _serialNumber, _fromAccount, _amount, _newBalance, _availableBalance); } Status::Code DepositTransaction::sendToBank() { return _bank.initiateDeposit(_session.cardNumber(), _session.PIN(), _atm.number(), _serialNumber, _toAccount, _amount, _newBalance, _availableBalance); } Status::Code TransferTransaction::sendToBank() { return _bank.doTransfer(_session.cardNumber(), _session.PIN(), _atm.number(), _serialNumber, _fromAccount, _toAccount, _amount, _newBalance, _availableBalance); } Status::Code InquiryTransaction::sendToBank() { return _bank.doInquiry(_session.cardNumber(), _session.PIN(), _atm.number(), _serialNumber, _fromAccount, _newBalance, _availableBalance); } //
// finishApprovedTransaction() is abstract in class Transaction:: Status::Code WithdrawlTransaction::finishApprovedTransaction() { _atm.dispenseCash(_amount); _bank.finishWithdrawl(_atm.number(), _serialNumber, true); char description[26]; sprintf(description, "WITHDRAWL FROM %s", _bank.accountName(_fromAccount)); _atm.issueReceipt(_session.cardNumber(), _serialNumber, description, _amount, _newBalance, _availableBalance); return Status::SUCCESS; } Status::Code DepositTransaction::finishApprovedTransaction() { bool envelopeAccepted = _atm.acceptEnvelope(); _bank.finishDeposit(_atm.number(), _serialNumber, envelopeAccepted); if (envelopeAccepted) { char description[26]; sprintf(description, "DEPOSIT TO %s", _bank.accountName(_toAccount)); _atm.issueReceipt(_session.cardNumber(), _serialNumber, description, _amount, _newBalance, _availableBalance); return Status::SUCCESS; } else return Status::ENVELOPE_DEPOSIT_TIMED_OUT; } Status::Code TransferTransaction::finishApprovedTransaction() { char description[26]; sprintf(description, "TRANSFER %s TO %s", _bank.accountName(_fromAccount), _bank.accountName(_toAccount)); _atm.issueReceipt(_session.cardNumber(), _serialNumber, description, _amount, _newBalance, _availableBalance); return Status::SUCCESS; } Status::Code InquiryTransaction::finishApprovedTransaction() { char description[26]; sprintf(description, "INQUIRY FROM %s", _bank.accountName(_fromAccount)); _atm.issueReceipt(_session.cardNumber(), _serialNumber, description, Money(0), // will cause this line to be omitted _newBalance, _availableBalance); return Status::SUCCESS; } //
WithdrawlTransaction::WithdrawlTransaction(Session & session, ATM & atm, Bank & bank) : Transaction(session, atm, bank) { } //
DepositTransaction::DepositTransaction(Session & session, ATM & atm, Bank & bank) : Transaction(session, atm, bank) { } //
TransferTransaction::TransferTransaction(Session & session, ATM & atm, Bank & bank) : Transaction(session, atm, bank) { } //
InquiryTransaction::InquiryTransaction(Session & session, ATM & atm, Bank & bank) : Transaction(session, atm, bank) { } //