// Account package org.javamoney.examples.ez.money.model.persisted.account; import static org.javamoney.examples.ez.money.ApplicationProperties.UI_CURRENCY_SYMBOL; import static org.javamoney.examples.ez.money.ApplicationProperties.creditBalanceIsPositive; import static org.javamoney.examples.ez.money.model.persisted.account.AccountTypeKeys.CREDIT; import javax.money.MonetaryAmount; import org.javamoney.examples.ez.money.model.DataElement; import org.javamoney.examples.ez.money.model.persisted.transaction.Transaction; import org.javamoney.examples.ez.money.model.persisted.transaction.TransactionSet; import org.javamoney.moneta.Money; /** * This class encompasses all the elements that make up an account and * facilitates the management of transactions. * * @author Werner Keil */ public final class Account extends DataElement { /** * Constructs a new account. * * @param type * The type of account. * @param identifier * The identifier. */ public Account(AccountTypeKeys type, String identifier) { this(type, identifier, 0.0); } /** * Constructs a new account. * * @param type * The type of account. * @param identifier * The unique identifier. * @param balance * The starting balance. */ public Account(AccountTypeKeys type, String identifier, double balance) { this(type, identifier, Money.of(balance, UI_CURRENCY_SYMBOL.getCurrency())); } /** * Constructs a new account. * * @param type * The type of account. * @param identifier * The unique identifier. * @param balance * The starting balance. */ public Account(AccountTypeKeys type, String identifier, MonetaryAmount balance) { super(identifier); setBalance(balance); setIsActive(true); setTransactions(new TransactionSet()); setType(type); } /** * This method adds all the transactions from the specified account. * * @param account * The account to add the transactions from. */ public void addAll(Account account) { getTransactions().addAll(account.getTransactions()); } /** * This method adds the transaction and then returns the result of the * operation. * <p> * <b>Note:</b> If the transaction causes the balance to exceed the maximum, * then the transaction will be removed. * * @param trans * The transaction to add. * * @return true or false. */ public boolean addTransaction(Transaction trans) { boolean result = getTransactions().add(trans); if (result == true) { result = setBalance(getBalance().add(trans.getAmount())); // Remove the transaction if the balance could not be set. if (result == false) { getTransactions().remove(trans); } } return result; } /** * This method returns the balance. * * @return The balance. */ public MonetaryAmount getBalance() { return itsBalance; } /** * This method returns the balance customized for the UI. * <p> * <b>Note:</b> A balance can have different meanings amongst the account * types. A deposit account's balance for example, represents how much money * is available. A credit account's balance however, represents how much is * owed. For non-credit accounts, this method will always return the actual * balance. Otherwise, the result will depend on whether or not the user * chooses to display credit card balances as positive (amount owed). * * @return The balance customized for the UI. */ public double getBalanceForUI() { double balance = getBalance().getNumber().doubleValue(); if (getType() == CREDIT && creditBalanceIsPositive() == true) { balance = -balance; } return balance; } /** * This method returns the transactions. * * @return The transactions. */ public TransactionSet getTransactions() { return itsTransactions; } /** * This method returns the type. * * @return The type. */ public AccountTypeKeys getType() { return itsType; } /** * This method returns true if the account is active, otherwise false. * * @return true or false. */ public boolean isActive() { return itsIsActive; } /** * This method removes the transaction and then returns the result of the * operation. * <p> * <b>Note:</b> If the transaction causes the balance to exceed the maximum, * then the transaction will be added back. * * @param trans * The transaction to remove. * * @return true or false. */ public boolean removeTransaction(Transaction trans) { boolean result = getTransactions().remove(trans); if (result == true) { result = setBalance(getBalance().subtract(trans.getAmount())); // Remove the transaction if the balance could not be set. if (result == false) { getTransactions().add(trans); } } return result; } /** * This method sets the balance as long as the amount does not exceed the * maximum balance. This method returns true if the balance was set, * otherwise false. * * @param value * The balance. * * @return true or false. */ public boolean setBalance(MonetaryAmount value) { boolean result = exceedsThreshold(value); if (result == false) { itsBalance = value; } return result == false; } /** * This method sets the account's active state to that of the passed in * parameter. * * @param value * true or false. */ public void setIsActive(boolean value) { itsIsActive = value; } // //////////////////////////////////////////////////////////////////////////// // Start of private methods. // //////////////////////////////////////////////////////////////////////////// private static boolean exceedsThreshold(MonetaryAmount value) { boolean result = false; if (value != null && value.getNumber() != null) { if (value.getNumber().doubleValue() >= MAX_BALANCE || value.getNumber().doubleValue() <= -MAX_BALANCE) { result = true; } } return result; } private void setTransactions(TransactionSet set) { itsTransactions = set; } private void setType(AccountTypeKeys type) { itsType = type; } // //////////////////////////////////////////////////////////////////////////// // Start of class members. // //////////////////////////////////////////////////////////////////////////// private MonetaryAmount itsBalance; private boolean itsIsActive; private TransactionSet itsTransactions; private AccountTypeKeys itsType; /** * The maximum positive and negative amount before an overflow occurs. */ public static final double MAX_BALANCE = 99999999.99; }