//
/* * 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 - Russell C. Bjork * */ #include#include "sysdep.h" #include "bank.h" #include "session.h" #include "transaction.h" #include "atm.h" // 
Transaction::Transaction(Session & session)
  : _session(session),
    _serialNumber(++ _lastSerialNumberAssigned)
  { }
//int Transaction::_lastSerialNumberAssigned = 0; //
Transaction * Transaction::makeTransaction(TransactionType type,
					   Session & session)
  {
    switch (type)
      {
	case WITHDRAWL: return new WithdrawlTransaction(session);
	case DEPOSIT:   return new DepositTransaction(session);
	case TRANSFER:  return new TransferTransaction(session);
	case INQUIRY:   return new InquiryTransaction(session);
      }
  }
//
void Transaction::doTransactionUseCase()
  {
    if (! getTransactionSpecificsFromCustomer())
	return;
    Bank::ApprovalCode code = sendToBank();
    if (code == Bank::INVALID_PIN)
	code = _session.doInvalidPINExtension();
    if (code == Bank::APPROVED)
	finishApprovedTransaction();
    else if (code != Bank::INVALID_PIN)
	theATM.reportRejection(theBank.rejectionDescription(code));
  }
//
// getTransactionSpecificsFromCustomer() is abstract for class Transaction::
bool WithdrawlTransaction::getTransactionSpecificsFromCustomer()
  {
    _fromAccount = theATM.getAccountChoice("withdraw from");
    _amount = theATM.getWithdrawlAmountChoice();
    return theATM.checkIfCashAvailable(_amount);
  }
bool DepositTransaction::getTransactionSpecificsFromCustomer()
  {
    _toAccount = theATM.getAccountChoice("deposit to");
    _amount = theATM.getAmountEntry();
    return true;
  }
bool TransferTransaction::getTransactionSpecificsFromCustomer()
  {
    _fromAccount = theATM.getAccountChoice("transfer from");
    _toAccount = theATM.getAccountChoice("transfer to");
    _amount = theATM.getAmountEntry();
    return true;
  }
bool InquiryTransaction::getTransactionSpecificsFromCustomer()
  {
    _fromAccount = theATM.getAccountChoice("balance for");
    return true;
  }
//
// sendToBank() is abstract for class Transaction::
Bank::ApprovalCode WithdrawlTransaction::sendToBank()
  {
    return theBank.initiateWithdrawl(_session.cardNumber(),
				     _session.PIN(),
				     theATM.number(),
				     _serialNumber,
				     _fromAccount,
				     _amount,
				     _newBalance,
				     _availableBalance);
  }
Bank::ApprovalCode DepositTransaction::sendToBank()
  {
    return theBank.initiateDeposit(_session.cardNumber(),
				   _session.PIN(),
				   theATM.number(),
				   _serialNumber,
				   _toAccount,
				   _amount,
				   _newBalance,
				   _availableBalance);
  }
Bank::ApprovalCode TransferTransaction::sendToBank()
  {
    return theBank.doTransfer(_session.cardNumber(),
			      _session.PIN(),
			      theATM.number(),
			      _serialNumber,
			      _fromAccount,
			      _toAccount,
			      _amount,
			      _newBalance,
			      _availableBalance);
  }
Bank::ApprovalCode InquiryTransaction::sendToBank()
  {
    return theBank.doInquiry(_session.cardNumber(),
			     _session.PIN(),
			     theATM.number(),
			     _serialNumber,
			     _fromAccount,
			     _newBalance,
			     _availableBalance);
  }
//
// finishApprovedTransaction() is abstract in class Transaction::
void WithdrawlTransaction::finishApprovedTransaction()
  {
    theATM.dispenseCash(_amount);
    theBank.finishWithdrawl(theATM.number(), _serialNumber, true);
    char description[26];
    sprintf(description, "WITHDRAWL FROM %s",theBank.accountName(_fromAccount));
    theATM.issueReceipt(_session.cardNumber(),
			_serialNumber, 
			description,
			_amount,
			_newBalance,
			_availableBalance);
  }
void DepositTransaction::finishApprovedTransaction()
  {
    bool envelopeAccepted = theATM.acceptEnvelope();
    if (envelopeAccepted)
      {
	char description[26];
	sprintf(description, "DEPOSIT TO %s", theBank.accountName(_toAccount));
	theATM.issueReceipt(_session.cardNumber(),
			    _serialNumber,
			    description,			
			    _amount,
			    _newBalance,
			    _availableBalance);
      }
    theBank.finishDeposit(theATM.number(), _serialNumber, envelopeAccepted);
  }
void TransferTransaction::finishApprovedTransaction()
  {
    char description[26];
    sprintf(description,"TRANSFER %s TO %s",theBank.accountName(_fromAccount),
					    theBank.accountName(_toAccount));
    theATM.issueReceipt(_session.cardNumber(),
			_serialNumber,
			description,
			_amount,
			_newBalance,
			_availableBalance);
  }
void InquiryTransaction::finishApprovedTransaction()
  {
    char description[26];
    sprintf(description, "INQUIRY FROM %s", theBank.accountName(_fromAccount));
    theATM.issueReceipt(_session.cardNumber(),
			_serialNumber,
			description,
			0,		// will cause this line to be omitted
			_newBalance,
			_availableBalance);
  }
//
WithdrawlTransaction::WithdrawlTransaction(Session & session)
  : Transaction(session)
  { } 
//
DepositTransaction::DepositTransaction(Session & session)
  : Transaction(session)
  { }
//
TransferTransaction::TransferTransaction(Session & session)
  : Transaction(session)
  { }
//
InquiryTransaction::InquiryTransaction(Session & session)
  : Transaction(session)
  { }
//