#include <iostream>
#include <fstream>
std::string fileName;
struct transaction {std::string description; std::string category; std::string incomeorexpense; double amount; };
std::vector<transaction> transactions; // vector of type transaction to store all transactions
void add_transaction (transaction trans) {
// takes in a transaction and adds it to the vector of all transactions
transactions.push_back(trans);
}
void view_transactions (){
int transactionscount = 0;
int expensescount = 0;
int incomecount = 0;
for (transaction t : transactions){
transactionscount ++;
if (t.incomeorexpense == "income"){
incomecount++;
}
else if (t.incomeorexpense=="expense") {
expensescount ++;
}
}
if (transactionscount == 0) {
std::cout << "\nThere are no transactions to display.\n";
}
else {
std::cout<<" TRANSACTIONS: \n ==============";
if (expensescount > 0){
std::cout << "\n $ spent \n___________________________";
for (transaction t : transactions) {
if (t.incomeorexpense =="expense"){
std::cout << "\nDescription: " << t.description << "\nCategory: " << t.category <<"\nAmount: " << t.amount << "\n";
}
}
}
if (incomecount > 0) {
std::cout << "\n $ earned \n___________________________";
for (transaction t : transactions) {
if (t.incomeorexpense =="income"){
std::cout << "\nDescription: " << t.description << "\nCategory: " << t.category <<"\nAmount: " << t.amount <<"\n";
}
}
}
}
}
void savetofile (std::string fileName) {
std::ofstream outFile;
outFile.open(fileName+".txt"); // creates a file called transactions.txt and saves all transactions in the vector to it
for (transaction t : transactions) {
outFile << "\n" << t.description << " " << t.category << " "<< t.incomeorexpense<< " " << t.amount ;
}
outFile.close();
}
void loadfromfile (std::string fileName) {
std::ifstream inFile; // inFile reads from a file
inFile.open(fileName+".txt");
std::string line;
int lines = 0;
int count = 0;
while (std::getline(inFile, line)) {
lines++; // counts number of lines in text file
}
inFile.close();
inFile.open(fileName+".txt");
while (std::getline(inFile, line)){
std::string d;
std::string c;
std::string i;
double a;
inFile >> d;
inFile >> c;
inFile>> i;
inFile >> a;
transaction temp = {d,c,i,a}; // adds each line to the struct in it's respective place
add_transaction(temp);
}
inFile.close();
}
bool sortByCategory (const transaction &a, const transaction &b) {
// can be put into std::sort as a way to compare 2 categories alphabetically
return a.category < b.category;
}
void displaycategoryinfo (std::string Category ){
double total=0;
int numoftransactions=0; // for average calculation
for (transaction t : transactions) {
if (t.category == Category) {
// ensures that the category is correct before adding it to calculations
numoftransactions+=1;
if (t.incomeorexpense== "income") {
total+=t.amount;
}
if (t.incomeorexpense=="expense") {
total-=t.amount;
}
}
}
std::cout<<"The total spent/earned on " << Category << " is $" << total;
std::cout<<"\nThe average money spent/earned per transaction on " << Category << " is " << total/numoftransactions;
}
void displaystatistics (std::vector <transaction> transactions) {
double totalspent = 0;
double totalearned = 0;
int positivetransactions=0;
int negativetransactions =0;
for (transaction t: transactions){
if (t.incomeorexpense == "income") {
// positive value (total spent)
totalearned += t.amount;
positivetransactions+=1;
}
else if (t.incomeorexpense == "expense") {
// negative value (total earned)
totalspent -= t.amount;
negativetransactions+=1;
}
}
std::cout << "\nTotal spent: " << (totalspent) << "\nTotal earned: " << totalearned;
std::cout<< "\nAverage cost of an expense: " << totalearned/positivetransactions;
std::cout<< "\nAverage cost of money gained: " << totalspent/negativetransactions;
}
void viewbudget(std::string budgettype, double goal){
if (budgettype == "savingsgoal"){
double total = 0;
for (transaction t : transactions) {
if (t.incomeorexpense == "income") {
total+=t.amount;
}
if (t.incomeorexpense=="expense") {
total=total-t.amount;
}
}
std::cout << "\nGoal: " << goal << "\nAmount saved: " << total;
if (total == goal) {
std::cout << "\nGreat job! You saved exactly how much you were supposed to!" ;
}
else if (total > goal) {
std::cout << "\nAmazing job! You saved more than your savings goal! ";
}
else if (total == goal+15 | total == goal -15){
std::cout << "\nYou were pretty close to your goal! Good job.";
}
else {
std::cout << "\nYou did not reach your goal! Do better saving next time!";
}
}
if (budgettype == "spendlim") {
double total = 0;
for (transaction t : transactions) {
if (t.incomeorexpense == "expense") {
total+=t.amount;
}
}
std::cout << "\nGoal: " << goal << "\nAmount spent: " << total;
if (total == goal) {
std::cout << "\nGreat job! You didn't pass your spending goal!" ;
}
else if (total < goal) {
std::cout << "\nAmazing job! You spent less than your goal! ";
}
else if (total == goal+15 ){
std::cout << "\nYou were pretty close to your goal! Good job.";
}
else {
std::cout << "\nYou spent too much money!!";
}
}
}
int main (int argc, char**argv) {
int answer1 = 0;
double budgetgoal;
std::string budgettype;
std::cout << "\nHi there, welcome to the transaction and budget tracker! ";
std::cout << "\nBefore we begin, what kind of budget do you want? ";
std::cout << "\n1 - Spending limit\n2 - Overall savings goal\n----------\n" ;
while (answer1 != 1 && answer1 != 2){
std::cin >> answer1;
if (answer1 != 1 && answer1 != 2){
std::cout << "Invalid entry... enter '1' or '2'.\n";
}
}
if (answer1 == 1){
std::cout << "\n\nWhat is your spending limit for this time period? $";
std::cin >> budgetgoal;
budgettype = "spendlim";
}
else if (answer1 == 2) {
std::cout << "\nHow much do you want to save in this time period? ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin >> budgetgoal;
budgettype = "savingsgoal";
}
std::cout <<"\n\nEnter the name of the file you would like to load or a new file you would like to create: \n(no need to include '.txt' )\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(std::cin,fileName);
loadfromfile(fileName);
std::string ans;
// Clear the input buffer up to a new line chaacter
do{
std::cout << "\n\nWhat do you want to do? (enter number) \n1 - add a transaction\n2 - view transactions\n3 - save transactions\n4 - display category info\n5 - display spending statistics\n6 - view budget \n7 - exit\n\n";
std::getline(std::cin,ans);
if (ans == "1") {
std::string d;
std::string c;
std::string i;
std::string x;
double a;
std::cout<< "\n-----------\n";
std::cout << "Enter transaction description: ";
std::getline(std::cin,d);
std::cout << "Enter transaction category: ";
std::getline(std::cin,c);
std::cout << "\nWas this \n1 - income \n2 - expense ? \n(enter the #) ";
std::cin>>i;
if (i != "1" && i != "2"){
std::cout<< "invalid choice, try again";
}
else if (i == "1"){
x = "income";
}
else if (i =="2") {
x = "expense";
}
if (x =="income"){
std::cout << "\nEnter money gained: ";
}
else if (x =="expense"){
std::cout <<"\nEnter money spent: ";
}
std::cin >> a;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
transaction trans = {d,c,x,a};
add_transaction (trans);
std::cout << "Transaction saved!\n";
}
if (ans == "2") {
view_transactions();
}
if (ans == "3") {
savetofile(fileName);
std::cout << "Transactions saved!";
}
if (ans == "4") {
std::string categorychoice;
std::cout << "\nWhich category do you want to show?\n";
std::sort(transactions.begin(), transactions.end(), sortByCategory);
// will organize alphabetically so transactions with the same category are beside each other
// easier to make sure that each category is only read once
std::string temp;
// will hold the value of the previous category to compare if they are the same
for (transaction t : transactions) {
//outputs all categories only once
if (t.category != temp) {
std::cout << "- " << t.category << "\n";
temp = t.category;
}
}
std::cout<<"\n";
std::cin >> categorychoice;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::string isthatacategory="no";
// will only be 'yes' if the category inputted is found in the vector of tranactions
for (transaction t : transactions) {
if (t.category == categorychoice) {
isthatacategory = "yes";
}
}
if (isthatacategory=="yes"){
displaycategoryinfo(categorychoice);
}
else {
std::cout<<"\nNot a valid choice, try again.";
}
}
if (ans =="5"){
displaystatistics(transactions);
}
if (ans =="6"){
viewbudget(budgettype, budgetgoal);
}
} while (ans!= "7");
}