Skip to content

Commit f31e319

Browse files
authored
Merge pull request #70 from LONECODER1/feature/invoiceGenerator
Invoice Generator added
2 parents b040d44 + 6e9fe18 commit f31e319

File tree

9 files changed

+487
-0
lines changed

9 files changed

+487
-0
lines changed
Lines changed: 322 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,322 @@
1+
// InvoiceGenerator.cpp
2+
// Works on Dev-C++, Old MinGW, Linux, Windows
3+
// Compile: g++ InvoiceGenerator.cpp -o InvoiceGenerator
4+
5+
#include <iostream>
6+
#include <fstream>
7+
#include <vector>
8+
#include <string>
9+
#include <iomanip>
10+
#include <sstream>
11+
12+
#ifdef _WIN32
13+
#include <direct.h> // for _mkdir
14+
#else
15+
#include <sys/stat.h> // for mkdir
16+
#endif
17+
18+
using namespace std;
19+
20+
// ----------- Utility: Create Directory -------------
21+
void makeDirectory(const string &dirName)
22+
{
23+
#ifdef _WIN32
24+
_mkdir(dirName.c_str()); // Windows
25+
#else
26+
mkdir(dirName.c_str(), 0777); // Linux
27+
#endif
28+
}
29+
30+
// Check if file exists
31+
bool fileExists(const string &filename)
32+
{
33+
ifstream f(filename.c_str());
34+
return f.good();
35+
}
36+
37+
// ----------- Item Class -------------
38+
class Item
39+
{
40+
public:
41+
string name;
42+
int quantity;
43+
double price;
44+
45+
Item() : quantity(0), price(0) {}
46+
47+
Item(string n, int q, double p)
48+
: name(n), quantity(q), price(p) {}
49+
50+
double getTotal() const
51+
{
52+
return quantity * price;
53+
}
54+
};
55+
56+
// ----------- Invoice Class -------------
57+
class Invoice
58+
{
59+
public:
60+
int invoiceID;
61+
string customerName;
62+
vector<Item> items;
63+
double subtotal, tax, total;
64+
double taxRate; // NEW: user-entered tax rate %
65+
66+
Invoice(int id, string cname, double tr)
67+
: invoiceID(id), customerName(cname), subtotal(0),
68+
tax(0), total(0), taxRate(tr) {}
69+
70+
void addItem(const Item &it)
71+
{
72+
items.push_back(it);
73+
}
74+
75+
void calculateTotals()
76+
{
77+
subtotal = 0;
78+
for (auto &it : items)
79+
subtotal += it.getTotal();
80+
81+
tax = subtotal * (taxRate / 100.0);
82+
total = subtotal + tax;
83+
}
84+
85+
string filename() const
86+
{
87+
return "invoices/invoice_" + to_string(invoiceID) + ".txt";
88+
}
89+
90+
void saveToFile()
91+
{
92+
makeDirectory("invoices");
93+
94+
ofstream out(filename().c_str());
95+
if (!out)
96+
{
97+
cout << "Error saving invoice file!\n";
98+
return;
99+
}
100+
101+
out << "----------------------------------------\n";
102+
out << "Invoice ID: " << invoiceID << "\n";
103+
out << "Customer Name: " << customerName << "\n";
104+
out << "----------------------------------------\n\n";
105+
106+
out << left << setw(20) << "Item Name"
107+
<< setw(10) << "Qty"
108+
<< setw(10) << "Price"
109+
<< setw(10) << "Total" << "\n";
110+
out << "--------------------------------------------------\n";
111+
112+
for (auto &it : items)
113+
{
114+
out << left << setw(20) << it.name
115+
<< setw(10) << it.quantity
116+
<< setw(10) << fixed << setprecision(2) << it.price
117+
<< setw(10) << fixed << setprecision(2) << it.getTotal()
118+
<< "\n";
119+
}
120+
121+
out << "--------------------------------------------------\n\n";
122+
out << "Subtotal: " << subtotal << "\n";
123+
out << "Tax (" << taxRate << "%): " << tax << "\n";
124+
out << "Total: " << total << "\n";
125+
out << "----------------------------------------\n";
126+
127+
out.close();
128+
}
129+
};
130+
131+
// ----------- Invoice Manager -------------
132+
class InvoiceManager
133+
{
134+
public:
135+
string indexFile;
136+
137+
InvoiceManager()
138+
{
139+
indexFile = "invoices/index.txt";
140+
makeDirectory("invoices");
141+
142+
if (!fileExists(indexFile))
143+
{
144+
ofstream make(indexFile.c_str());
145+
make.close();
146+
}
147+
}
148+
149+
int generateID()
150+
{
151+
ifstream f(indexFile.c_str());
152+
string line;
153+
int maxID = 1000;
154+
155+
while (getline(f, line))
156+
{
157+
if (line.empty())
158+
continue;
159+
160+
stringstream ss(line);
161+
string idStr;
162+
getline(ss, idStr, '|');
163+
164+
int id = stoi(idStr);
165+
if (id > maxID)
166+
maxID = id;
167+
}
168+
return maxID + 1;
169+
}
170+
171+
void saveToIndex(int id, string cname, string fname)
172+
{
173+
ofstream f(indexFile.c_str(), ios::app);
174+
f << id << "|" << cname << "|" << fname << "\n";
175+
f.close();
176+
}
177+
178+
void createInvoice()
179+
{
180+
cin.ignore();
181+
cout << "Enter customer name: ";
182+
string cname;
183+
getline(cin, cname);
184+
185+
cout << "Enter tax percentage (%): ";
186+
double taxPercent;
187+
cin >> taxPercent;
188+
cin.ignore();
189+
190+
int id = generateID();
191+
Invoice inv(id, cname, taxPercent);
192+
193+
while (true)
194+
{
195+
cout << "\nEnter item name (leave blank to finish): ";
196+
string iname;
197+
getline(cin, iname);
198+
199+
if (iname.empty())
200+
break;
201+
202+
cout << "Quantity: ";
203+
int qty;
204+
cin >> qty;
205+
206+
cout << "Price: ";
207+
double price;
208+
cin >> price;
209+
cin.ignore();
210+
211+
inv.addItem(Item(iname, qty, price));
212+
}
213+
214+
if (inv.items.empty())
215+
{
216+
cout << "No items added. Invoice cancelled.\n";
217+
return;
218+
}
219+
220+
inv.calculateTotals();
221+
inv.saveToFile();
222+
223+
saveToIndex(inv.invoiceID, inv.customerName, inv.filename());
224+
225+
cout << "\nInvoice created and saved successfully!\n";
226+
}
227+
228+
void viewInvoiceByID()
229+
{
230+
cout << "Enter Invoice ID: ";
231+
int id;
232+
cin >> id;
233+
234+
ifstream f(indexFile.c_str());
235+
string line;
236+
237+
while (getline(f, line))
238+
{
239+
stringstream ss(line);
240+
string idStr, cname, fname;
241+
242+
getline(ss, idStr, '|');
243+
getline(ss, cname, '|');
244+
getline(ss, fname, '|');
245+
246+
if (stoi(idStr) == id)
247+
{
248+
ifstream invFile(fname.c_str());
249+
cout << "\n----- Invoice Content -----\n\n";
250+
string ln;
251+
while (getline(invFile, ln))
252+
cout << ln << "\n";
253+
return;
254+
}
255+
}
256+
257+
cout << "Invoice not found!\n";
258+
}
259+
260+
void showAllInvoices()
261+
{
262+
ifstream f(indexFile.c_str());
263+
string line;
264+
265+
cout << "\nStored Invoices:\n";
266+
cout << "-------------------------------------------\n";
267+
268+
while (getline(f, line))
269+
{
270+
if (line.empty())
271+
continue;
272+
273+
stringstream ss(line);
274+
string id, cname, fname;
275+
getline(ss, id, '|');
276+
getline(ss, cname, '|');
277+
getline(ss, fname, '|');
278+
279+
cout << "ID: " << id << " | Name: " << cname
280+
<< " | File: " << fname << "\n";
281+
}
282+
}
283+
};
284+
285+
// ----------- MAIN MENU -------------
286+
int main()
287+
{
288+
InvoiceManager manager;
289+
290+
while (true)
291+
{
292+
cout << "\n----------------------------------------\n";
293+
cout << " INVOICE GENERATOR SYSTEM \n";
294+
cout << "----------------------------------------\n";
295+
cout << "1. Create Invoice\n";
296+
cout << "2. View Invoice by ID\n";
297+
cout << "3. Show All Invoices\n";
298+
cout << "4. Exit\n";
299+
cout << "Enter choice: ";
300+
301+
int choice;
302+
cin >> choice;
303+
304+
switch (choice)
305+
{
306+
case 1:
307+
manager.createInvoice();
308+
break;
309+
case 2:
310+
manager.viewInvoiceByID();
311+
break;
312+
case 3:
313+
manager.showAllInvoices();
314+
break;
315+
case 4:
316+
cout << "Exiting...\n";
317+
return 0;
318+
default:
319+
cout << "Invalid choice!\n";
320+
}
321+
}
322+
}
139 KB
Binary file not shown.

0 commit comments

Comments
 (0)