//
/* * Example ATM simulation - file session.cc * * This file implements the class that represents a single customer session * with the ATM, declared in session.h * * Copyright (c) 1996,1997 - Russell C. Bjork * */ #include "sysdep.h" #include "status.h" #include "money.h" #include "bank.h" #include "session.h" #include "transaction.h" #include "atmparts.h" #include "atm.h" //
Session::Session(int cardNumber, ATM & atm, Bank & bank)
: _cardNumber(cardNumber),
_atm(atm),
_bank(bank),
_state(RUNNING),
_PIN(0),
_currentTransaction(NULL)
{ }
//
void Session::doSessionUseCase()
{
_PIN = _atm.getPIN();
do
{
const char * anotherMenu[] = { "Yes", "No" };
_currentTransaction = Transaction::chooseTransaction(*this,_atm,_bank);
Status::Code status = _currentTransaction -> doTransactionUseCase();
switch (status)
{
case Status::SUCCESS:
if (1 != _atm.getMenuChoice
("Do you want to perform another transaction?",2,anotherMenu))
_state = FINISHED;
break;
case Status::INVALID_PIN:
_state = ABORTED;
break;
default:
bool doAnother = doFailedTransactionExtension(status);
if (! doAnother)
_state = FINISHED;
}
delete _currentTransaction;
}
while (_state == RUNNING);
if (_state != ABORTED)
_atm.ejectCard();
}
//
Status::Code Session::doInvalidPINExtension()
{
Status::Code code;
for (int i = 0; i < 3; i ++)
{ _PIN = _atm.reEnterPIN();
code = _currentTransaction -> sendToBank();
if (code != Status::INVALID_PIN)
return code;
}
_atm.retainCard();
_state = ABORTED;
return Status::INVALID_PIN;
}
//
bool Session::doFailedTransactionExtension(Status::Code reason)
{ switch(reason)
{
case Status::TOO_LITTLE_CASH:
return _atm.reportTransactionFailure(
"Sorry, there is not enough cash available to satisfy your request");
case Status::ENVELOPE_DEPOSIT_TIMED_OUT:
return _atm.reportTransactionFailure(
"Envelope not deposited - transaction cancelled");
default:
return _atm.reportTransactionFailure(
_bank.rejectionExplanation(reason));
}
}
//
int Session::cardNumber() const
{ return _cardNumber; }
//
int Session::PIN() const
{ return _PIN; }
//