-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.cpp
1619 lines (1362 loc) · 75.3 KB
/
Main.cpp
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <ctime>
#include <chrono>
using namespace std;
// Structure to hold details about users (manager and customer)
struct UserDetails {
// Manager credentials for logging into the system
string username; // Store the username of the restaurant manager
string password; // Store the password of the restaurant manager
// Customer details for making orders
string customerName; // Store the name of the customer
};
// Function prototypes for various operations in the program
char getUserType(); // Function to determine whether the user is a manager or a customer
void signup(UserDetails& ud); // Function to allow manager to sign up
void login(UserDetails& ud); // Function to allow manager to log in
void getManagerAction(); // Function for manager to choose actions to perform
void getCustomerAction(UserDetails& ud); // Function for customer to choose their actions
//void trackManagerActions(int arrManagerChoices[]); // Tracks manager actions (currently not used)
void continueProgram(); // Asks user if they want to continue using the program
int logout(); // Allows the user to log out from the system
// Manager-specific operations
void createOrUpdateMenu(); // Manager can create or modify the restaurant menu
void updatePrices(); // Manager can adjust the price of menu items
void viewStats(); // Manager can view restaurant stats like popular dishes and sales
void managerHelpInfo(); // Provides help or instructions for the manager on using the system
// Internal functions for manager actions, not directly invoked by manager
float calcTotalPaymentsPerOrder(); // Calculates the total payment for a given order
int calcEstDeliveryTime(string& deliveryArea, int& totalPrepTime); // Estimates delivery time based on location and prep time
int displayMenu(); // Displays the menu to the user (manager or customer)
bool itemAlreadyExists(string itemName); // Checks if the item already exists in the menu when updating
int acceptOrder(int**, int x, int totalMenuItems); // Accepts or rejects an order based on item availability
void updateStocks(int menuIndex, int quantity, int totalMenuItems, int currentStock); // Updates stock after accepting an order
string** readMenu(int&); // Reads the current menu and returns it in a dynamic 2D array
// Customer-specific operations
void orderOnline(UserDetails& ud); // Allows customer to place an online food order
void makePayments(UserDetails& ud); // Allows customer to make a payment for the order
// Internal functions for customer actions, not directly invoked by customer
bool isNewcomer(UserDetails& ud); // Checks if the customer is new or existing based on their details
int main() {
UserDetails ud; // Declare a variable to store user details (manager or customer)
// Display a welcome message to the user
cout << "===================================================================\n";
cout << "====================== Welcome to NinjaFood! ======================\n";
cout << "===================================================================\n\n";
char choice = 'Y'; // Variable to store user's choice to continue or exit the program
cout << "\n=> Would you like to start using this program? [Y/N] "; // Prompt user to start
cin >> choice;
// INPUT VALIDATION: Ensure user input is either 'Y', 'y', 'N', or 'n'
while (choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n')
{
cout << "\n/// Invalid selection. Please try again!";
cout << "\n=> Do you wish to continue using this program? [Y/N] "; // Re-prompt if invalid input
cin >> choice;
}
if (choice == 'Y' || choice == 'y') // If user chooses to continue
{
// Ask user whether they are a manager or customer
char userTypeChoice = getUserType();
// If the user is a restaurant manager
if (userTypeChoice == 'M' || userTypeChoice == 'm')
{
// Call the login function to verify manager's credentials
login(ud);
// Provide manager with options for tasks to perform
getManagerAction();
}
else
{
// If the user is a customer, allow them to place an order
getCustomerAction(ud);
}
}
else // If user opts to exit
{
// Display a thank you message and exit the program
cout << "\n====== Thank you for using NinjaFood's Food Ordering System program! ======\n"
<< "===================== Have a nice day and take care :) ====================\n";
exit(0); // Terminate the program
}
return 0;
}
// Function to determine the user's identity: whether they are a restaurant manager or a customer
char getUserType() {
string choice; // Variable to store the user input (string to prevent issues with garbage input)
// Prompt the user to choose their role
cout << "\n=> Please select your identity: \n"
<< "[M] Restaurant Manager\n"
<< "[C] Customer\n";
cin >> choice; // Read the user's input, but only take the first character
// INPUT VALIDATION - Ensure the user inputs only one character and check if it's valid
while (choice.length() > 1) {
cout << "\n/// Invalid selection. Please try again!\n";
cout << "=> Please select your identity: \n"
<< "[M] Restaurant Manager\n"
<< "[C] Customer\n";
cin >> choice; // Prompt again if input is not valid
// Ensure the input is either 'M', 'm', 'C', or 'c'
while (choice[0] != 'M' && choice[0] != 'm' && choice[0] != 'C' && choice[0] != 'c') {
cout << "\n/// Invalid selection. Please try again!\n";
cout << "=> Please select your identity: \n"
<< "[M] Restaurant Manager\n"
<< "[C] Customer\n";
cin >> choice; // Re-prompt if the user input is invalid
}
}
return choice[0]; // Return the first character of the choice to identify the user
}
// Login function to authenticate restaurant managers and secure system access
void login(UserDetails& ud) {
bool matchFound = false; // Flag to track whether a valid login is found
string choice; // Variable to store user input (login or sign up choice)
string data; // Temporary variable to store data read from the login credentials file
// Open the file containing manager login credentials
ifstream file;
file.open("login_credentials.txt");
cout << "\n**************************** LOGIN PAGE ****************************\n";
// Prompt the user to choose between logging in or signing up
cout << "\n/// Welcome. You are accessing as RESTAURANT MANAGER.\n"
<< "=> Please select an option below to proceed:\n"
<< "[1] Login\n"
<< "[2] Sign up\n";
cin >> choice; // Read user input for login or sign up
cin.ignore(); // Clear the input buffer to avoid issues with subsequent inputs
// INPUT VALIDATION - Ensure the user input is a valid selection (either '1' or '2')
while (choice.length() > 1) {
cout << "\n/// Invalid selection. Please try again!\n";
cout << "=> Please select your identity: \n"
<< "[1] Login\n"
<< "[2] Sign up\n";
cin >> choice; // Prompt again for valid input
// Ensure the input is either '1' or '2'
while (choice[0] != '1' && choice[0] != '2') {
cout << "\n/// Invalid selection. Please try again!\n"
<< "=> Please select an option below:\n"
<< "[1] Login\n"
<< "[2] Sign up\n";
cin >> choice;
cin.ignore(); // Clear the buffer after reading input
}
}
// If the manager chooses login
if (choice[0] == '1') {
// Check if the login credentials file exists
if (file.fail()) {
cout << "\n/// No login credentials found. Please sign up first!\n"
<< "/// Redirecting to sign up page...\n\n";
// If file doesn't exist, redirect to sign-up process
signup(ud);
}
// Check if the file is empty (no stored credentials)
else if (file.seekg(0, ios::end), file.tellg() == 0) {
cout << "\n/// No login credentials found. Please sign up first!\n"
<< "/// Redirecting to sign up page...\n\n";
// If file is empty, prompt for sign-up
signup(ud);
}
else {
// Loop until valid login credentials are entered
while (!matchFound) {
cout << "\n=> Enter username: ";
cin >> ud.username; // Get the manager's username
cout << "=> Enter password: ";
cin >> ud.password; // Get the manager's password
file.clear(); // Clear any error flags from previous file operations
file.seekg(0, ios::beg); // Rewind to the beginning of the file
// Read each line in the file and check for matching username and password
while (getline(file, data, '\t')) {
// If the username matches
if (ud.username == data) {
// Retrieve the password associated with the username
getline(file, data, '\n');
// If the password matches
if (ud.password == data) {
matchFound = true; // Login is successful
break; // Exit loop since credentials are verified
}
}
else {
// Skip password reading if the username doesn't match
getline(file, data);
}
}
// If no match is found, prompt user to try again
if (!matchFound) {
cout << "\n/// Incorrect username or password."
<< "\n/// Please ensure the username and password are entered correctly (case-sensitive)."
<< "\n/// Try again!\n";
}
else {
cout << "\n/// Login successful! Welcome as RESTAURANT MANAGER.\n\n"; // Successful login message
break; // Exit the loop if login is successful
}
}
}
file.close(); // Close the credentials file
}
else {
signup(ud); // If user selects sign-up, proceed to sign-up process
}
}
// Function to log out the restaurant manager and redirect back to the main page
int logout() {
cout << "\n/// Redirecting to main page...\n\n"; // Notify the user that they are being redirected
return main(); // Call the main function again to return to the main menu
}
// Function for a new restaurant manager to sign up, creating login credentials
void signup(UserDetails& ud) {
string data; // Temporary variable to store any unnecessary data while reading the file
string newUsername; // Variable to store the new username for sign up
bool valid = false; // Flag to indicate whether the entered credentials are valid
// Open the file to store login credentials (in both read and write mode, appending new data)
fstream file;
file.open("login_credentials.txt", ios::out | ios::in | ios::app);
cout << "\n*************************** SIGN UP PAGE ***************************\n";
cout << "\n/// You are signing up as RESTAURANT MANAGER.\n";
// Loop until a valid username is entered
while (!valid) {
file.seekp(0, ios::beg); // Move the file pointer to the beginning of the file
// Prompt the user to enter a new username
cout << "\n=> Enter new username: ";
getline(cin, newUsername);
// Read through the file to check if the username already exists
while (file) {
getline(file, data, '\t'); // Read each username separated by a tab
// If the new username matches an existing one, prompt the user to choose another one
if (newUsername == data) {
valid = false;
cout << "\n/// This username already exists. Please try again!\n";
break; // Exit the file-reading loop to re-enter a new username
}
else {
valid = true;
getline(file, data, '\n'); // Skip the password and check the next username
}
}
}
file.clear(); // Clear any error flags from the file operation
// If the entered username is valid (doesn't exist already), write it to the file
if (valid) {
file << newUsername << '\t'; // Write the new username to the file
}
cin.clear(); // Clear any previous input errors from cin
// Prompt the user to enter a new password with a minimum length of 6 characters
cout << "=> Enter new password (min 6 characters): ";
getline(cin, ud.password);
// Validate the entered password length
while (ud.password.length() < 6) {
cout << "\n/// Password must be at least 6 characters!\n";
cout << "=> Enter new password (min 6 characters): ";
getline(cin, ud.password); // Re-enter the password if it doesn't meet the requirements
}
// If the password is valid, write it to the file along with the username
file << ud.password << "\n";
cout << "\n/// Sign up successful!\n"
<< "/// Redirecting to login page...\n\n";
file.close(); // Close the file after writing the credentials
// After sign-up, automatically redirect to the login page
login(ud);
}
// Function to determine the action the restaurant manager would like to perform
void getManagerAction() {
string actionChoice; // Variable to store the user's action choice as a string
// Prompt the user to select an action from the available options
cout << "\n=> Please select an action as RESTAURANT MANAGER: \n"
<< "[1] Create/update menu\n"
<< "[2] Update prices\n"
<< "[3] View stats (most popular dish, total number of customers, total sales, total number of orders)\n"
<< "\n/// Do you need help navigating the system? Select the option below! \n"
<< "[4] View Manager Help info\n";
cin >> actionChoice; // Read the user's action choice
// INPUT VALIDATION - Ensure that the input is a single character and valid
while (actionChoice.length() > 1) {
cout << "\n/// Invalid selection. Please try again!\n";
cout << "=> Please select an action as RESTAURANT MANAGER: \n"
<< "[1] Create/update menu\n"
<< "[2] Update prices\n"
<< "[3] View stats (most popular dish, total number of customers, total sales, total number of orders)\n"
<< "\n/// Do you need help navigating the system? Select the option below! \n"
<< "[4] View Manager Help info\n";
cin >> actionChoice; // Prompt again if the input is not valid
// Check if the input is valid (choices are '1', '2', '3', or '4')
while (actionChoice[0] != '1' && actionChoice[0] != '2' && actionChoice[0] != '3' && actionChoice[0] != '4') {
cout << "\n/// Invalid selection. Please try again!\n";
cout << "=> Please select an action as RESTAURANT MANAGER: \n"
<< "[1] Create/update menu\n"
<< "[2] Update prices\n"
<< "[3] View stats (most popular dish, total number of customers, total sales, total number of orders)\n"
<< "\n/// Do you need help navigating the system? Select the option below! \n"
<< "[4] View Manager Help info\n";
cin >> actionChoice[0]; // Re-prompt for valid input
}
}
// Based on the action choice, call the appropriate function to perform the task
switch (actionChoice[0]) {
case '1':
createOrUpdateMenu(); // Call function to create or update the menu
break;
case '2':
updatePrices(); // Call function to update prices in the menu
break;
case '3':
viewStats(); // Call function to view the statistics (most popular dish, sales, etc.)
break;
case '4':
managerHelpInfo(); // Call function to view help information for the manager
break;
default:
// This block should not be reached due to the input validation above
cout << "Error!\n";
}
}
// Function to get the customer action, either to make an order or proceed with payment
void getCustomerAction(UserDetails& ud) {
string actionChoice; // Variable to store the customer's action choice
// Prompt the customer to choose between ordering online or making a payment
cout << "\n=> Please select an action as CUSTOMER: \n"
<< "[1] Order online\n"
<< "[2] Make payment\n";
cin >> actionChoice;
// INPUT VALIDATION - Ensure that the input is a single character and valid
while (actionChoice.length() > 1) {
cout << "\n/// Sorry, that is not a valid selection. Please try again!\n";
cout << "\n=> Please select an action as CUSTOMER: \n"
<< "[1] Order online\n"
<< "[2] Make payment\n";
cin >> actionChoice;
// Check if the entered choice is valid (either '1' or '2')
while (actionChoice[0] != '1' && actionChoice[0] != '2') {
cout << "\n/// Sorry, that is not a valid selection. Please try again!\n";
cout << "\n=> Please select an action as CUSTOMER: \n"
<< "[1] Order online\n"
<< "[2] Make payment\n";
cin >> actionChoice[0]; // Prompt again if input is invalid
}
}
// Based on the action choice, proceed with the appropriate function
switch (actionChoice[0]) {
case '1':
orderOnline(ud); // Call the function to allow the customer to order online
break;
case '2':
makePayments(ud); // Call the function to allow the customer to make a payment
break;
default:
cout << "Error!\n"; // This should not happen due to input validation
}
}
// Function to display guidelines and help for the restaurant manager to use the system effectively
void managerHelpInfo() {
cout << "\n********************** MANAGER HELP INFO PAGE ***********************\n";
cout << "\n/// You have selected the option to: View Manager Help Info\n";
cout << "\nWelcome to the NinjaFood Ordering System!\n"
<< "This system enables Restaurant Managers to manage the restaurant's menu, view statistics, and perform other administrative tasks.\n";
// Description of the available options for the manager
cout << "\n===> Options Specifications"
<< "\n\n[1] Create/Update Menu"
<< "\n\t This option allows the Restaurant Manager to create a new menu or update the existing one."
<< "\n\t The menu includes the following details for each item: "
<< "\n\t\t 1. Item name"
<< "\n\t\t 2. Item price"
<< "\n\t\t 3. Preparation time (the time required to prepare the item)"
<< "\n\t\t 4. Stock quantity (number of items available for order)"
<< "\n\n[2] Update Prices"
<< "\n\t This option allows the Restaurant Manager to modify the price of any menu item."
<< "\n\n[3] View Stats"
<< "\n\t This option displays the restaurant's key statistics, including the following details: "
<< "\n\t\t 1. Most popular dish"
<< "\n\t\t 2. Total number of orders for today"
<< "\n\t\t 3. Total sales for today"
<< "\n\t\t 4. Total number of customers for today";
cout << "\n=============================================================\n";
// Ask the user whether they want to continue using the program
continueProgram();
}
// Function to read the menu file and store all its contents into a dynamically allocated 2D array
// The function takes a reference to totalNumItems, which represents the total number of items in the menu
string** readMenu(int& totalNumItems) {
string itemName; // Variable to store the name of a food item
string line; // Variable to store each line in the menu file temporarily
float itemPrice = 0; // Variable to store the price of a food item
string strItemPrice; // String representation of item price
int preparationTime = 0; // Variable to store the preparation time of the food item
string strPreparationTime; // String representation of preparation time
int stock = 0; // Variable to store the stock quantity of the item
string strStock; // String representation of stock quantity
char toSkip; // Variable to store a character to skip (e.g., commas in the file)
string strIndex; // String representation of the index/ID of the food item
fstream file;
file.open("menu.txt", ios::in); // Open the menu file in read mode
int index = 0; // Variable to count the number of menu items
// Count the number of items in the menu by counting the number of lines in the file
while (getline(file, line))
++index;
totalNumItems = index; // Update totalNumItems with the total number of menu items
// Dynamically allocate a 2D array to store the menu details
string** arrMenuContent = new string*[index];
for (int j = 0; j < index; j++) {
arrMenuContent[j] = new string[5]; // Each item has 5 details (ID, name, price, preparation time, stock)
}
// If the menu is empty, return the empty array
if (index == 0)
return arrMenuContent;
else {
// Clear the file and set the file pointer to the beginning for reading
file.clear();
file.seekp(0, ios::beg);
int i = 0; // Index for the array to store menu items
while (file >> index) { // Read the index of the item
file >> toSkip; // Skip the comma separating the index and item name
getline(file, itemName, ','); // Read the item name (up to the comma delimiter)
file >> itemPrice; // Read the item price
file >> toSkip; // Skip the comma
file >> preparationTime; // Read the preparation time
file >> toSkip; // Skip the comma
file >> stock; // Read the stock quantity
// Convert the values to strings to store in the array
strIndex = to_string(index);
strItemPrice = to_string(itemPrice);
strPreparationTime = to_string(preparationTime);
strStock = to_string(stock);
// Store the item details into the dynamically allocated array
arrMenuContent[i][0] = strIndex;
arrMenuContent[i][1] = itemName;
arrMenuContent[i][2] = strItemPrice;
arrMenuContent[i][3] = strPreparationTime;
arrMenuContent[i][4] = strStock;
++i; // Increment to store the next item in the array
}
}
file.close(); // Close the file after reading the menu
return arrMenuContent; // Return the 2D array containing the menu details
}
// Manager function to allow the restaurant manager to create or update the menu
void createOrUpdateMenu() {
int numbering = 1; // Integer variable to track the sequence number for menu items
char choice = 'Y'; // Variable to store the user's choice for whether they wish to continue adding/updating menu items
string itemName; // String variable to hold the name of the food item
string line; // Temporary string to store each line from the file
float itemPrice = 0; // Float variable to store the price of the food item
int preparationTime = 0; // Integer variable to store the preparation time of the food item (in minutes)
int stock = 0; // Integer variable to store the available stock quantity of the item
fstream file;
file.open("menu.txt", ios::out | ios::app); // Open the menu file in append mode to update the existing content
cout << "\n*********************** CREATE/UPDATE MENU PAGE ***********************\n";
cout << "\n/// You have selected the option to: Update/Create Menu\n";
// Retrieve the current menu index by displaying the existing menu
int index = displayMenu();
numbering = ++index; // Increment the index to start numbering new items
if (index == 0) // Check if the menu file is empty
cout << "/// Menu does not exist. Creating menu...\n"; // Inform user that a new menu will be created
// Loop to allow the manager to add/update items until they choose to stop
while (choice == 'Y' || choice == 'y') {
cout << "\n=> Enter name of item #" << numbering << ": "; // Prompt for the name of the new food item
cin.ignore(); // Clear any extra newline characters left in the input buffer
getline(cin, itemName); // Get the item name from the user input
// Validate the item name - it should not be empty, too long, or already exist in the menu
while (itemName.empty() || itemName == " " || itemName.length() >= 25 || itemAlreadyExists(itemName)) {
if (itemName.empty() || itemName == " ") {
cout << "/// Item name cannot be empty!\n"; // Error if the name is empty
}
else if (itemName.length() >= 25) {
cout << "/// Item name cannot be more than 25 characters! Please try again.\n"; // Error if the name is too long
}
else {
cout << "\n/// This item already exists in the menu!";
cout << "\n/// Please consider the \"Update Prices\" option for this item instead.\n"; // Error if the item already exists
}
cout << "\n=> Enter name of item #" << numbering << ": "; // Prompt to re-enter the item name
getline(cin, itemName); // Get the item name again
}
file << numbering << "," << itemName << ","; // Write the item number and name to the file
cout << "=> Enter price of item #" << numbering << ": $"; // Prompt for the item price
cin >> itemPrice;
// Validate the price - it must be greater than zero
while (itemPrice <= 0) {
cout << "\n/// Item price cannot be equal to or less than zero! Please try again.\n";
cout << "=> Enter price of item #" << numbering << ": $"; // Prompt to re-enter the price
cin >> itemPrice;
}
file << fixed << setprecision(2) << itemPrice << ","; // Write the price to the file with two decimal places
cout << "=> Enter preparation time of item #" << numbering << " (in minutes): "; // Prompt for preparation time
cin >> preparationTime;
// Validate the preparation time - it must be greater than zero
while (preparationTime <= 0) {
cout << "\n/// Preparation time cannot be less than or equal to zero! Please try again.\n";
cout << "=> Enter preparation time of item #" << numbering << " (in minutes): "; // Prompt to re-enter the preparation time
cin >> preparationTime;
}
file << preparationTime << ","; // Write the preparation time to the file
cout << "=> Enter stock quantity of item #" << numbering << " : "; // Prompt for the stock quantity
cin >> stock;
// Validate the stock quantity - it must be greater than zero
while (stock <= 0) {
cout << "\n/// Stock quantity cannot be less than or equal to zero! Please try again.\n";
cout << "=> Enter stock quantity of item #" << numbering << " : "; // Prompt to re-enter the stock quantity
cin >> stock;
}
file << stock << "\n"; // Write the stock quantity to the file
// Ask if the manager wants to continue adding more items to the menu
cout << "=> Do you wish to continue? [Y/N] "; // Prompt for continuation choice
cin >> choice;
// Validate the user's choice for continuation
while (choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n') {
cout << "\n/// Sorry, that is not a valid selection. Please try again!";
cout << "\n=> Do you wish to continue? [Y/N] "; // Prompt again if the input is invalid
cin >> choice;
}
++numbering; // Increment the item numbering for the next item
}
// After updating the menu, move the file pointer to the beginning for displaying the updated menu
file.seekp(0, ios::beg); // Set file pointer to the start of the file
cout << "\n/// Displaying updated menu...\n";
displayMenu(); // Display the updated menu to the manager
// Ask the manager if they want to continue using the system
continueProgram(); // Proceed with the next action in the program
}
// Function to allow the restaurant manager to update the prices of menu items
void updatePrices() {
int index = 0; // Index variable to store the menu item's index
int userIndex = 0; // Variable to store the user's input for selecting an item by its index
int totalNumItems = 0; // Variable to store the total number of items in the menu
string itemName; // Variable to store the name of the menu item
string strItemPrice; // Variable to store the item price as a string
float itemPrice = 0; // Variable to store the item price as a float
string strOldPrice; // Variable to store the old price of the item as a string
float oldPrice = 0; // Variable to store the old price of the item as a float
string strNewPrice; // Variable to store the new price of the item as a string
float newPrice = 0; // Variable to store the new price of the item as a float
char choice = 'Y'; // Variable to determine whether the manager wants to continue updating prices
int preparationTime = 0; // Variable to store the preparation time of the item (in minutes)
string strPreparationTime; // Variable to store the preparation time as a string
int stock = 0; // Variable to store the stock quantity of the item
string strStock; // Variable to store the stock quantity as a string
string line; // Temporary variable to hold unused data from the file
// Read the current menu into a 2D array and retrieve the total number of items
string** arrMenuContent = readMenu(totalNumItems);
cout << "\n**************************** UPDATE PRICES ****************************\n";
cout << "\n/// You have selected the option to: Update Prices\n";
// Display the current menu to the manager
displayMenu();
fstream file;
file.open("menu.txt", ios::out); // Open the menu file for writing (to update prices)
// If the menu file doesn't exist or is empty, prompt the manager to create a menu first
if (file.fail() || totalNumItems == 0) {
cout << "/// Menu not found! Please create the menu first and try again.\n";
cout << "/// Redirecting to Create/Update Menu...\n";
createOrUpdateMenu(); // Redirect to menu creation if menu doesn't exist
} else {
// Proceed if the menu exists and contains items
while (choice == 'Y' || choice == 'y') {
cout << "\n=> Please enter the index of the item to update the price: ";
cin >> userIndex;
// Validate that the user input index is within valid range
while (userIndex < 1 || userIndex > totalNumItems) {
cout << "/// Invalid index. Please try again!\n";
cout << "\n=> Please enter index of item to update price: ";
cin >> userIndex;
}
// Iterate through the menu and find the selected item to update its price
for (int i = 0; i < totalNumItems; i++) {
index = stoi(arrMenuContent[i][0]); // Get the index of the current item
if (index == userIndex) { // If item matches the user's selection
itemName = arrMenuContent[i][1]; // Get the item name
strOldPrice = arrMenuContent[i][2]; // Get the old price as a string
oldPrice = stof(strOldPrice); // Convert the old price to float
cout << "\n/// Current price for " << itemName << ": $" << oldPrice;
cout << "\n=> Please enter the new price for " << itemName << ": $";
cin >> newPrice; // Get the new price from the user
// Validate that the new price is valid (not equal to the old price or non-positive)
while (newPrice == oldPrice || newPrice <= 0) {
if (newPrice == oldPrice) {
cout << "\n/// New price cannot be equal to the old price!\n";
cout << "=> Please enter the new price for " << itemName << ": $";
cin >> newPrice;
} else if (newPrice <= 0) {
cout << "\n/// New price cannot be less than or equal to zero!\n";
cout << "=> Please enter the new price for " << itemName << ": $";
cin >> newPrice;
}
}
// Store the new price as a string in the menu content
strNewPrice = to_string(newPrice);
arrMenuContent[i][2] = strNewPrice; // Update the price in the array
break;
}
}
// Update the file with the modified menu data
for (int j = 0; j < totalNumItems; j++) {
string strIndex = arrMenuContent[j][0]; // Get the index as a string
file << strIndex << ","; // Write the item index to the file
itemName = arrMenuContent[j][1]; // Get the item name
file << itemName << ","; // Write the item name to the file
strItemPrice = arrMenuContent[j][2]; // Get the price as a string
itemPrice = stof(strItemPrice); // Convert the price to a float
file << fixed << setprecision(2) << itemPrice << ","; // Write the price to the file with 2 decimals
strPreparationTime = arrMenuContent[j][3]; // Get the preparation time as a string
preparationTime = stoi(strPreparationTime); // Convert preparation time to integer
file << preparationTime << ","; // Write the preparation time to the file
strStock = arrMenuContent[j][4]; // Get the stock quantity as a string
stock = stoi(strStock); // Convert stock quantity to integer
file << stock << "\n"; // Write the stock quantity to the file
}
file.clear(); // Clear any error flags
file.seekp(0, ios::beg); // Move the file pointer back to the beginning of the file
cout << "\n/// Displaying updated menu...\n";
displayMenu(); // Display the updated menu to the manager
// Ask the manager if they want to continue updating prices for other items
cout << "\n=> Do you wish to continue updating prices? [Y/N] ";
cin >> choice;
// Validate the user's choice for continuation
while (choice != 'Y' && choice != 'y' && choice != 'N' && choice != 'n') {
cout << "\n/// Sorry, that is not a valid selection. Please try again!";
cout << "\n=> Do you wish to continue updating prices? [Y/N] ";
cin >> choice;
}
}
}
// Release the dynamically allocated memory for the menu array
delete[] arrMenuContent;
file.close(); // Close the file after writing
// Ask the manager whether they want to continue using the program
continueProgram(); // Proceed with the next action in the program
}
// Function to display restaurant statistics: top dish, total sales, and customer count
void viewStats() {
int index = 0; // Variable to track the number of sales lines in the total sales file
float line = 0; // Represents each line of sales data in the file
int numOfCustomers = 0; // Tracks the number of customers
string data; // Temporary variable to store data from files that are not needed for processing
int numbering = 0; // To count the number of entries in the top dish file
int menuIndex = 0; // The index of the menu item
string strMenuIndex; // To store the menu index as a string
string itemName; // To store the item name
string strItemPrice; // To store the item price as a string
float itemPrice = 0; // To store the item price as a float
int quantity = 0; // Quantity of items ordered
int preparationTime = 0; // Preparation time of the item
char toSkip; // To skip characters while reading the file
bool alreadyExists = false; // Flag to check if a dish has already been recorded
int topDishIndex = 0; // The index of the most popular dish
int maxQuantity = 0; // Maximum quantity ordered for a dish
int totalNumItems; // Total number of items in the menu
float totalSales = 0; // Total sales value
fstream totalSalesFile;
totalSalesFile.open("total_sales.txt", ios::in | ios::out | ios::app); // Open sales file to read total sales data
fstream topdishFile;
topdishFile.open("topdish.txt", ios::in | ios::out | ios::app); // Open top dish file to read most popular dishes
// Read the menu into an array and store the total number of items
string** arrMenuContent = readMenu(totalNumItems);
cout << "\n**************************** VIEW STATS ****************************\n";
cout << "\n/// You have selected the option to: View Stats\n";
// Check if there is any data in the top dish file
while (getline(topdishFile, data))
++numbering; // Count the number of lines in the file
// If no data exists in the top dish file, show a message and exit
if (numbering == 0) {
cout << "\n/// Stats not available. \n/// Reason: No orders have been made yet.\n"
<< "/// Please wait for a customer to order first, then try again!\n";
} else {
// Dynamically allocate arrays to store dish indices and quantities
int* arrDishes = nullptr;
arrDishes = new int[numbering]; // Array to store dish indices
int* arrQuantity = nullptr;
arrQuantity = new int[numbering]; // Array to store corresponding quantities ordered
topdishFile.clear();
topdishFile.seekg(0, ios::beg); // Reset file pointer to the beginning
int x = 0;
// Read the data from the topdish file and populate the arrays
while (topdishFile >> menuIndex) {
topdishFile >> toSkip; // Skip the separator
topdishFile >> quantity; // Read the quantity of the item ordered
// Check if the dish has already been recorded, update quantity if so
for (int z = 0; z < x + 1; z++) {
if (arrDishes[z] == menuIndex) {
arrQuantity[z] += quantity; // Increment the quantity for the existing dish
alreadyExists = true; // Flag that the dish already exists
break;
}
}
// If the dish is not found, add it to the arrays
if (!alreadyExists) {
arrDishes[x] = menuIndex; // Add the new dish to the array
arrQuantity[x] = quantity; // Add the corresponding quantity
++x; // Increment the index for the next entry
}
}
// Find the most popular dish by looking for the dish with the highest order quantity
for (int y = 0; y < x; y++) {
if (arrQuantity[y] > maxQuantity) {
maxQuantity = arrQuantity[y]; // Update maximum quantity
topDishIndex = arrDishes[y]; // Set the index of the most popular dish
}
}
// If the menu is empty, prompt the user to create a menu first
if (totalNumItems == 0) {
cout << "/// Menu not found! Please create the menu first and try again.\n";
cout << "/// Redirecting to Create/Update Menu...";
createOrUpdateMenu();
} else {
// Display the menu and find the most popular dish
for (int i = 0; i < totalNumItems; i++) {
strMenuIndex = arrMenuContent[i][0];
menuIndex = stoi(strMenuIndex);
if (menuIndex == topDishIndex) {
itemName = arrMenuContent[i][1];
strItemPrice = arrMenuContent[i][2];
itemPrice = stof(strItemPrice);
// Display information about the most popular dish
cout << "\n1. MOST POPULAR DISH OF NINJAFOOD: \n";
cout << "===> " << left << setw(20) << itemName
<< "$" << setw(5) << fixed << setprecision(2) << itemPrice
<< "\t\tTotal orders: " << maxQuantity
<< "\tTotal profit: " << "$" << setw(5) << fixed << setprecision(2) << maxQuantity * itemPrice << "\n";
break;
}
}
}
// Read the total sales data from the file and calculate total sales and customer count
while (getline(totalSalesFile, data))
++index; // Count the number of sales records
totalSalesFile.clear();
totalSalesFile.seekg(0, ios::beg); // Reset file pointer to the beginning
// Read each line and add to the total sales
while (totalSalesFile >> line) {
totalSales += line; // Add each sale amount to the total
++numOfCustomers; // Increment the customer count for each sale
}
// Display the statistics: total orders, total sales, and number of customers
cout << "\n2. TOTAL ORDERS TODAY: " << index;
cout << fixed << setprecision(2) << "\n3. TOTAL SALES TODAY: $" << totalSales;
cout << "\n4. TOTAL NUMBER OF CUSTOMERS TODAY: " << numOfCustomers << "\n";
}
totalSalesFile.close(); // Close the total sales file
topdishFile.close(); // Close the top dish file
// Ask the user whether they want to continue using the program
continueProgram(); // Proceed with the next step in the program
}
// Function to display the menu of the restaurant, showing items, prices, preparation time, and stock
int displayMenu() {
string itemName; // To store the name of the menu item
string line; // Temporary variable to store each line from the menu file
float itemPrice = 0; // To store the price of the item as a float
string strItemPrice; // To store the price as a string
int preparationTime = 0; // To store the preparation time of the item
string strPreparationTime; // To store the preparation time as a string
int stock = 0; // To store the stock quantity of the item
string strStock; // To store the stock quantity as a string
string strIndex; // To store the index of the item as a string
int index = 0; // To store the index of the item
int totalNumItems = 0; // To store the total number of items in the menu
// Read the menu into an array and store the total number of items
string** arrMenuContent = readMenu(totalNumItems);
// If the menu is empty, return 0
if (totalNumItems == 0) {
return 0;
} else {
// Display the menu with item details
cout << "\n/// There are currently " << totalNumItems << " item(s) on the menu.\n"; // Show the number of items on the menu
cout << "\n============================================================================\n";
cout << "=================================== MENU ===================================\n";
cout << "============================================================================\n\n";
cout << "NO. ITEM NAME\t\t ITEM PRICE\tPREPARATION TIME\t STOCK";
cout << "\n-----------------------------------------------------------------------------\n";
// Loop through the menu and display each item
for (int i = 0; i < totalNumItems; i++) {
strIndex = arrMenuContent[i][0];
index = stoi(strIndex); // Convert the string index to integer
itemName = arrMenuContent[i][1]; // Get the item name
strItemPrice = arrMenuContent[i][2];
itemPrice = stof(strItemPrice); // Convert item price to float
strPreparationTime = arrMenuContent[i][3];
preparationTime = stoi(strPreparationTime); // Convert preparation time to integer
strStock = arrMenuContent[i][4];
stock = stoi(strStock); // Convert stock quantity to integer
// Display item details in a tabular format
cout << index << ") " << left << setw(25) << itemName
<< "\t$" << fixed << setprecision(2) << itemPrice;
cout << "\t\t" << preparationTime << " minutes";
cout << "\t\t" << stock << "\n";
}
}
return totalNumItems; // Return the total number of items
}
// Function to accept an order and verify stock availability, updates the order if valid
int acceptOrder(int** arrOrder, int x, int totalMenuItems) {
int numbering = 0; // Temporary variable to store the item numbering
int menuIndex = 0; // To store the menu item index
string line; // Temporary variable for reading file lines
string itemName; // To store the name of the item
int preparationTime = 0; // Preparation time of the item
int stock = 0; // Stock quantity of the item
int invalidItemIndex = 0; // To track the index of invalid items
int totalNumItems = 0; // Total number of items in the menu
string strStock; // Stock quantity in string form for conversion
fstream topdishFile;
topdishFile.open("topdish.txt", ios::out | ios::app); // Open topdish file for appending new orders
// Menu structure: index, itemName, itemPrice, preparationTime, stock
// Dynamically allocated array to hold menu content
string** arrMenuContent = readMenu(totalNumItems);
// Loop through the menu items and check if the order exists
for (int i = 0; i < totalMenuItems; i++) {
menuIndex = stoi(arrMenuContent[i][0]); // Get the menu item index
if (menuIndex == arrOrder[x][0]) { // Match order with menu item
strStock = arrMenuContent[i][4]; // Get the current stock quantity
stock = stoi(strStock); // Convert stock to integer
break;
}
}
// Check if the ordered quantity exceeds the available stock
if (arrOrder[x][1] > stock) {
invalidItemIndex = arrOrder[x][0]; // Store the invalid item's menu index
arrOrder[x][0] = 0; // Set menu index to 0 to indicate invalid item
arrOrder[x][1] = 0; // Set quantity to 0
} else {
// If the order is valid, append the menu index and quantity to the top dish file
topdishFile << arrOrder[x][0] << "," << arrOrder[x][1] << "\n";
updateStocks(menuIndex, arrOrder[x][1], totalMenuItems, stock); // Update stock based on order
}
topdishFile.close(); // Close the top dish file
return invalidItemIndex; // Return the index of invalid items (if any)
}
// Function to update the stock after an order is processed
void updateStocks(int menuIndex, int quantity, int totalMenuItems, int currentStock) {
int index = 0; // To store the menu item index
string itemName; // To store the name of the menu item
string strItemPrice; // To store the price as a string
float itemPrice = 0; // To store the item price
char choice = 'Y'; // User choice for confirming the update (not used here)
int preparationTime = 0; // Preparation time of the item
string strPreparationTime; // Preparation time as a string
int stock = 0; // To store the stock quantity
string strStock; // Stock quantity in string form
string line; // Temporary variable for reading lines from the file
int totalNumItems = 0; // To store the total number of items in the menu
// Menu structure: index, itemName, itemPrice, preparationTime, stock
// Dynamically allocated memory to hold menu content
string** arrMenuContent = readMenu(totalNumItems);
// Loop through the menu and find the item to update its stock
for (int i = 0; i < totalMenuItems; i++) {
index = stoi(arrMenuContent[i][0]); // Get the index of the item
if (index == menuIndex) { // If we find the correct menu item