All except loaning.

Signed-off-by: Abdulkadir Furkan Şanlı <me@abdulocra.cy>
This commit is contained in:
Abdulkadir Furkan Şanlı
2022-01-04 23:34:35 +01:00
parent 87ca15456e
commit 26c5521eaa
2 changed files with 163 additions and 66 deletions
+145 -52
View File
@@ -1,7 +1,6 @@
#include "bank.h" #include "bank.h"
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <stdlib.h> // rand(), srand()
using namespace std; using namespace std;
double double
@@ -17,18 +16,16 @@ Client::getMattress ()
return underMattress; return underMattress;
} }
void auto
Bank::listClients ()
{
for (auto i : clients)
cout << "Name: " << i.id << " Current: " << i.current << endl;
cout << clients.size () << " accounts." << endl;
}
void
Bank::countEmployees () Bank::countEmployees ()
{ {
cout << employees.size () << " employees." << endl; return employees.size ();
}
auto
Bank::countClients ()
{
return clients.size ();
} }
bool bool
@@ -54,8 +51,8 @@ Bank::closeAccount (Client &x)
{ {
if (i->loans.size () != 0) if (i->loans.size () != 0)
return false; // Can't close account with outstanding loans. return false; // Can't close account with outstanding loans.
else if (this->withdraw (x, this->getCurrent (x)) == -2) else if (this->withdraw (x, this->getCurrent (x)) == -3)
return false; // Bank can't pay for withdrawal. return false; // Bank can't pay for withdrawal and wasn't bailed out.
else else
{ {
clients.erase (i); clients.erase (i);
@@ -124,17 +121,23 @@ Bank::withdraw (Client &x, const double amount)
if (amount == 0) if (amount == 0)
return 0; return 0;
if (amount < 0) if (amount < 0)
return 0; // Can't be negative. return 0; // Can't be negative.
if (current < amount) // TODO: bailout mechanism.
if (this->centralBank->reserveWithdraw (*this, ceil (amount - current))
< 0)
if (!this->centralBank->bailout (*this, ceil (amount - current)))
return -3; // Bank unable to pay, wasn't bailed out.
for (auto i = clients.begin (); i != clients.end (); i++) for (auto i = clients.begin (); i != clients.end (); i++)
if (i->current < amount) if (i->id == x.id)
return 0;
else
{ {
if (i->current < amount)
return 0;
if (current < amount)
{
if (this->centralBank->reserveWithdraw (*this,
ceil (amount - current))
< 0)
{
if (!this->centralBank->bailout (*this,
ceil (amount - current)))
return -3; // Bank unable to pay, wasn't bailed out.
}
}
i->current -= amount; i->current -= amount;
x.underMattress += amount; x.underMattress += amount;
current -= amount; current -= amount;
@@ -210,7 +213,7 @@ Gov::reserveWithdraw (Bank &x, const double amount)
return 0; return 0;
if (amount < 0) if (amount < 0)
return 0; // Can't be negative. return 0; // Can't be negative.
if (x.creditable < amount * FACTOR) if (x.creditable < (amount * FACTOR))
return -3; // Bank can't repay. return -3; // Bank can't repay.
x.creditable -= amount * FACTOR; x.creditable -= amount * FACTOR;
reserve -= amount; reserve -= amount;
@@ -218,6 +221,32 @@ Gov::reserveWithdraw (Bank &x, const double amount)
return amount; return amount;
} }
// Functions for simulating giving and receiving back loans (no interest). Used
// for testing until loans are implemented.
bool
Bank::loan (const double amount)
{
if (amount == 0)
return 0;
if (creditable < amount)
return 0;
creditable -= amount;
credited += amount;
return amount;
}
bool
Bank::unloan (const double amount)
{
if (amount == 0)
return 0;
if (credited < amount)
return 0;
creditable += amount;
credited -= amount;
return amount;
}
// Gov bailout for Bank's unfulfillable Client withdrawals. 50% chance, seeded // Gov bailout for Bank's unfulfillable Client withdrawals. 50% chance, seeded
// with time since last bailout. // with time since last bailout.
bool bool
@@ -239,58 +268,122 @@ main ()
{ {
Client abdul ("abdul"); Client abdul ("abdul");
abdul.earn (666); abdul.earn (666);
abdul.earn (10);
Employee dude ("dude"); if (abdul.getMattress () != 676)
Employee gal ("gal"); exit (1);
Gov fed; Gov fed;
Bank boa (&fed); Bank boa (&fed);
cout << fed.associate (&boa) << endl; // Can't associate twice. if (fed.associate (&boa))
exit (1); // Can't associate twice.
cout << boa.openAccount (abdul) << endl; if (boa.openAccount (abdul))
boa.countEmployees (); // Insufficient employee capacity. exit (1); // Over employee capacity.
Employee dude ("dude");
Employee gal ("gal");
boa.hire (dude); boa.hire (dude);
boa.countEmployees (); if (boa.countEmployees () != 1)
exit (1);
boa.fire (gal); // Can't fire non-employed. boa.fire (gal); // Can't fire non-employed.
boa.countEmployees (); if (boa.countEmployees () != 1)
exit (1);
boa.fire (dude); boa.fire (dude);
boa.countEmployees (); if (boa.countEmployees () != 0)
exit (1);
boa.hire (gal); boa.hire (gal);
boa.hire (dude); boa.hire (dude);
boa.hire (dude); // Can't hire employed. boa.hire (dude); // Can't hire employed.
boa.countEmployees (); if (boa.countEmployees () != 2)
exit (1);
cout << boa.openAccount (abdul) << endl; if (boa.openAccount (abdul) != 1)
cout << boa.openAccount (abdul) exit (1);
<< endl; // Can't open existing client account. if (boa.openAccount (abdul) != 0)
boa.listClients (); exit (1); // Can't open existing client account.
if (boa.countClients () != 1)
exit (1);
cout << abdul.getMattress () << " under mattress." << endl; if (abdul.getMattress () != 676)
exit (1);
boa.deposit (abdul, 500); boa.deposit (abdul, 500);
cout << boa.getCurrent (abdul) << " in bank account." << endl; if (boa.getCurrent (abdul) != 500)
cout << abdul.getMattress () << " under mattress." << endl; exit (1);
cout << boa.getCurrent () << " in bank current accounts." << endl; if (abdul.getMattress () != 176)
exit (1);
if (boa.getCurrent () != 500)
exit (1);
boa.withdraw (abdul, 30); boa.withdraw (abdul, 30);
Client jane ("jane"); Client jane ("jane");
jane.earn (1000); jane.earn (1000);
cout << jane.getMattress () << " under mattress." << endl;
boa.openAccount (jane); boa.openAccount (jane);
boa.deposit (jane, 500); boa.deposit (jane, 500);
cout << boa.getCurrent (abdul) << " in bank account." << endl; if (boa.getCurrent (abdul) != 470)
cout << abdul.getMattress () << " under mattress." << endl; exit (1);
cout << boa.getCurrent (jane) << " in bank account." << endl; if (abdul.getMattress () != 206)
cout << jane.getMattress () << " under mattress." << endl; exit (1);
cout << boa.getCurrent () << " in bank current accounts." << endl; if (boa.getCurrent (jane) != 500)
exit (1);
if (jane.getMattress () != 500)
exit (1);
if (boa.getCurrent () != 970)
exit (1);
Client joe ("joe"), bob ("bob"), frank ("frank"); Client joe ("joe"), bob ("bob"), frank ("frank");
boa.openAccount (joe); boa.openAccount (joe);
boa.openAccount (joe); // Second open call.
boa.openAccount (bob); boa.openAccount (bob);
boa.openAccount (frank); // Insufficient employee capacity. Sorry frank. boa.openAccount (frank); // Not added (5th client).
boa.listClients (); if (boa.countClients () != 4)
boa.closeAccount (abdul); exit (1); // Over employee capacity.
boa.listClients ();
boa.closeAccount (abdul); // Success
if (boa.countClients () != 3)
exit (1);
if (boa.getCurrent () != 500)
exit (1);
if (abdul.getMattress () != 676)
exit (1);
fed.reserveDeposit (boa, 250);
if (fed.getReserve () != 250)
exit (1);
if (boa.getCreditable () != 1500)
exit (1);
fed.reserveWithdraw (boa, 125);
fed.reserveWithdraw (boa, 1000); // Can't repay.
if (fed.getReserve () != 125)
exit (1);
if (boa.getCreditable () != 750)
exit (1);
boa.loan (250);
bool bailed = boa.closeAccount (jane); // Bank can't pay, Gov may bail out.
if (bailed == 0 // Not bailed out.
&& (jane.getMattress () != 500 || boa.getCreditable () != 500
|| boa.getCredited () != 250 || boa.getCurrent () != 375))
exit (1);
if (bailed == 1 // Bailed out.
&& (jane.getMattress () != 1000 || boa.getCreditable () != 500
|| boa.getCredited () != 250 || boa.getCurrent () != 0))
exit (1);
joe.earn (1000);
boa.deposit (joe, 1000);
fed.reserveDeposit (boa, 500);
boa.loan (100);
boa.withdraw (joe, 50); // Test withdrawal bank can pay.
if (joe.getMattress () != 50)
exit (1);
boa.withdraw (
joe, 500); // Test withdrawal bank can pay by withdrawing from reserves.
if (joe.getMattress () != 550)
exit (1);
// Run until both 0 and 1 are seen, in order to test both code paths for
// bailout.
cout << "Bailed out: " << bailed << ", all others successful." << endl;
return 0; return 0;
} }
+18 -14
View File
@@ -22,7 +22,7 @@ public:
private: private:
time_t lastBailout = 0; // Time since last bailout. time_t lastBailout = 0; // Time since last bailout.
double reserve = 0; // Total in bank reserves. double reserve = 0; // Total in bank reserves.
std::vector<Bank *> banks; std::vector<Bank *> banks;
}; };
@@ -42,13 +42,17 @@ public:
bool fire (Employee &x); bool fire (Employee &x);
bool openAccount (Client &x); bool openAccount (Client &x);
bool closeAccount (Client &x); bool closeAccount (Client &x);
bool newCredit (const std::string id, const double amount, // TODO: implement loans, for now there is placeholder loan() and unloan(),
const int installments, const int days, // in order to simulate loaning and test bailout mechanism.
const float interest); // interest is additional interest on
// top of Gov rate. // bool newCredit (const std::string id, const double amount,
double payInstallment (const int index); // const int installments, const int days,
void countEmployees (); // const float interest);
void listClients (); // double payInstallment (const int index);
auto countEmployees ();
auto countClients ();
bool loan (const double amount);
bool unloan (const double amount);
private: private:
Gov *centralBank; Gov *centralBank;
@@ -56,13 +60,13 @@ private:
double current = 0; // Total current accts. of clients. double current = 0; // Total current accts. of clients.
double creditable = 0; // Amount able to be loaned to clients. double creditable = 0; // Amount able to be loaned to clients.
double credited = 0; // Amount loaned. double credited = 0; // Amount loaned.
struct creditRecord struct creditRecord // TODO: implement loans, currently this struct is a dud.
{ {
time_t start; // time_t start;
long interval; // Interval of payments in number of seconds. // long interval; // Interval of payments in number of seconds.
double amount; // double amount;
int installments; // int installments;
float interest; // float interest;
}; };
struct clientRecord struct clientRecord
{ {