/**
   * 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();
  }
Exemple #7
0
/*
 @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()));
 }