001package de.hdm_stuttgart.mi.sd1.interest;
002
003/**
004 * Dealing with account balances and interest calculations.
005 *
006 */
007public class Account {
008
009  private static double
010      assetInterestRate = 1.5,  // applied to positive balances / assets
011      debtInterestRate = 15.;   // applied to negative balances / debt
012
013  private static int accountLimit = 10000;
014
015  private double balance;       // Balances are defined on a per-account basis. Thus "static" must not appear here.
016
017  /**
018   * Create a new account having a balance of 0.
019   */
020  public Account() {            // Default Constructor. This one has no parameters creating
021    this(0);             // an initially empty account.
022  }
023
024  /**
025   * Create a new account of given initial balance.
026   *
027   * @param balance The account's initial balance.
028   */
029  public Account(double balance) {  // Non-default constructor creating an account
030    setBalance(balance);            // of given balance.
031  }
032
033  /**
034   * @return The account's current balance.
035   */
036  public double getBalance() {
037    return balance;
038  }
039  /**
040   * Setting a (possibly) new balance.
041   *
042   * @param balance The desired new balance value. If greater than 10000
043   *      a warning message is being issued and the accounts current value will be retained.
044   */
045  public void setBalance(double balance) {
046    if (balance <= accountLimit) {
047      this.balance = balance; // "this" required to resolve name shadowing conflict.
048    } else {
049      System.out.println("Balance" + balance + " exceeds " + accountLimit);
050    }
051  }
052  /**
053   * Setting the interest rate common to all accounts. This one
054   * will be applied to positive balances only. For handling
055   * negative balances see {{@link #setDebtInterestRate(double)}.
056   *
057   * @param assetInterestRate The desired (global) interest rate.
058   */
059  public static void setAssetInterestRate(double assetInterestRate) {
060    Account.assetInterestRate = assetInterestRate;
061  }
062  /**
063   * @return The current global interest rate
064   */
065  public static double getAssetInterestRate() {
066    return assetInterestRate;
067  }
068
069  /**
070   * @return The debt interest rate value.
071   */
072  public static double getDebtInterestRate() {
073    return debtInterestRate;
074  }
075
076  /**
077   * This interest rate will be applied to negative balances. In contrast
078   * {{@link #setAssetInterestRate(double)} will handle positive balance values.
079   *
080   * @param debtInterestRate The debt interest rate's value.
081   */
082  public static void setDebtInterestRate(double debtInterestRate) {
083    Account.debtInterestRate = debtInterestRate;
084  }
085
086  /**
087   * <p>Convenience method to {{@link #applyInterest(int)}}: Adding one year's interest to the current balance according
088   * to:</p>
089   *
090   * \[ balance_{1} = balance (1 + {interestRate\over 100}) \]
091   *
092   */
093  public void applyInterest() {
094    applyInterest(1);
095  }
096
097  /**
098   * <p>Adding the accumulated interest of a given number of years to the current balance according to:</p>
099   *
100   * \[ balance_{years} = balance\ {\left(1 + {interestRate\over 100}\right)}^{years} \]
101   *
102   *<p>Positive balances will receive the value of {@link #setAssetInterestRate(double)} whereas
103   * calculation of negative  balances will be based on {{@link #setDebtInterestRate(double)}.</p>
104   *
105   * @param years the given time period.
106   */
107  public void applyInterest(int years) {
108
109    final double annualInterestFactor;
110    if (0 < balance) {                                      // Asset type balance
111      annualInterestFactor = 1 + assetInterestRate / 100;
112    } else {                                                // Debt type balance
113      annualInterestFactor = 1 + debtInterestRate / 100;
114    }
115    for (int i = 0; i < years; i++) {
116      balance *= annualInterestFactor;
117    }
118  }
119
120  /**
121   * Calculate the expected annual interest without changing the account's balance.
122   *
123   * @return Annual interest to be expected
124   */
125  public double getYearlyInterest() {
126    return balance * assetInterestRate / 100;
127  }
128}