-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMapDatabase.cpp
More file actions
281 lines (238 loc) · 11.3 KB
/
MapDatabase.cpp
File metadata and controls
281 lines (238 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#include <iostream>
#include <vector>
#include <utility>
#include <iomanip>
#include <fstream>
#include <sstream>
#include "MapDatabase.h"
using namespace std;
MapDatabase::MapDatabase(int size) : capacity(size), size(0) {
hashTable.resize(capacity, nullptr);
}
int MapDatabase::hashFunction(int key) {
return key % capacity;
}
void MapDatabase::resizeHashtable() {
capacity *= 2;
vector<Node*> newHashtable(capacity, nullptr);
for (auto oldNode : hashTable) {
Node* currentNode = oldNode;
while (currentNode) {
Node* temp = currentNode->next;
int index = hashFunction(currentNode->key);
currentNode->next = newHashtable[index];
newHashtable[index] = currentNode;
currentNode = temp;
}
}
hashTable = newHashtable;
}
void MapDatabase::buy(int id, int q, float c) {
int index = hashFunction(id);
//Checks if product exists
if (!hashTable[index]) {
hashTable[index] = new Node(id, Product(id, q, c));
}
else {
//Check for collision in linked list, and traverse if so
Node* currentNode = hashTable[index];
while (currentNode) {
//Product exists, call buy function from Product class
if (currentNode->key == id) {
currentNode->value.buy(q, c);
return;
}
//Go to next node in list
if (currentNode->next) {
currentNode = currentNode->next;
}
else {
break;
}
}
//Add product to end of linked list
currentNode->next = new Node(id, Product(id, q, c));
}
size++;
//Check if resizing is needed
float currLoadFactor = size / capacity;
if (currLoadFactor >= loadFactor) {
resizeHashtable();
}
}
bool MapDatabase::sell(int id, int q, float c) {
int index = hashFunction(id);
//Check if product does not exist
if (!hashTable[index]) {
return false;
}
else {
Node* currentNode = hashTable[index];
while (currentNode) {
//Check if product found
if (currentNode->key == id) {
//Check if quantity is enough for sell through Product buy function
if (currentNode->value.sell(q, c)) {
return true;
}
else {
return false;
}
}
//Go to next node in linked list
currentNode = currentNode->next;
}
}
return false;
}
bool MapDatabase::printItem(int id) {
int index = hashFunction(id);
//Check if product does not exist
if (!hashTable[index]) {
return false;
}
else {
Node* currentNode = hashTable[index];
while (currentNode) {
if (currentNode->key == id) {
cout << left << setw(30) << "ID: " << currentNode->key << '\n';
cout << left << setw(30) << "Current Stock: " << currentNode->value.getQuantity() - currentNode->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Amount Bought: " << currentNode->value.getQuantity() << '\n';
cout << left << setw(30) << "Amount Sold: " << currentNode->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Average Cost: " << "$" << fixed << setprecision(2) << currentNode->value.getAverageCost() << '\n';
cout << left << setw(30) << "Average Sale: " << "$" << fixed << setprecision(2) << currentNode->value.getAverageSale() << '\n';
cout << left << setw(30) << "Sold Item Profit: " << "$" << fixed << setprecision(2) << currentNode->value.getAverageSale() * currentNode->value.getQuantitySold() - currentNode->value.getAverageCost() * currentNode->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Unsold Inventory Cost: " << "$" << fixed <<setprecision(2) << currentNode->value.getAverageCost() * (currentNode->value.getQuantity() - currentNode->value.getQuantitySold()) << '\n' << '\n';
return true;
}
currentNode = currentNode->next;
}
}
//Return false if product was not found
return false;
}
void MapDatabase::printSalesReport() {
//Define a vector of pairs to store the collected information for sales report calculation
vector<pair<string, float>> salesInfo = {
{"[0] = Costs", 0.0f},
{"[1] = Revenue", 0.0f},
{"[2] = How Many items bought", 0},
{"[3] = How many items sold", 0},
{"[4] = product ID with the most sales", -1},
{"[5] = sale amount of 4", 0.0f},
{"[6] = product ID with the highest '%' over retail", -1},
{"[7] = '%' over retail of 6", 0.0f},
{"[8] = min remaining inventory revenue", 0.0f}
};
cout << "\nInventory:\n" << endl;
//Iterating through the hashtable
for (auto& currentNode : hashTable) {
Node* current = currentNode;
while (current) {
//Calculate and accumulate total costs and revenue
cout << left << setw(30) << "ID: " << current->key << '\n';
cout << left << setw(30) << "Current Stock: " << current->value.getQuantity() - current->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Amount Bought: " << current->value.getQuantity() << '\n';
cout << left << setw(30) << "Amount Sold: " << current->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Average Cost: " << "$" << fixed << setprecision(2) << current->value.getAverageCost() << '\n';
cout << left << setw(30) << "Average Sale: " << "$" << fixed << setprecision(2) << current->value.getAverageSale() << '\n';
cout << left << setw(30) << "Sold Item Profit: " << "$" << fixed << setprecision(2) << current->value.getAverageSale() * current->value.getQuantitySold() - current->value.getAverageCost() * current->value.getQuantitySold() << '\n';
cout << left << setw(30) << "Unsold Inventory Cost: " << "$" << fixed << setprecision(2) << current->value.getAverageCost() * (current->value.getQuantity() - current->value.getQuantitySold()) << '\n' << '\n';
salesInfo[0].second += current->value.getAverageCost() * current->value.getQuantity();
salesInfo[1].second += current->value.getAverageSale() * current->value.getQuantitySold();
salesInfo[2].second += current->value.getQuantity();
salesInfo[3].second += current->value.getQuantitySold();
//Check for product with most sales
if (current->value.getQuantitySold() > salesInfo[5].second) {
salesInfo[4].second = current->key;
salesInfo[5].second = current->value.getQuantitySold();
}
//Calculate % over retail and check for product with the highest %
//float percentOverRetail = ((current->value.getAverageSale() - current->value.getAverageCost()) / current->value.getAverageCost()) * 100;
float percentOverRetail = ((current->value.getAverageSale() / current->value.getAverageCost())) * 100;
if (percentOverRetail > salesInfo[7].second) {
salesInfo[6].second = current->key;
salesInfo[7].second = percentOverRetail;
}
//Calculate revenue from remaining inventory and check for minimum
float remainingInventoryRevenue = current->value.getAverageCost() * (current->value.getQuantity() - current->value.getQuantitySold());
salesInfo[8].second += remainingInventoryRevenue;
current = current->next;
}
}
/*// Testing if collected information from the vector of pairs is right
for (const auto& info : salesInfo) {
cout << left << setw(30) << info.first << ": $" << fixed << setprecision(2) << info.second << endl;
}*/
//Printing out sales report
cout << "Cumulative Sales Report:\n" << '\n';
cout << left << setw(30) << "Total Cost:" << '$' << fixed << setprecision(2) << salesInfo[0].second << '\n';
cout << left << setw(30) << "Total Revenue:" << '$' << fixed << setprecision(2) << salesInfo[1].second << '\n';
cout << left << setw(30) << "Total Profit:" << '$' << fixed << setprecision(2) << salesInfo[1].second - salesInfo[0].second << '\n';
cout << left << setw(30) << "Unsold Inventory Cost:" << '$' << fixed << setprecision(2) << salesInfo[8].second << '\n';
cout << left << setw(30) << "Inventory Size:" << int(salesInfo[2].second) - int(salesInfo[3].second) << '\n';
cout << left << setw(30) << "Total Bought:" << int(salesInfo[2].second) << '\n';
cout << left << setw(30) << "Total Sold:" << int(salesInfo[3].second) << '\n';
cout << left << setw(30) << "Highest Sales:" << int(salesInfo[4].second) << " - " << int(salesInfo[5].second) << '\n';
cout << left << setw(30) << "Highest % Profit:" << int(salesInfo[6].second) << " - %" << fixed << setprecision(2) << salesInfo[7].second << '\n';
cout << '\n';
}
void MapDatabase::saveSpreadsheet(string filename) {
ofstream csvFile(filename); // creates file
if (!csvFile.is_open()) {
cout << "Error opening file!" << endl;
return;
}
else {
csvFile << "Identifier, Stock, Historical Quantity, Quantity Sold, Average Cost, Average Sale" << endl; // first line of file always
for (auto& currentNode : hashTable) {
Node* current = currentNode;
while (current) {
csvFile << current->key << ", " << current->value.getQuantity() - current->value.getQuantitySold() << ", "
<< current->value.getQuantity() << ", " << current->value.getQuantitySold() << ", " <<
current->value.getAverageCost() << ", " << current->value.getAverageCost() << endl;
current = current->next;
}
}
}
}
bool MapDatabase::loadSpreadsheet(string filename) {
ifstream csvFile(filename); // accesses the file,, should have ".csv" in string
if (csvFile.is_open()) {
string line;
getline(csvFile, line); // reads first line
// all start as a string
string not_needed;
string identifier;
string quantity;
string quantity_sold;
string average_cost;
string average_sale;
// to stoi/stof the strings
int id;
int q;
int q_sold;
float avg_cost;
float avg_sale;
while (getline(csvFile, line)) { // will stop after it goes through every line of the file
istringstream stream(line); // a stream of data
// separates the stream of data into the string variable when it finds the comma
getline(stream, identifier, ',');
getline(stream, not_needed, ',');
getline(stream, quantity, ',');
getline(stream, quantity_sold, ',');
getline(stream, average_cost, ',');
getline(stream, average_sale, ',');
// changes these all into correct data type
id = stoi(identifier);
q = stoi(quantity);
q_sold = stoi(quantity_sold);
avg_cost = stof(average_cost);
avg_sale = stof(average_sale);
buy(id, q, avg_cost);
sell(id, q_sold, avg_sale);
}
return true;
}
return false;
}