#include <iostream>
#include <locale>
#include "bank.h"
int main()
{
Bank bank;
while (true) {
std::cout << "Welcome to the Bank of the Universe"
<< "\n";
std::cout << "Please press a button"
<< "\n";
std::cout << "'c' - Create new account"
<< "\n";
std::cout << "'d' - Deposit"
<< "\n";
std::cout << "'w' - Withdraw"
<< "\n";
std::cout << "'s' - Show balance"
<< "\n";
std::cout << "'q' - Quit program"
<< "\n";
char c;
std::cin >> c;
switch (tolower(c)) {
case 'q':
return 0;
case 'c':
bank.CreateAccount();
break;
case 'd':
bank.Deposit();
break;
case 'w':
bank.Withdraw();
break;
case 's':
bank.ShowBalance();
break;
default:
break;
}
}
}
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include <string>
class Account {
private:
double balance_;
std::string id_;
public:
explicit Account(std::string id);
double GetBalance() const noexcept;
void SetBalance(double balance) noexcept;
std::string GetId() const;
};
#endif // ACCOUNT_H_
#include "account.h"
#include <utility>
Account::Account(std::string id) : balance_{0.0}, id_{std::move(id)} {}
double Account::GetBalance() const noexcept { return balance_; }
void Account::SetBalance(const double balance) noexcept { balance_ = balance; }
std::string Account::GetId() const { return id_; }
#ifndef BANK_H_
#define BANK_H_
#include <map>
#include <memory>
#include <string>
class Account;
class Bank {
private:
std::map<std::string, std::shared_ptr<Account>> accounts_;
public:
void CreateAccount();
void Deposit() const;
void Withdraw() const;
void ShowBalance() const;
private:
std::shared_ptr<Account> ReadAccount() const;
static double ReadAmount();
static void ChangeBalance(const std::shared_ptr<Account>& account,
double amount);
static void ReportBalance(const std::string& process, double amount,
const Account& account);
static void ReportBalance(const Account& account);
static void ReportBalance(std::ostringstream& stream, const Account& account);
static void ReportInformation(const std::string& text,
const std::string& account_id);
static void ReportToConsole(const std::string& text);
static void ReportToFile(const std::string& text,
const std::string& file_name,
const std::string& account_id = "");
static void ReportInformation(std::ostream& writer, const std::string& text,
const std::string& account_id = "");
};
#endif // BANK_H_
#include "bank.h"
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include "account.h"
#include "tools.h"
void Bank::CreateAccount()
{
std::ostringstream account_id;
account_id << std::setw(4) << std::setfill('0') << (accounts_.size() + 1);
auto success = accounts_.insert(std::make_pair(
account_id.str(), std::make_shared<Account>(account_id.str())));
if (!success.second) {
std::cout << "Account: " << account_id.str() << " already exists"
<< "\n\n";
return;
}
std::string text = "Account: " + account_id.str() + " created.";
ReportInformation(text, account_id.str());
}
void Bank::Deposit() const
{
const auto account = ReadAccount();
if (account == nullptr) {
return;
}
const auto amount = ReadAmount();
ChangeBalance(account, amount);
ReportBalance("deposited", amount, *account);
}
void Bank::Withdraw() const
{
const auto account = ReadAccount();
if (account == nullptr) {
return;
}
const auto amount = ReadAmount();
ChangeBalance(account, -amount);
ReportBalance("paid", amount, *account);
}
void Bank::ShowBalance() const
{
const auto account = ReadAccount();
if (account == nullptr) {
return;
}
ReportBalance(*account);
}
std::shared_ptr<Account> Bank::ReadAccount() const
{
std::cout << "Please enter your Account number: ";
std::string account_id;
std::cin >> account_id;
std::shared_ptr<Account> account;
if (accounts_.find(account_id) != accounts_.end()) {
account = accounts_.at(account_id);
}
else {
std::cout << "Account number " << account_id << " does not exist!\n\n";
}
return account;
}
double Bank::ReadAmount()
{
double amount;
do {
std::cout << "Enter the amount: ";
std::cin >> amount;
std::cout << "\n";
if (!std::cin.fail()) {
break;
}
std::string temp;
std::cin.clear();
std::cin >> temp;
std::cout << "Please enter a number\n";
} while (true);
return amount;
}
void Bank::ChangeBalance(const std::shared_ptr<Account>& account,
const double amount)
{
auto balance = account->GetBalance();
balance += amount;
account->SetBalance(balance);
}
void Bank::ReportBalance(const std::string& process, const double amount,
const Account& account)
{
std::ostringstream stream;
stream << std::setprecision(2) << std::fixed << amount << " EUR " << process
<< ".\n";
ReportBalance(stream, account);
}
void Bank::ReportBalance(const Account& account)
{
std::ostringstream stream;
ReportBalance(stream, account);
}
void Bank::ReportBalance(std::ostringstream& stream, const Account& account)
{
stream << "Balance: " << std::setprecision(2) << std::fixed
<< account.GetBalance() << " EUR.\n";
ReportInformation(stream.str(), account.GetId());
}
void Bank::ReportInformation(const std::string& text,
const std::string& account_id)
{
ReportToConsole(text);
ReportToFile(text, "customer_receipt_" + account_id + ".txt");
ReportToFile(text, "customer_receipt.txt", account_id);
}
void Bank::ReportToConsole(const std::string& text)
{
ReportInformation(std::cout, text);
}
void Bank::ReportToFile(const std::string& text, const std::string& file_name,
const std::string& account_id)
{
const auto output_file_name = GetTempPath() + "\\" + file_name;
std::ofstream writer(output_file_name, std::ios_base::app);
ReportInformation(writer, text, account_id);
writer.close();
}
void Bank::ReportInformation(std::ostream& writer, const std::string& text,
const std::string& account_id)
{
if (!account_id.empty()) {
writer << "Account: " << account_id << ":\n";
}
writer << text << "\n\n";
}
#ifndef TOOLS_H_
#define TOOLS_H_
#include <string>
std::string GetTempPath();
#endif // TOOLS_H_
#include "tools.h"
std::string GetTempPath()
{
const char* const keys[] = {"TEMP", "TMP", "TEMPDIR", "TMPDIR"};
for (auto const& key : keys) {
const auto value = getenv(key);
if (value != nullptr) {
std::string result(value);
return result;
}
}
return "";
}