namespace BankersLibrary
{
public enum TransactionType { Deposit, Withdraw, Transfer }
[Serializable]
public class Owner
{
// first last phone email
private string _firstName;
public string FirstName
{ get { return _firstName; } }
private string _lastName;
public string LastName
{ get { return _lastName; } }
private string _phoneNumber;
public string PhoneNumber
{ get { return _phoneNumber; } }
private string _email;
public string Email
{ get { return _email; } }
public Owner(string fName, string lName, string pNumber, string email)
{
_firstName = fName;
_lastName = lName;
_phoneNumber = pNumber;
_email = email;
}
}
[Serializable]
public class Transaction
{
// Define a class Transaction with fields _amount, _transactionDate, type(TransactionType)
private decimal _amount;
public decimal Amount
{ get { return _amount; } }
private DateTime _transactionDate;
public DateTime TransactionDate
{ get { return _transactionDate; } }
private TransactionType _transactionType;
public TransactionType TransactionType
{ get { return _transactionType; } }
public Transaction(decimal amount, DateTime date, TransactionType type)
{
_amount = amount;
_transactionDate = date;
_transactionType = type;
}
}
[Serializable]
public abstract class BankAccount
{
// Define an abstract class BankAcount with fields _accountNumber, _balance, _dateCreated, _owner (of type List<Owner>)
string _accountNumber;
public string AccountNumber
{ get { return _accountNumber; } }
private decimal _balance;
public decimal Balance
{
get { return _balance; }
internal protected set { _balance = value; }
}
private DateTime _dateCreated;
public DateTime DateCreated
{ get { return _dateCreated; } }
private List<Owner> _owner;
public Owner[] Owner
{ get { return _owner.ToArray(); } }
internal protected List<Transaction> _transactions;
public Transaction[] TransactionList
{
get { return _transactions.ToArray(); }
}
// Add constructor \/ and properties ^
public BankAccount(string accountNumber, decimal initialDeposit, DateTime todaysDate, Owner accountOwner)
{
_accountNumber = accountNumber;
_balance = initialDeposit;
_dateCreated = todaysDate;
_owner = new List<Owner>();
_owner.Add(accountOwner);
_transactions = new List<Transaction>();
}
// Add instance methods: virtual Deposit, abstract Withdraw, AddOwner(Owner owner)
public virtual decimal Deposit(decimal amount)
{
Transaction t = new Transaction(amount, DateTime.Now, TransactionType.Deposit);
_transactions.Add(t);
_balance += amount;
return _balance;
}
public abstract bool Withdraw(decimal amount);
public void AddOwner(Owner owner)
{
_owner.Add(owner);
}
// Add static methods: static Transfer
/// <summary>
/// Transfers a specified amount from the balance of account 1 to the balance of account 2.
/// </summary>
/// <param name="a1">The Account which contains the funds to be transfered from.</param>
/// <param name="a2">The Account which will recieve the transfered funds</param>
/// <param name="amount">The value in dollers which will be transfered</param>
/// <returns></returns>
public static bool TransferFunds(BankAccount a1, BankAccount a2, decimal amount)
{
if (a1._balance >= amount)
{
Transaction t = new Transaction(-1 * amount, DateTime.Now, TransactionType.Transfer);
a1._transactions.Add(t);
Transaction tr = new Transaction(amount, DateTime.Now, TransactionType.Transfer);
a2._transactions.Add(tr);
///////////////////////////////////////////////////////////////////////////////////
a2._balance += amount;
a1._balance -= amount;
return true;
}
return false;
}
}
// Define a class CheckingAccount that inherits from BankAccount
// add fields: _minBalance
// Define its constructor, properties, methods
[Serializable]
public class CheckingAccount : BankAccount
{
private decimal _minimumBalance;
public decimal MinimumBalance
{ get { return _minimumBalance; } }
public CheckingAccount(string accountNumber, decimal initialDeposit, DateTime todaysDate, Owner accountOwner)
: base(accountNumber, initialDeposit, todaysDate, accountOwner)
{
_minimumBalance = 500; // $500 required to open a checking account.
if (initialDeposit < _minimumBalance)
throw new Exception("Can not create an account without a deposit of $500 or more");
}
new public decimal Deposit(decimal amount)
{
return base.Deposit(amount);
}
public override bool Withdraw(decimal amount)
{
if (Balance - amount >= _minimumBalance)
{
Transaction t = new Transaction(amount, DateTime.Now, TransactionType.Withdraw);
_transactions.Add(t);
Balance -= amount;
return true;
}
return false;
}
}
// Define a class SavingsAccount that inherts from BankAccount
// Add fields: _interestRate
// Define its constructor, properties and methods.
[Serializable]
public class SavingsAccount : BankAccount
{
private decimal _interestRate;
public decimal InterestRate
{ get { return _interestRate; } }
public SavingsAccount(string accountNumber, decimal initialDeposit, DateTime todaysDate, Owner accountOwner)
: base(accountNumber, initialDeposit, todaysDate, accountOwner)
{
_interestRate = 0.035m;
}
public override decimal Deposit(decimal amount)
{
Transaction t = new Transaction(amount, DateTime.Now, TransactionType.Deposit);
_transactions.Add(t);
Balance += amount;
return Balance;
}
public override bool Withdraw(decimal amount)
{
if (Balance - amount >= 0)
{
Transaction t = new Transaction(amount, DateTime.Now, TransactionType.Withdraw);
_transactions.Add(t);
Balance -= amount;
return true;
}
return false;
}
}
}
//====================================================================
using System.Windows.Forms;
using BankersLibrary;
using System.IO;
namespace BankAccount_Lab
{
// Add UI to perform the following:
// Be able to:
// Deposit money into account selected account
// Withdraw money from account selected account
// Transfer from one account to another
//
// Provide account way to save all accounts to account file and read them back.
public partial class Form1 : Form
{
///<summary> Gloabl Variables:
///</summary>
// Bank Account List to store all accounts and their activity/data.
List<BankAccount> accountList = new List<BankAccount>();
// This will act as the index of the previously selected account so it can be reselected when the display refreshes.
int selectedAccountIndex;
// file location for accountList
string accountFileLocation = "accountList.dat";
// Master Account Number Generator:
int MASTER_ACCOUNT_ID;
string Master_Account_ID_Location = "MasterAccountID.txt";
bool bCloseNormally = true;
/// <summary> Loading and Closing Events
/// </summary>
public Form1()
{
InitializeComponent(); // initializes the Form
}
private void Form1_Load(object sender, EventArgs e)
{
// Read and Load the master account ID
if (File.Exists(Master_Account_ID_Location))
{
using (StreamReader sr = new StreamReader(Master_Account_ID_Location, true))
{
// Store that ID in MASTER_ACCOUNT_ID
MASTER_ACCOUNT_ID = int.Parse(sr.ReadToEnd());
}
}
else
{
MessageBox.Show("A required file did not load correctly. Please contact the IT department immediatley. CODE RED!\nThe MASTER_ACCOUNT_ID could not be loaded. \"File Not Found!\"\n\nSystem Closing...");
bCloseNormally = false;
this.Close();
}
// Update the ID display.
lblAccountNumber.Text = "Next Account Number: " + MASTER_ACCOUNT_ID.ToString();
// Read and Load the Account List
if (File.Exists(accountFileLocation))
{
DialogResult dr = MessageBox.Show("Load all accounts?", "Load Account File?", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (dr == DialogResult.Yes)
{
RDUtil.DeserializeList<BankAccount>(accountFileLocation, ref accountList);
}
}
UpdateAccountDisplay();
}
/// <summary>
/// Just experimenting with override. No reason to call this
/// </summary>
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (bCloseNormally)
{
base.OnFormClosing(e);
}
else
{
//Write some Log File about the missing file and some time sensitive hoop-de-doo
}
}
protected void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dr = MessageBox.Show("Save all accounts?", "Always Save Before Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
if (dr == DialogResult.Yes)
{
RDUtil.SerializeListData(accountFileLocation, accountList);
}
using (StreamWriter sw = new StreamWriter(Master_Account_ID_Location))
{
sw.WriteLine(MASTER_ACCOUNT_ID.ToString());
}
}
/// <summary> Updates the ListViewItems to reflect thier currently stored values.
/// Should be used after changing any account balances, and when reading accounts from account file.
/// </summary>
private void UpdateAccountDisplay()
{
lsvAccount.Items.Clear();
ListViewItem lvi;
foreach (BankAccount a in accountList)
{
lvi = new ListViewItem(a.GetType().Name);
lvi.SubItems.Add(a.AccountNumber);
lvi.SubItems.Add(a.Owner[0].FirstName);
lvi.SubItems.Add(a.Owner[0].LastName);
lvi.SubItems.Add(a.DateCreated.ToShortDateString());
lvi.SubItems.Add(a.Balance.ToString("c"));
lvi.SubItems.Add(a.Owner[0].PhoneNumber);
lvi.SubItems.Add(a.Owner[0].Email);
lsvAccount.Items.Add(lvi);
}
}
/// <summary> Populates the Transactions ListView with the with BankAccount.
/// </summary>
/// <param name="account">The Account whose information you wish to display.</param>
private void DisplayAccountTransactions(BankAccount account)
{
lsvTransaction.Items.Clear();
ListViewItem lvi = null;
foreach (Transaction t in account.TransactionList)
{
string amount = t.Amount.ToString("c");
if (t.Amount < 0)
{
amount = "-" + t.Amount.ToString("c");
}
lvi = new ListViewItem(amount);
lvi.SubItems.Add(t.TransactionDate.ToShortDateString());
lvi.SubItems.Add(t.TransactionType.ToString());
lsvTransaction.Items.Add(lvi);
}
}
/// <summary> Returns the selected account from the Accounts ListView. Returns null if nothing is selected.
/// </summary>
/// <returns></returns>
private BankAccount GetSelectedAccount()
{
if (lsvAccount.SelectedItems.Count > 0)
{
// get selected account
string accountNumber = lsvAccount.SelectedItems[0].SubItems[1].Text;
BankAccount ba = GetAccountByNumber(accountNumber);
return ba;
}
return null;
}
/// <summary> Finds account given account in the accountList
/// </summary>
/// <param name="accountNumber">The Account number which belongs to the Account you wish to get.</param>
/// <returns></returns>
private BankAccount GetAccountByNumber(string accountNumber)
{
foreach (BankAccount a in accountList)
{
if (a.AccountNumber == accountNumber)
{
return a;
}
}
return null;
}
/// <summary> Returns true if the specified BankAccount has enough funds to withdraw from.
/// </summary>
/// <param name="ba">The Account you wish to withdraw from.</param>
/// <param name="amount">The dollar amount you wish to withdraw.</param>
private void ProcessWithdraw(BankAccount ba, decimal amount)
{
if (ba.Withdraw(amount))
{
toolTip.Show("Success", btnWithdrawOrDeposit, 1300);
}
else
MessageBox.Show("The account you are trying to access does not have sufficient funds.\nAccount: " + ba.AccountNumber + "\nBalance: " + ba.Balance + "\nAttempted Withdrawl: " + amount.ToString("c"));
}
/// <summary> Calls the Deposit(decimal amount) method of the provided BankAccount.
/// </summary>
/// <param name="bankAccount">The Account you wish to deposit into.</param>
/// <param name="amount">The full amount which will be deposited.</param>
private void ProcessDeposit(BankAccount bankAccount, decimal amount)
{
bankAccount.Deposit(amount);
}
/// EVENTS:
// Fires when an account is selected from the Account ListView
private void lsvAccount_SelectedIndexChanged(object sender, EventArgs e)
{
if (lsvAccount.SelectedItems.Count > 0)
{
// set globally available selected account:
selectedAccountIndex = lsvAccount.SelectedIndices[0];
string accountNumber = lsvAccount.SelectedItems[0].SubItems[1].Text;
foreach (BankAccount a in accountList)
{
if (a.AccountNumber == accountNumber)
{
DisplayAccountTransactions(a);
break;
}
}
}
}
// Fires when account Deposit or Withdraw radio button is selected.
private void radDepositAndWithdraw_CheckedChanged(object sender, EventArgs e)
{
if (radDeposit.Checked == true)
{
lblChangeOnWithdrawDeposit.Text = "Deposit Amount:";
btnWithdrawOrDeposit.Text = "Deposit";
}
else if (radWithdraw.Checked == true)
{
lblChangeOnWithdrawDeposit.Text = "Withdraw Amount:";
btnWithdrawOrDeposit.Text = "Withdraw";
}
}
// Buttons for transfer and withdraw/deposit
private void btnTransfer_Click(object sender, EventArgs e)
{
// get account numbers from user
if (txtTransferAccountOne.Text != String.Empty && txtTransferAccountTwo.Text != String.Empty)
{
string acNum1 = txtTransferAccountOne.Text;
string acNum2 = txtTransferAccountTwo.Text;
// get account1 by number
if (acNum1 != acNum2)
{
BankAccount ba1 = GetAccountByNumber(acNum1);
if (ba1 != null)
{
// get account2 by number
BankAccount ba2 = GetAccountByNumber(acNum2);
if (ba2 != null)
{
// read amount
decimal amount;
if (decimal.TryParse(txtTransferAmount.Text, out amount))
{
// complete Transfer
if (BankAccount.TransferFunds(ba1, ba2, amount))
{
UpdateAccountDisplay();
MessageBox.Show("Transfer Complete.", "Success");
txtTransferAccountOne.Clear();
txtTransferAccountTwo.Clear();
txtTransferAmount.Clear();
}
else
{
MessageBox.Show("The Transfer Attempt failed. Account, " + ba1.AccountNumber + " contains insufficient funds.\n\n" +
"Current Funds: " + ba1.Balance.ToString("C") +
"\nTransfer Attempt: " + amount.ToString("C"), "Failed to Transfer");
}
}
}
else
{
toolTip.Show("Invalid Account number", txtTransferAccountTwo, 1800);
}
}
else
{
toolTip.Show("Invalid Account number", txtTransferAccountOne, 1800);
}
}
else
{
toolTip.Show("Enter Valid Account Numbers", btnTransfer, 1800);
}
}
}
private void btnWithdrawOrDeposit_Click(object sender, EventArgs e)
{
// read selected bank account
BankAccount ba = GetSelectedAccount();
if (ba != null)
{
decimal amount;
if (decimal.TryParse(txtWithdrawOrDepsoit.Text, out amount))
{
// Withdraw or Deposit - radio button option
if (radDeposit.Checked == true)
{
// Calls the Deposit method for the selected bank account
ProcessDeposit(ba, amount);
UpdateAccountDisplay();
txtWithdrawOrDepsoit.Clear();
lsvAccount.Select();
lsvAccount.Items[selectedAccountIndex].Selected = true;
}
else if (radWithdraw.Checked == true)
{
ProcessWithdraw(ba, amount);
UpdateAccountDisplay();
txtWithdrawOrDepsoit.Clear();
lsvAccount.Select();
lsvAccount.Items[selectedAccountIndex].Selected = true;
}
else
{
toolTip.Show("Select Deposit or Withdraw to continue.", btnWithdrawOrDeposit, 1800);
}
}
else
{
toolTip.Show("Please enter a valid doller amount\nEx: 1500.99", txtWithdrawOrDepsoit, 1800);
}
}
else
{
toolTip.Show("Please select an account from the list", btnWithdrawOrDeposit, 1800);
}
}
// Create an account button
private void btnCreateAccount_Click(object sender, EventArgs e)
{
// Prepare it for use in adding accounts method...
// get f+l name, phone, email, and amount of initial deposit
string firstName = txtFirstName.Text;
string lastName = txtLastName.Text;
string phoneNo = txtPhone.Text;
string email = txtEmail.Text;
decimal amount;
// create an owner
if (firstName != String.Empty && lastName != String.Empty && phoneNo != String.Empty && email != String.Empty)
{
BankersLibrary.Owner owner = new Owner(firstName, lastName, phoneNo, email);
// get inital deposit, and next account number (gloabl var read from text file)
if (decimal.TryParse(txtInitialBalance.Text, out amount))
{
// Determine Account Type
if (radChecking.Checked == true)
{
if (amount >= 500)
{
// add new account to accountList
CheckingAccount ca = new CheckingAccount(MASTER_ACCOUNT_ID.ToString(), amount, DateTime.Now, owner);
accountList.Add(ca);
ClearTextData_OnAddAccount();
UpdateAccountDisplay();
IncrementMasterAccountNumber();
}
else
MessageBox.Show("Can not createa a Checking Account with out an initial deposit of at least: $500");
}
else if (radSavings.Checked == true)
{
if (amount >= 1)
{
// add new account to accountList
SavingsAccount sa = new SavingsAccount(MASTER_ACCOUNT_ID.ToString(), amount, DateTime.Now, owner);
accountList.Add(sa);
ClearTextData_OnAddAccount();
UpdateAccountDisplay();
IncrementMasterAccountNumber();
}
else
MessageBox.Show("Can not create a Savings Account with out an initial deposit of at least: $1");
}
else
toolTip.Show("Select an option.", radChecking, 1800);
}
}
}
// related methods to run after creating an account
private void IncrementMasterAccountNumber()
{
MASTER_ACCOUNT_ID++;
lblAccountNumber.Text = "Next Account Number: " + MASTER_ACCOUNT_ID.ToString();
}
private void ClearTextData_OnAddAccount()
{
txtFirstName.Clear();
txtLastName.Clear();
txtInitialBalance.Clear();
txtPhone.Clear();
txtEmail.Clear();
}
private void txtTransferAccountOne_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (lsvAccount.SelectedItems.Count > 0)
{
txtTransferAccountOne.Text = lsvAccount.SelectedItems[0].SubItems[1].Text;
}
}
private void txtTransferAccountTwo_MouseDoubleClick(object sender, MouseEventArgs e)
{
if (lsvAccount.SelectedItems.Count > 0)
{
txtTransferAccountTwo.Text = lsvAccount.SelectedItems[0].SubItems[1].Text;
}
}
}
}
// New Lab 10/30/14 --- DUE: Tuesday, November 7th (11/7/14)
// Create account new project - BankAccount_Lab
// Add another project (Class Library) to the solution. Name it something like BankersLibrary
//
// Within BankersLibrary:
// Define an enum: TransactionType (Deposit, Withdraw, Trasfer)
// Define account class Owner. An Owner has: _first and _last name fields, _phoneNumber and _email
// Define account class Transaction. A Transaction has: fields _amount, _transactionDate, _transactions (of type: List<Transaction>)
// Define an abstract class, BankAcount. A BankAccount has: _accountNumber, _balance, _dateCreated, _owner (of type: List<Owner>)
// Add constructor and properties
// Add instance methods: virtual Deposit, abstract Withdraw, Transfer, and AddOwner(Owner owner)
// Add static methods: static Transfer
//
// Define account class: CheckingAccount, that inherits from BankAccount
// add fields: _minBalance
// Define its constructor and properties, and implement necessary methods
//
// Define account class: SavingsAccount, that also inherts from BankAccount
// Add fields: _interestRate
// Define its constructor, properties and methods.
//
// HINT: The transaction objects should be created and added within the methods
// Deposit, Withdraw, and Transfer, because account transaction occurs when any of those 3 actions occurs.
//
// In Form1: Create account list of accounts
// add account list view to display all the account data (Account Number, balance, creation date, owner first and last name, phone, and email)
// when you select an Account from the listview, an even should trigger that display its transaction history in account second list view.
//
// Add UI to perform the following:
// Be able to:
// Deposit money into account selected account
// Withdraw money from account selected account
// Transfer from one account to another
//
// Provide account way to save all accounts to account file and read them back.

No comments:
Post a Comment