/** * Simulate processing of a withdrawal * * @param message the message describing the withdrawal requested * @param balances (out) balances in account after withdrawal * @return status code derived from current values */ private Status withdrawal(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER[cardNumber][message.getFromAccount()]; if (accountNumber == 0) return new Failure("Invalid account type"); Money amount = message.getAmount(); Money limitRemaining = new Money(DAILY_WITHDRAWAL_LIMIT); limitRemaining.subtract(WITHDRAWALS_TODAY[cardNumber]); if (!amount.lessEqual(limitRemaining)) return new Failure("Daily withdrawal limit exceeded"); if (!amount.lessEqual(AVAILABLE_BALANCE[accountNumber])) return new Failure("Insufficient available balance"); // Update withdrawals today and account balances once we know everything is // OK WITHDRAWALS_TODAY[cardNumber].add(amount); BALANCE[accountNumber].subtract(amount); AVAILABLE_BALANCE[accountNumber].subtract(amount); // Return updated balances balances.setBalances(BALANCE[accountNumber], AVAILABLE_BALANCE[accountNumber]); return new Success(); }
/** * Simulate the handling of a message * * @param message the message to send * @param balances (out) balances in customer's account as reported by bank * @return status code returned by bank */ public Status handleMessage(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); if (cardNumber < 1 || cardNumber > PIN.length) return new Failure("Invalid card"); if (message.getPIN() != PIN[cardNumber]) return new InvalidPIN(); switch (message.getMessageCode()) { case Message.WITHDRAWAL: return withdrawal(message, balances); case Message.INITIATE_DEPOSIT: return initiateDeposit(message); case Message.COMPLETE_DEPOSIT: return completeDeposit(message, balances); case Message.TRANSFER: return transfer(message, balances); case Message.INQUIRY: return inquiry(message, balances); } // Need to keep compiler happy return null; }
/** * Simulate processing of a transfer * * @param message the message describing the transfer requested * @param balances (out) balances in "to" account after transfer * @return status code derived from current values */ private Status transfer(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int fromAccountNumber = ACCOUNT_NUMBER[cardNumber][message.getFromAccount()]; if (fromAccountNumber == 0) return new Failure("Invalid from account type"); int toAccountNumber = ACCOUNT_NUMBER[cardNumber][message.getToAccount()]; if (toAccountNumber == 0) return new Failure("Invalid to account type"); if (fromAccountNumber == toAccountNumber) return new Failure("Can't transfer money from\n" + "an account to itself"); Money amount = message.getAmount(); if (!amount.lessEqual(AVAILABLE_BALANCE[fromAccountNumber])) return new Failure("Insufficient available balance"); // Update account balances once we know everything is OK BALANCE[fromAccountNumber].subtract(amount); AVAILABLE_BALANCE[fromAccountNumber].subtract(amount); BALANCE[toAccountNumber].add(amount); AVAILABLE_BALANCE[toAccountNumber].add(amount); // Return updated balances balances.setBalances(BALANCE[toAccountNumber], AVAILABLE_BALANCE[toAccountNumber]); return new Success(); }
/** * Simulate initiation of a deposit. At this point, the bank only approves the validity of the * deposit - no changes to the records are made until the envelope is actually inserted * * @param message the message describing the deposit requested * @return status code derived from current values */ private Status initiateDeposit(Message message) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER[cardNumber][message.getToAccount()]; if (accountNumber == 0) return new Failure("Invalid account type"); // Don't update anything yet return new Success(); }
/** * Simulate processing of an inquiry * * @param message the message describing the inquiry requested * @param balances (out) balances in account * @return status code derived from current values */ private Status inquiry(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER[cardNumber][message.getFromAccount()]; if (accountNumber == 0) return new Failure("Invalid account type"); // Return requested balances balances.setBalances(BALANCE[accountNumber], AVAILABLE_BALANCE[accountNumber]); return new Success(); }
/** * Simulate completion of a deposit * * @param message the message describing the deposit requested * @param balances (out) balances (not updated until completed) * @return status code - must always be success in this case */ private Status completeDeposit(Message message, Balances balances) { int cardNumber = message.getCard().getNumber(); int accountNumber = ACCOUNT_NUMBER[cardNumber][message.getToAccount()]; if (accountNumber == 0) return new Failure("Invalid account type"); // Now we can update the balance Money amount = message.getAmount(); BALANCE[accountNumber].add(amount); // Return updated balances balances.setBalances(BALANCE[accountNumber], AVAILABLE_BALANCE[accountNumber]); return new Success(); }
/*
@Test public void logSend() { Message message = new Message(1, new Card(2), 3, 4, 5, new Money(6)); log.logSend(message); assertTrue(mock_simulator.getLastLog().equals("Message: " + message.toString())); }