In: Computer Science
Programming Language: C#
CheckingAccount class
You will implement the CheckingAccount Class in Visual Studio. This is a sub class is derived from the Account class and implements the ITransaction interface. There are two class variables i.e. variables that are shared but all the objects of this class. A short description of the class members is given below:
CheckingAccount Class |
Fields |
$- COST_PER_TRANSACTION = 0.05 : double $- INTEREST_RATE = 0.005 : double - hasOverdraft: bool |
Methods |
+ «Constructor» CheckingAccount(balance = 0 : double, hasOverdraft = false: bool) + Deposit(amount : double, person : Person) : void + Withdraw(amount : double, person : Person) : void + PrepareMonthlyReport(amount : double, person : Person) : void |
Fields:
Methods:
This definition hides the corresponding member in the parent class because the base class implementation is needed for this method as well as the Withdraw() method |
In a real-world application, the transaction objects would be archived before clearing. |
This method does not take any parameter nor does it display anything
SavingAccount class
You will implement the SavingAccount Class in Visual Studio. This is a sub class derived from the Account class and implements the ITransaction interface. Again, there are two class variables. A short description of the class members is given below:
SavingAccount Class → Account, ITransaction |
Fields |
$- COST_PER_TRANSACTION : double $- INTEREST_RATE : double |
Methods |
+ «Constructor» SavingAccount(balance = 0 : double) + Deposit(amount : double, person : Person) : void + Withdraw(amount : double, person : Person) : void + PrepareMonthlyReport(amount : double, person : Person) : void |
Fields:
Methods:
This method does not take any parameters, nor does it display anything
Working code implemented in C# and appropriate comments provided for better understanding:
Here I am attaching code for these files:
Source code for main.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("---- START RUNING CODE FROM PROGRAM.CS
-----");
//testing the visa account
Console.WriteLine("\nAll acounts:");
Bank.PrintAccounts();
Console.WriteLine("----- PASSED PRINT ACCOUNTS -----");
Console.WriteLine("\nAll Users:");
Console.WriteLine();
Bank.PrintPersons();
Console.WriteLine();
Console.WriteLine("----- PASSED PRINT PERSONS -----");
Person p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10;
p0 = Bank.GetPerson("Narendra");
p1 = Bank.GetPerson("Ilia");
p2 = Bank.GetPerson("Tom");
p3 = Bank.GetPerson("Syed");
p4 = Bank.GetPerson("Arben");
p5 = Bank.GetPerson("Patrick");
p6 = Bank.GetPerson("Yin");
p7 = Bank.GetPerson("Hao");
p8 = Bank.GetPerson("Jake");
p9 = Bank.GetPerson("Joanne");
p10 = Bank.GetPerson("Nicoletta");
Console.WriteLine();
Console.WriteLine("----- PASSED PERSON REQUEST -----");
p0.Login("123");
p1.Login("234");
p2.Login("345");
p3.Login("456");
p4.Login("567");
p5.Login("678");
p6.Login("789");
p7.Login("890");
p10.Login("234");
p8.Login("901");
Console.WriteLine();
Console.WriteLine("----- PASSED LOGINS -----");
//a visa account
VisaAccount a = Bank.GetAccount("VS-100000") as VisaAccount;
a.DoPayment(1500, p0);
a.DoPurchase(200, p1);
a.DoPurchase(25, p2);
a.DoPurchase(15, p0);
a.DoPurchase(39, p1);
a.DoPayment(400, p0);
Console.WriteLine(a);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR VS-100000
-----");
VisaAccount aa =
(VisaAccount)Bank.GetAccount("VS-100001");
aa.DoPayment(500, p0);
aa.DoPurchase(25, p3);
aa.DoPurchase(20, p4);
aa.DoPurchase(15, p5);
Console.WriteLine(aa);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR VS-100001
-----");
//a saving account
ITransaction b = Bank.GetAccount("SV-100002") as
ITransaction;
b.Withdraw(300, p6);
b.Withdraw(32.90, p6);
b.Withdraw(50, p7);
b.Withdraw(111.11, p8);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100002
-----");
b = (SavingAccount)Bank.GetAccount("SV-100003");
b.Deposit(300, p3); //ok even though p3 is not a holder
b.Deposit(32.90, p2);
b.Deposit(50, p5);
b.Withdraw(111.11, p10);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100003
-----");
//a checking account
ITransaction c = Bank.GetAccount("CK-100004") as
ITransaction;
c.Deposit(33.33, p7);
c.Deposit(40.44, p7);
c.Withdraw(150, p2);
c.Withdraw(200, p4);
c.Withdraw(645, p6);
c.Withdraw(350, p6);
Console.WriteLine(c);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100004
-----");
c = Bank.GetAccount("CK-100005") as ITransaction;
c.Deposit(33.33, p8);
c.Deposit(40.44, p7);
c.Withdraw(450, p10);
c.Withdraw(500, p8);
c.Withdraw(645, p10);
c.Withdraw(850, p10);
Console.WriteLine(c);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100005
-----");
a = Bank.GetAccount("VS-100006") as VisaAccount;
a.DoPayment(700, p0);
a.DoPurchase(20, p3);
a.DoPurchase(10, p1);
a.DoPurchase(15, p1);
Console.WriteLine(a);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100006
-----");
b = (ITransaction)Bank.GetAccount("SV-100007");
b.Deposit(300, p3); //ok even though p3 is not a holder
b.Deposit(32.90, p2);
b.Deposit(50, p5);
b.Withdraw(111.11, p7);
Console.WriteLine(b);
Console.WriteLine();
Console.WriteLine("----- PASSED TRANSACTIONS FOR SV-100007
-----");
//The following will cause exception
Console.WriteLine("\n\nExceptions:");
try
{
p8.Login("911"); //incorrect password
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
p3.Logout();
a.DoPurchase(12.5, p3); //exception user is not logged in
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
a.DoPurchase(12.5, p0); //user is not associated with this
account
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
a.DoPurchase(5825, p4); //credit limit exceeded
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
c.Withdraw(1500, p6); //no overdraft
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
Bank.GetAccount("CK-100018"); //account does not exist
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
try
{
Bank.GetPerson("Trudeau"); //user does not exist
}
catch (AccountException e)
{
Console.WriteLine(e.Message);
}
foreach (Account account in Bank.ACCOUNTS)
{
Console.WriteLine("\nBefore PrepareMonthlyReport()");
Console.WriteLine(account);
Console.WriteLine("\nAfter PrepareMonthlyReport()");
account.PrepareMonthlyReport(); //all transactions are cleared,
balance changes
Console.WriteLine(account);
}
}
}
}
Source code for Bank.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
static class Bank
{
// fields properties
public static readonly List<Account> ACCOUNTS;
public static readonly List<Person> USERS;
// constructor
static Bank()
{
//initialize the USERS collection
USERS = new List<Person>()
{
new Person("Narendra", "1234-5678"), //0
new Person("Ilia", "2345-6789"), //1
new Person("Tom", "3456-7890"), //2
new Person("Syed", "4567-8901"), //3
new Person("Arben", "5678-9012"), //4
new Person("Patrick", "6789-0123"), //5
new Person("Yin", "7890-1234"), //6
new Person("Hao", "8901-2345"), //7
new Person("Jake", "9012-3456"), //8
new Person("Joanne", "1224-5678"), //9
new Person("Nicoletta", "2344-6789"), //10
};
//initialize the ACCOUNTS collection
ACCOUNTS = new List<Account>()
{
new VisaAccount(), //VS-100000
new VisaAccount(150, -500), //VS-100001
new SavingAccount(5000), //SV-100002
new SavingAccount(), //SV-100003
new CheckingAccount(2000), //CK-100004
new CheckingAccount(1500, true), //CK-100005
new VisaAccount(50, -550), //VS-100006
new SavingAccount(1000), //SV-100007
};
//associate users with accounts
ACCOUNTS[0].AddUser(USERS[0]);
ACCOUNTS[0].AddUser(USERS[1]);
ACCOUNTS[0].AddUser(USERS[2]);
ACCOUNTS[1].AddUser(USERS[3]);
ACCOUNTS[1].AddUser(USERS[4]);
ACCOUNTS[1].AddUser(USERS[5]);
ACCOUNTS[2].AddUser(USERS[6]);
ACCOUNTS[2].AddUser(USERS[7]);
ACCOUNTS[2].AddUser(USERS[8]);
ACCOUNTS[3].AddUser(USERS[9]);
ACCOUNTS[3].AddUser(USERS[10]);
ACCOUNTS[4].AddUser(USERS[2]);
ACCOUNTS[4].AddUser(USERS[4]);
ACCOUNTS[4].AddUser(USERS[6]);
ACCOUNTS[5].AddUser(USERS[8]);
ACCOUNTS[5].AddUser(USERS[10]);
ACCOUNTS[6].AddUser(USERS[1]);
ACCOUNTS[6].AddUser(USERS[3]);
ACCOUNTS[7].AddUser(USERS[5]);
ACCOUNTS[7].AddUser(USERS[7]);
}
// methods - acitons
public static void PrintAccounts()
{
foreach (Account account in ACCOUNTS)
{
Console.WriteLine(account);
}
}
public static void PrintPersons()
{
foreach (Person person in USERS)
{
Console.WriteLine(person);
}
}
public static Person GetPerson(string name)
{
foreach (Person person in USERS)
{
if (person.Name == name)
{
Console.WriteLine(person);
return person;
}
}
throw new
AccountException(ExceptionEnum.USER_DOES_NOT_EXIST);
}
public static Account GetAccount(string number)
{
foreach (Account account in ACCOUNTS)
{
if (account.Number == number)
{
return account;
}
}
throw new
AccountException(ExceptionEnum.ACCOUNT_DOES_NOT_EXIST);
}
}
}
Source code for Person.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class Person
{
// fields and properties for person object
private string password;
public string SIN { get; }
public string Name { get; }
public bool IsAuthenticated { get; private set; }
// constructor for person object
public Person(string name, string SIN)
{
Name = name;
this.SIN = SIN;
password = SIN.Substring(0,3);
}
// methods - actions of the person class
public void Login(string password)
{
try
{
if (password != this.password)
{
IsAuthenticated = false;
throw new AccountException(ExceptionEnum.PASSWORD_INCORRECT);
}
else
{
IsAuthenticated = true;
Console.WriteLine($"{Name,-15}\thas logged IN.");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public void Logout()
{
IsAuthenticated = false;
Console.WriteLine($"{Name,-15}\thas logged OUT.");
}
public override string ToString()
{
return $"{Name}";
}
}
}
Source code for Account.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
abstract class Account
{
// fields and properties for the account class
public readonly List<Person> users = new
List<Person>();
public readonly List<Transaction> transactions = new
List<Transaction>();
private static int LAST_NUMBER = 100_000;
public double Balance { get; protected set; }
public double LowestBalance { get; protected set; }
public string Number { get; }
// constructor of the account class
public Account(string type, double balance)
{
Number = $"{type}{LAST_NUMBER}";
LAST_NUMBER++;
Balance = balance;
LowestBalance = balance;
}
// methos - actions of the account class
public void Deposit(double amount, Person person)
{
Balance += amount;
if (Balance < LowestBalance)
{
LowestBalance = Balance;
}
transactions.Add(new Transaction(Number, amount, person,
DateTime.Now));
}
public void AddUser(Person person)
{
users.Add(new Person(person.Name, person.SIN));
}
public bool IsUser(string name)
{
foreach (Person person in users)
{
if (person.Name == name)
{
return true;
}
}
return false;
}
public abstract void PrepareMonthlyReport();
public override string ToString()
{
return $"\n--- ACCOUNT INFO:\n" +
$"Account Number:\t{Number}\n" +
$"Users:\t\t{string.Join(", ", users)}\n" +
$"Balance:\t{Balance:C}\n";
}
}
}
Source code for SavingAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class SavingAccount : Account, ITransaction
{
// fields and properties of the saving account class
private double COST_PER_TRANSACTION = 0.05;
private double INTEREST_RATE = 0.015;
// constructor for the savings account class
public SavingAccount(double balance = 0) : base("SV-",
balance)
{
}
// methods - acitons of the sabings account class
public new void Deposit(double amount, Person person)
{
base.Deposit(amount, person);
}
public void Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance)
{
throw new AccountException(ExceptionEnum.NO_OVERDRAFT);
}
else
{
base.Deposit(amount * -1, person); // -1 to withdraw the amount of
the account
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public override void PrepareMonthlyReport()
{
double serviceCharge, interests;
serviceCharge = COST_PER_TRANSACTION * transactions.Count;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance + interests - serviceCharge;
transactions.Clear();
}
}
}
Source code for CheckingAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class CheckingAccount : Account, ITransaction
{
// fields and properties of the checking account class
private double COST_PER_TRANSACTION = 0.05;
private double INTEREST_RATE = 0.005;
private bool hasOverDraft;
// constructor of the checking account class
public CheckingAccount(double balance = 0, bool hasOverDraft =
false) : base("CK-", balance) // takes the arguments from the
parent class 'account'
{
this.hasOverDraft = hasOverDraft;
}
// mthods - actions of the checking account class
public new void Deposit(double amount, Person person)
{
base.Deposit(amount, person); // calls the deposit method from the
parent class
}
public void Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance || hasOverDraft == false)
{
throw new AccountException(ExceptionEnum.NO_OVERDRAFT);
}
else
{
base.Deposit(amount * -1, person); // -1 to withdraw the amount of
the account
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public override void PrepareMonthlyReport()
{
double serviceCharge, interests;
serviceCharge = COST_PER_TRANSACTION * transactions.Count;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance + interests - serviceCharge;
transactions.Clear();
}
}
}
Source code for Transaction.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
// interface for the transaction class
interface ITransaction
{
void Withdraw(double amount, Person person);
void Deposit(double amount, Person person);
}
class Transaction
{
// flieds and properties of the class transactions
public string AccountNumber { get; }
public double Amount { get; }
public Person Originator { get; }
public DateTime Time { get; }
// constructor for the transaction class
public Transaction(string accountNumber, double amount, Person
person, DateTime time)
{
AccountNumber = accountNumber;
Amount = amount;
Originator = person;
Time = time;
}
// methods - actions for the transaction class
public override string ToString()
{
return $"\n--- TRANSACTION INFO:\n" +
$"Date:\t\t\t{Time.ToShortTimeString()}\n" +
$"Name:\t\t\t{Originator}\n" +
$"Account Number:\t\t{AccountNumber}\n" +
$"Transaction:\t\t{Amount:C}\n";
}
}
}
Source code for VisaAccount.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
class VisaAccount : Account, ITransaction
{
// fields and properties of visa account class
private double creditLimit;
private double INTEREST_RATE = 0.1995;
// constructor for visa account class
public VisaAccount(double balance = 0, double creditLimit = 1200) :
base("VS-", balance)
{
this.creditLimit = creditLimit;
}
// methods - acitons of the sabings account class
public void DoPayment(double amount, Person person)
{
base.Deposit(amount, person);
}
public void DoPurchase(double amount, Person person)
{
// throwing exceptions as rules specifies
try
{
// for (int i = 0; i < users.Count; i++)
//{
if (users.Contains<Person>(person) == true)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > creditLimit)
{
throw new
AccountException(ExceptionEnum.CREDIT_LIMIT_HAS_BEEN_EXCEEDED);
}
else
{
base.Deposit(-amount, person); // -1 to withdraw the amount of the
account
}
//}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
void ITransaction.Deposit(double amount, Person person)
{
base.Deposit(amount, person);
}
void ITransaction.Withdraw(double amount, Person person)
{
// throwing exceptions as rules specifies
if (users.Contains<Person>(person) == false)
{
throw new
AccountException(ExceptionEnum.NAME_NOT_ASSOCIATED_WITH_ACCOUNT);
// exceptions are brought from exceptions class
}
else if (person.IsAuthenticated == false)
{
throw new AccountException(ExceptionEnum.USER_NOT_LOGGED_IN);
}
else if (amount > Balance)
{
throw new
AccountException(ExceptionEnum.CREDIT_LIMIT_HAS_BEEN_EXCEEDED);
}
else
{
base.Deposit(-amount, person); // -1 to withdraw the amount of the
account
}
}
public override void PrepareMonthlyReport()
{
double interests;
interests = INTEREST_RATE * LowestBalance / 12;
Balance = Balance - interests;
transactions.Clear();
}
}
}
Source code for AccountException.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Assignment04_BankApp
{
public enum ExceptionEnum
{
ACCOUNT_DOES_NOT_EXIST,
CREDIT_LIMIT_HAS_BEEN_EXCEEDED,
NAME_NOT_ASSOCIATED_WITH_ACCOUNT,
NO_OVERDRAFT,
PASSWORD_INCORRECT,
USER_DOES_NOT_EXIST,
USER_NOT_LOGGED_IN
}
class AccountException : Exception
{
public AccountException(ExceptionEnum reason) :
base(reason.ToString())
{
}
}
}
Sample Output Screenshots:
Hope it helps, if you like the answer give it a thumbs up. Thank you.