C++ - Vehicle Rental Application

Vehicle Rental Application - C++


This is an application written in C++ to implement a vehicle rental application. The user can interact with the application and input new information through a graphical user interface.

The car reservation program was developed using CMake, it includes a graphical user interface using the C++ Nana library, aimed to track customers, rental locations, and available vehicles. The system allowed users to add and remove customers, rental locations, and vehicles, while vehicles could be assigned to a rental location for pickup and return, or remain unassigned, indicating their unavailability for rent. Customer management included capturing their first and last names, street address, and age, with the option to designate "preferred customers" who received a 20% discount on rentals, except for those aged 25 or younger who incurred a 20% surcharge and were not eligible for preferred status. Customers could rent cars for specific days, with the system ensuring that a rented car was unavailable for other customers during that period and indicating the unavailability of a car if already booked by another customer.

A video demonstrating the application and the code is shown below:


Alternate Link

View the Source Code below, or view the full codebase on GitHub

CMakeList
Header File
Program
Exported from Notepad++
# CMakeList.txt : CMake project for FinalProject, include source and define # project specific logic here. # cmake_minimum_required (VERSION 3.8) project ("FinalProject") add_definitions( -D_SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING) # Add source to this project's executable. add_executable (FinalProject "FinalProject.cpp" "FinalProject.h") # Link the local nana directories target_include_directories(FinalProject PUBLIC "D:\\nana\\include") target_link_libraries(FinalProject "nana_v143_Debug_x64") target_link_directories(FinalProject PUBLIC "D:\\nana\\build\\bin")
Exported from Notepad++
1 // FinalProject.h : Include file for standard system include files, 2 // or project specific include files. 3 4 #pragma once 5 6 #include "FinalProject.h" 7 8 #include <vector> 9 #include <algorithm> 10 #include <string> 11 #include <iostream> 12 #include <ranges> 13 14 #include <nana/gui.hpp> 15 #include <nana/gui/widgets/label.hpp> 16 #include <nana/gui/widgets/button.hpp> 17 #include <nana/gui/widgets/textbox.hpp> 18 #include <nana/gui/widgets/combox.hpp> 19 20 #include <nana/gui/widgets/checkbox.hpp> 21 using namespace std; 22 using namespace nana; 23 24 // a customer class for managing out customers 25 class Customer { 26 public: 27 string name; 28 string address; 29 int age; 30 int rentals; 31 bool preferred; 32 double amountOwing; 33 double multiplier; 34 35 // constructor 36 public: Customer(string n, string ad, int a, bool pref) 37 { 38 // set the name, age and preffered status 39 name = n; 40 address = ad; 41 age = a; 42 preferred = pref; 43 // set other variables to default values 44 amountOwing = 0; 45 rentals = 0; 46 47 // set the multiplier based on age/prefferred status 48 if (age <= 25) { 49 multiplier = 1.2; 50 } 51 else if (preferred == true) { 52 multiplier = 0.8; 53 } 54 else { 55 multiplier = 1; 56 } 57 } 58 string toString() { 59 return(" " + name + " Address: " + address); 60 } 61 string toStringDetailed() { 62 return(" " + name + " Address: " + address + ", Age: " + to_string(age) + " years old, owes " + to_string(amountOwing) + " dollars"); 63 } 64 }; 65 66 // a location calss for managing our locations 67 class Location { 68 public: 69 // variables needed 70 string name; 71 string address; 72 int cars; 73 74 Location(string n, string a) { 75 name = n; 76 address = a; 77 cars = 0; 78 } 79 80 string toString() { 81 return(" " + name + " " + address); 82 } 83 84 string toStringDetailed() { 85 return(" " + name + " located at " + address + ", there are " + to_string(cars) + " vehicles here"); 86 } 87 }; 88 89 // a vehicle class for managing our vehicles 90 class Vehicle { 91 public: 92 // variables needed 93 string name; 94 string location; 95 string customer; 96 int start; 97 int end; 98 bool cleaning; 99 100 public: 101 // constructor 102 Vehicle(string n, string loc) { 103 // set the name and location 104 name = n; 105 location = loc; 106 // set other variables to default values 107 customer = "N/A"; 108 start = -1; 109 end = -1; 110 cleaning = false; 111 } 112 string toString() { 113 string info = name; 114 115 if (location != "N/A") { 116 // if there is a location return the info 117 if (cleaning == true) { 118 info += " being cleaned at" + location; 119 } 120 else { 121 info += " available at" + location; 122 } 123 }else if (customer != "N/A") { 124 // if a customer is renting return the info 125 info += " rented by " + customer + " from day " + to_string(start) + " to day " + to_string(end); 126 } 127 else { 128 // if no location/customer not for rent 129 info += " not available for rent"; 130 } 131 132 return (" " + info); 133 } 134 }; 135
Exported from Notepad++
1 // FinalProject.cpp 2 // Vehicle Rental Application 3 4 #include "FinalProject.h" 5 6 int main() 7 { 8 // integer to keep track of the date 9 int currentDay = 0; 10 // renting cost 11 double cost = 30; 12 13 // array for vehicles, customers and locations 14 vector<Vehicle> vehicles; 15 vector<Customer> customers; 16 vector<Location> locations; 17 18 // create the information to be shown at start of program 19 string information = ""; 20 for (Vehicle vehicle : vehicles) { 21 information += vehicle.toString() + "\n"; 22 } 23 24 if (information == "") { 25 information = " There are no vehicles"; 26 } 27 28 // create a form/window 29 form window(rectangle(50,50, 1200, 600)); 30 window.caption("Mostapha's Rentals"); 31 window.bgcolor(color_rgb(0xE5E5E5)); 32 33 // create a label 34 label header{window}; 35 header.format(true); 36 header.bgcolor(color_rgb(0xF3F3F3)); 37 header.fgcolor(color_rgb(0x000000)); 38 header.caption("Mostapha's Rentals\nDay: "+to_string(currentDay)); 39 //paint::font defFont = paint::font("", 14, true); 40 //defFont.weight(); 41 //detail::font_style::font_style(weight = 500); 42 header.typeface(paint::font("", 14, true)); 43 44 // create a textbox 45 label text{ window }; 46 text.format(true); 47 text.bgcolor(color_rgb(0xFFFFFF)); 48 text.typeface(paint::font("", 14, true)); 49 text.caption(information); 50 51 // create top (menu) buttons 52 button veh{ window, "Vehicles" }; 53 button cust{ window, "Customers" }; 54 button loc{ window, "Locations" }; 55 button day{ window, "Next Day" }; 56 veh.bgcolor(color_rgb(0xFFFFFF)); 57 cust.bgcolor(color_rgb(0xD6E6EA)); 58 loc.bgcolor(color_rgb(0xD6E6EA)); 59 day.bgcolor(color_rgb(0xD6E6EA)); 60 61 // create section specific buttons 62 #pragma region 63 // vehicle section 64 button allVeh{ window, "View All Vehicles" }; 65 button rentedVeh{ window, "View Rented Vehicles" }; 66 button lateVeh{ window, "View Late Vehicles" }; 67 button addVeh{ window, "Add a Vehicle" }; 68 button removeVeh{ window, "Remove a Vehicle" }; 69 button rentVeh{ window, "Rent a Vehicle" }; 70 button returnVeh{ window, "Return a Vehicle" }; 71 allVeh.bgcolor(color_rgb(0xFFFFFF)); 72 rentedVeh.bgcolor(color_rgb(0xFFFFFF)); 73 lateVeh.bgcolor(color_rgb(0xFFFFFF)); 74 addVeh.bgcolor(color_rgb(0xFFFFFF)); 75 removeVeh.bgcolor(color_rgb(0xFFFFFF)); 76 rentVeh.bgcolor(color_rgb(0xFFFFFF)); 77 returnVeh.bgcolor(color_rgb(0xFFFFFF)); 78 79 // customer section 80 button allCust{ window, "View All Customers" }; 81 button rentCust{ window, "View Customers with Rentals" }; 82 button addCust{ window, "Add a Customer" }; 83 button removeCust{ window, "Remove a Customer" }; 84 allCust.bgcolor(color_rgb(0xFFFFFF)); 85 rentCust.bgcolor(color_rgb(0xFFFFFF)); 86 addCust.bgcolor(color_rgb(0xFFFFFF)); 87 removeCust.bgcolor(color_rgb(0xFFFFFF)); 88 89 // location section 90 button allLoc{ window, "View All Locations" }; 91 button addLoc{ window, "Add a Location" }; 92 button removeLoc{ window, "Remove a Location" }; 93 allLoc.bgcolor(color_rgb(0xFFFFFF)); 94 addLoc.bgcolor(color_rgb(0xFFFFFF)); 95 removeLoc.bgcolor(color_rgb(0xFFFFFF)); 96 #pragma endregion buttons creation 97 98 // define the window layout 99 #pragma region 100 window.div("vert < <HEAD weight = 15%> <VEH> <CUST> <LOC> <DAY> weight = 12%> " 101 +"< < vert <ALLVEH><RENTEDVEH><LATEVEH><><RENTVEH><RETURNVEH><><ADDVEH><REMOVEVEH><> weight = 15%> <INFO> >"); 102 103 // specify layout components 104 window["HEAD"] << header; 105 window["VEH"] << veh; 106 window["CUST"] << cust; 107 window["LOC"] << loc; 108 window["DAY"] << day; 109 window["INFO"] << text; 110 111 window["RENTVEH"] << rentVeh; 112 window["RETURNVEH"] << returnVeh; 113 window["ALLVEH"] << allVeh; 114 window["RENTEDVEH"] << rentedVeh; 115 window["LATEVEH"] << lateVeh; 116 window["ADDVEH"] << addVeh; 117 window["REMOVEVEH"] << removeVeh; 118 119 window["ALLCUST"] << allCust; 120 window["RENTCUST"] << rentCust; 121 window["ADDCUST"] << addCust; 122 window["REMOVECUST"] << removeCust; 123 124 window["ALLLOC"] << allLoc; 125 window["ADDLOC"] << addLoc; 126 window["REMOVELOC"] << removeLoc; 127 128 window.collocate(); 129 #pragma endregion Layout creation and assignments 130 131 // define button functionalities 132 // viewing the vehicles 133 veh.events().click([&] { 134 // update the window's layout 135 window.div("vert < <HEAD weight = 15%> <VEH> <CUST> <LOC> <DAY> weight = 12%> " 136 +"< < vert <ALLVEH><RENTEDVEH><LATEVEH><><RENTVEH><RETURNVEH><><ADDVEH><REMOVEVEH><> weight = 15%> <INFO> >"); 137 window.collocate(); 138 139 // set button colours 140 veh.bgcolor(color_rgb(0xFFFFFF)); 141 cust.bgcolor(color_rgb(0xD6E6EA)); 142 loc.bgcolor(color_rgb(0xD6E6EA)); 143 144 // update the information box 145 information = ""; 146 147 for (Vehicle vehicle : vehicles) { 148 information += vehicle.toString() + "\n"; 149 } 150 151 if (information == "") { 152 information = " There are no vehicles"; 153 } 154 155 text.caption(information); 156 }); 157 158 // viewing the customers 159 cust.events().click([&] { 160 // update the window's layout 161 window.div("vert < <HEAD weight = 15%> <VEH> <CUST> <LOC> <DAY> weight = 12%> " 162 +"< < vert <ALLCUST><RENTCUST><><ADDCUST><REMOVECUST><><><><><> weight = 15%> <INFO> >"); 163 window.collocate(); 164 165 // set button colours 166 veh.bgcolor(color_rgb(0xD6E6EA)); 167 cust.bgcolor(color_rgb(0xFFFFFF)); 168 loc.bgcolor(color_rgb(0xD6E6EA)); 169 170 // update the information box 171 information = ""; 172 173 for (Customer customer : customers) { 174 information += customer.toStringDetailed() + "\n"; 175 } 176 177 if (information == "") { 178 information = " There are no Customers"; 179 } 180 181 text.caption(information); 182 }); 183 184 // viewing the locations 185 loc.events().click([&] { 186 // update the window's layout 187 window.div("vert < <HEAD weight = 15%> <VEH> <CUST> <LOC> <DAY> weight = 12%> "+ 188 "< < vert <ALLLOC><><ADDLOC><REMOVELOC><><><><><><> weight = 15%> <INFO> >"); 189 window.collocate(); 190 191 // set button colours 192 veh.bgcolor(color_rgb(0xD6E6EA)); 193 cust.bgcolor(color_rgb(0xD6E6EA)); 194 loc.bgcolor(color_rgb(0xFFFFFF)); 195 196 // update the information box 197 information = ""; 198 199 for (Location location : locations) { 200 information += location.toStringDetailed() + "\n"; 201 } 202 203 if (information == "") { 204 information = " There are no Locations"; 205 } 206 207 text.caption(information); 208 }); 209 210 // increasing the day 211 day.events().click([&] { 212 // increment day and update header 213 currentDay++; 214 header.caption("Mostapha's Rentals\nDay: " + to_string(currentDay)); 215 216 // update amount owing and cleaning status 217 int i = 0; 218 for (Vehicle vehicle : vehicles) { 219 // update cleaning status 220 if (vehicle.cleaning == true) { 221 vehicles[i].cleaning = false; 222 i++; 223 } 224 // update amount owing 225 if (vehicle.customer != "N/A" && vehicle.start < currentDay) { 226 int i = 0; 227 // find the customer 228 for (Customer customer : customers) { 229 if (customer.toString() == vehicle.customer) { 230 // check if its overdue 231 if (vehicle.end < currentDay) { 232 customers[i].amountOwing += 2 * cost * customers[i].multiplier; 233 } 234 else { 235 customers[i].amountOwing += cost * customers[i].multiplier; 236 } 237 break; 238 } 239 i++; 240 } 241 } 242 } 243 244 text.caption(" Simulated another day passing to day " + to_string(currentDay)); 245 }); 246 247 // define vehicle specific buttons 248 // rent a vehicle button 249 rentVeh.events().click([&] { 250 // create a vector for available vehicles 251 vector<int> availableVeh; 252 253 // create a pop up window 254 form newRentalWindow(window, rectangle(50, 50, 550, 320)); 255 // create boxes for input 256 combox customerInput{ newRentalWindow }; 257 combox locationInput{ newRentalWindow }; 258 combox vehicleInput{ newRentalWindow }; 259 //inputbox::integer start("Start Day:", 0, 0, 0, 0); 260 textbox start{ newRentalWindow }; 261 textbox end{ newRentalWindow }; 262 // button to confirm changes 263 button Rent{ newRentalWindow, "Rent" }; 264 Rent.bgcolor(color_rgb(0x7FEA78)); 265 // labels for input 266 label custLabel{ newRentalWindow, "Choose Customer:" }; 267 label locLabel{ newRentalWindow, "Choose Location:" }; 268 label vehLabel{ newRentalWindow, "Choose Vehicle:" }; 269 label startLabel{ newRentalWindow, " Start Date:" }; 270 label endLabel{ newRentalWindow, " End Date:" }; 271 label message{ newRentalWindow, "" }; 272 273 // create layout and set components 274 newRentalWindow.div("vert <CUSTLABEL weight = 10%><CUST><LOCLABEL weight = 10%><LOC><VEHLABEL weight = 10%>" 275 +"<VEH>< weight = 5%>< <STARTLABEL weight = 12%> <START> <ENDLABEL weight = 12%> <END> ><MESSAGE weight = 10%>" 276 +"<RENT>"); 277 newRentalWindow["CUSTLABEL"] << custLabel; 278 newRentalWindow["CUST"] << customerInput; 279 newRentalWindow["LOCLABEL"] << locLabel; 280 newRentalWindow["LOC"] << locationInput; 281 newRentalWindow["VEHLABEL"] << vehLabel; 282 newRentalWindow["VEH"] << vehicleInput; 283 newRentalWindow["STARTLABEL"] << startLabel; 284 newRentalWindow["START"] << start; 285 newRentalWindow["ENDLABEL"] << endLabel; 286 newRentalWindow["END"] << end; 287 newRentalWindow["MESSAGE"] << message; 288 newRentalWindow["RENT"] << Rent; 289 newRentalWindow.collocate(); 290 291 // populate customers and locations combox 292 for (Customer customer : customers) { 293 customerInput.push_back(customer.toString()); 294 } 295 for (Location location : locations) { 296 locationInput.push_back(location.toString()); 297 } 298 299 // populate vehicles depending on location 300 locationInput.events().selected([&] { 301 // clear the combox 302 vehicleInput.clear(); 303 304 // check location 305 int option = locationInput.option(); 306 307 // add vehicles at that location, keep track of the vehicle selected 308 int i = 0; 309 for (Vehicle vehicle : vehicles) { 310 if (vehicle.location == locations[option].toString() && vehicle.cleaning == false) { 311 vehicleInput.push_back(vehicle.toString()); 312 availableVeh.push_back(i); 313 } 314 } 315 316 API::modal_window(newRentalWindow); 317 }); 318 319 // button after confirming 320 Rent.events().click([&] { 321 // store start and end date 322 string startDate; 323 start.getline(0, startDate); 324 string endDate; 325 end.getline(0, endDate); 326 bool digit = true; 327 328 // confirm dates are digits 329 if (!startDate.empty() && !endDate.empty()) { 330 for (char character : startDate) { 331 if (!isdigit(character)) { 332 digit = false; 333 } 334 } 335 if (digit == true) { 336 for (char character : endDate) { 337 if (!isdigit(character)) { 338 digit = false; 339 } 340 } 341 } 342 } 343 else { 344 digit = false; 345 } 346 347 348 // check if all selections are made and valid 349 if (digit == false) { 350 message.caption("Dates must be integers!"); 351 } else if (vehicleInput.option() == -1) { 352 message.caption("Make a selection!"); 353 } 354 else if (stoi(startDate) < currentDay) { 355 message.caption("Start date must be current day or in the future!"); 356 } 357 else if (stoi(endDate) <= stoi(startDate)) { 358 message.caption("End date must be after start day!"); 359 } 360 else { 361 // change vehicle status 362 vehicles[availableVeh[vehicleInput.option()]].location = "N/A"; 363 vehicles[availableVeh[vehicleInput.option()]].customer = customers[customerInput.option()].toString(); 364 vehicles[availableVeh[vehicleInput.option()]].start = stoi(startDate); 365 vehicles[availableVeh[vehicleInput.option()]].end = stoi(endDate); 366 customers[customerInput.option()].rentals++; 367 locations[locationInput.option()].cars--; 368 369 // print the vehicle 370 text.caption(" " + vehicles[availableVeh[vehicleInput.option()]].toString()); 371 // close window 372 newRentalWindow.close(); 373 } 374 }); 375 API::modal_window(newRentalWindow); 376 }); 377 378 // return a vehicle button 379 returnVeh.events().click([&] { 380 // create a vector for available vehicles 381 vector<int> availableVeh; 382 383 // create a pop up window 384 form newRentalWindow(window, rectangle(50, 50, 550, 290)); 385 // , rectangle(50, 50, 550, 220) 386 387 // create boxes for input 388 combox customerInput{ newRentalWindow }; 389 combox vehicleInput{ newRentalWindow }; 390 combox locationInput{ newRentalWindow }; 391 // button to confirm changes 392 button Return{ newRentalWindow, "Return" }; 393 Return.bgcolor(color_rgb(0x7FEA78)); 394 // labels for input 395 label custLabel{ newRentalWindow, "Choose Customer:" }; 396 label vehLabel{ newRentalWindow, "Choose Vehicle:" }; 397 label locLabel{ newRentalWindow, "Return Vehicle to Location:" }; 398 label message{ newRentalWindow, "" }; 399 400 // create layout and set components 401 newRentalWindow.div("vert <CUSTLABEL weight = 10%><CUST><VEHLABEL weight = 10%><VEH><LOCLABEL weight = 10%>" 402 +"<LOC><MESSAGE weight = 10%><RETURN>"); 403 newRentalWindow["CUSTLABEL"] << custLabel; 404 newRentalWindow["CUST"] << customerInput; 405 newRentalWindow["VEHLABEL"] << vehLabel; 406 newRentalWindow["VEH"] << vehicleInput; 407 newRentalWindow["LOCLABEL"] << locLabel; 408 newRentalWindow["LOC"] << locationInput; 409 newRentalWindow["MESSAGE"] << message; 410 newRentalWindow["RETURN"] << Return; 411 newRentalWindow.collocate(); 412 413 // populate customers and lcoations combox 414 for (Customer customer : customers) { 415 customerInput.push_back(customer.toString()); 416 } 417 for (Location location : locations) { 418 locationInput.push_back(location.toString()); 419 } 420 421 // populate vehicles depending on customer 422 customerInput.events().selected([&] { 423 // clear the combox 424 vehicleInput.clear(); 425 426 // check location 427 int option = customerInput.option(); 428 429 // add vehicles with that customer, keep track of the vehicle selected 430 int i = 0; 431 for (Vehicle vehicle : vehicles) { 432 if (vehicle.customer == customers[option].toString()) { 433 int days; 434 int fee; 435 if (currentDay > vehicle.start) { 436 days = currentDay - vehicle.start; 437 // calculate cost 438 if (vehicle.end >= currentDay) { 439 fee = days * customers[option].multiplier * cost; 440 } 441 else { 442 int regular; 443 int late; 444 445 regular = (vehicle.end - vehicle.start) * customers[option].multiplier * cost; 446 late = (currentDay - vehicle.end) * customers[option].multiplier * cost * 2; 447 448 fee = regular + late; 449 } 450 } 451 else { 452 days = 0; 453 fee = 0; 454 } 455 456 // print vehicle info 457 vehicleInput.push_back(vehicle.toString() + " rented for " + to_string(days) + " days, owing $" 458 + to_string(fee)); 459 availableVeh.push_back(i); 460 } 461 } 462 463 API::modal_window(newRentalWindow); 464 }); 465 466 // button after confirming 467 Return.events().click([&] { 468 // confirm a selection has been made 469 if (vehicleInput.option() == -1) { 470 message.caption("Make a selection!"); 471 } 472 else { 473 // change vehicle status 474 vehicles[availableVeh[vehicleInput.option()]].location = locations[locationInput.option()].toString(); 475 vehicles[availableVeh[vehicleInput.option()]].customer = "N/A"; 476 vehicles[availableVeh[vehicleInput.option()]].cleaning = true; 477 customers[customerInput.option()].rentals--; 478 locations[locationInput.option()].cars++; 479 480 // print the vehicle 481 text.caption(" Returned" + vehicles[availableVeh[vehicleInput.option()]].toString()); 482 // close window 483 newRentalWindow.close(); 484 } 485 486 }); 487 API::modal_window(newRentalWindow); 488 }); 489 490 // view all vehicles button 491 allVeh.events().click([&] { 492 // update the information box 493 information = ""; 494 495 for (Vehicle vehicle : vehicles) { 496 information += vehicle.toString() + "\n"; 497 } 498 499 if (information == "") { 500 information = " There are no vehicles"; 501 } 502 503 text.caption(information); 504 }); 505 506 // view rented vehicles button 507 rentedVeh.events().click([&] { 508 // update the information box 509 information = ""; 510 511 for (Vehicle vehicle : vehicles) { 512 if (vehicle.customer != "N/A") { 513 information += vehicle.toString() + "\n"; 514 } 515 } 516 517 if (information == "") { 518 information = " There are no vehicles being rented"; 519 } 520 521 text.caption(information); 522 }); 523 524 // view late rentals button 525 lateVeh.events().click([&] { 526 // update the information box 527 information = ""; 528 529 for (Vehicle vehicle : vehicles) { 530 if (vehicle.end != -1 && vehicle.end < currentDay) { 531 information += vehicle.toString() + "\n"; 532 } 533 } 534 535 if (information == "") { 536 information = " There are no late vehicles"; 537 } 538 539 text.caption(information); 540 }); 541 542 // add a vehicle button 543 addVeh.events().click([&] { 544 // create a pop up window 545 form newVehicleWindow(window, rectangle(50, 50, 550, 220)); 546 // create text boxes for input 547 textbox nameInput{ newVehicleWindow }; 548 combox locInput{ newVehicleWindow }; 549 550 // push the combox options 551 for (Location loc : locations) { 552 locInput.push_back(loc.toString()); 553 } 554 locInput.push_back(" NONE"); 555 556 // button to confirm changes 557 button add{ newVehicleWindow, "Add" }; 558 add.bgcolor(color_rgb(0x7FEA78)); 559 // labels for input 560 label nameLabel{ newVehicleWindow, "Enter vehicle name:" }; 561 label locLabel{ newVehicleWindow, "Enter vehicle location:" }; 562 label message{ newVehicleWindow, "" }; 563 564 // create layout and set components 565 newVehicleWindow.div("vert <NAMELABEL weight = 10%><NAME><LOCLABEL weight = 10%><LOCATION><MESSAGE weight = 10%>" 566 +"<ADD>"); 567 newVehicleWindow["NAMELABEL"] << nameLabel; 568 newVehicleWindow["NAME"] << nameInput; 569 newVehicleWindow["LOCLABEL"] << locLabel; 570 newVehicleWindow["LOCATION"] << locInput; 571 newVehicleWindow["MESSAGE"] << message; 572 newVehicleWindow["ADD"] << add; 573 newVehicleWindow.collocate(); 574 575 // button after confirming 576 add.events().click([&] { 577 string name; 578 string location; 579 int option; 580 581 // store the input 582 nameInput.getline(0, name); 583 option = locInput.option(); 584 585 // confirm all values were filled 586 if (name.empty() || locInput.option() == -1) { 587 message.caption("Enter all the information!"); 588 } 589 else { 590 if (option == locations.size()) { 591 location = "not availabe for rent"; 592 // create and add vehicle to vector 593 vehicles.push_back(Vehicle(name, "N/A")); 594 } 595 else { 596 location = locations[option].toString(); 597 locations[option].cars++; 598 // create and add vehicle to vector 599 vehicles.push_back(Vehicle(name, location)); 600 } 601 602 // print the added vehicle 603 text.caption(" Added " + name + " - " + location); 604 // close window 605 newVehicleWindow.close(); 606 } 607 }); 608 API::modal_window(newVehicleWindow); 609 }); 610 611 // remove a vehicle button 612 removeVeh.events().click([&] { 613 // create a pop up window 614 form removeVehicleWindow(window, rectangle(0, 0, 500, 120)); 615 // create comox box for input 616 combox vehChoice{ removeVehicleWindow }; 617 618 // push the combox options 619 for (Vehicle veh : vehicles) { 620 vehChoice.push_back(veh.toString()); 621 } 622 623 // button to confirm changes 624 button remove{ removeVehicleWindow, "Remove" }; 625 remove.bgcolor(color_rgb(0xEA7878)); 626 627 // labels for input 628 label vehLabel{ removeVehicleWindow, "Choose which Vehicle to remove:" }; 629 label message{ removeVehicleWindow, "" }; 630 631 // create layout and set components 632 removeVehicleWindow.div("vert <VEHLABEL weight = 15%><VEHCHOICE><MESSAGE weight = 10%><REMOVE>"); 633 removeVehicleWindow["VEHLABEL"] << vehLabel; 634 removeVehicleWindow["VEHCHOICE"] << vehChoice; 635 removeVehicleWindow["MESSAGE"] << message; 636 removeVehicleWindow["REMOVE"] << remove; 637 removeVehicleWindow.collocate(); 638 639 // button after confirming 640 remove.events().click([&] { 641 string name; 642 int option; 643 644 // store the input 645 option = vehChoice.option(); 646 name = vehicles[option].toString(); 647 648 // confirm selection has been made 649 if (option == -1) { 650 message.caption("Make a selection!"); 651 } 652 else if (vehicles[option].customer != "N/A") { 653 text.caption(" Can not delete a rented vehicle, " + name); 654 } 655 else { 656 // remove from location count 657 for (Location location : locations) { 658 if (vehicles[option].location == location.toString()) { 659 location.cars--; 660 break; 661 } 662 } 663 664 // delete the vehicle 665 vehicles.erase(vehicles.begin() + option); 666 667 // print the removed vehicle 668 text.caption(" Removed " + name); 669 } 670 // close window 671 removeVehicleWindow.close(); 672 }); 673 API::modal_window(removeVehicleWindow); 674 }); 675 676 // define customer specific buttons 677 // view all customers button 678 allCust.events().click([&] { 679 // update the information box 680 information = ""; 681 682 for (Customer customer : customers) { 683 information += customer.toStringDetailed() + "\n"; 684 } 685 686 if (information == "") { 687 information = " There are no Customers"; 688 } 689 690 text.caption(information); 691 }); 692 693 // view customers with rentals button 694 rentCust.events().click([&] { 695 // update the information box 696 information = ""; 697 698 for (Vehicle vehicle : vehicles) { 699 if (vehicle.customer != "N/A") { 700 // find customer 701 for (Customer cust : customers) { 702 string custString = cust.toStringDetailed(); 703 if (custString == vehicle.customer) { 704 information += custString + "\n"; 705 } 706 } 707 } 708 } 709 710 if (information == "") { 711 information = " There are no Customers with Rentals"; 712 } 713 714 text.caption(information); 715 }); 716 717 // add a customer button 718 addCust.events().click([&] { 719 // create a pop up window 720 form newCustomerWindow(window, rectangle(50, 50, 550, 320)); 721 // create text boxes for input 722 textbox nameInput{ newCustomerWindow }; 723 textbox ageInput{ newCustomerWindow }; 724 textbox addressInput{ newCustomerWindow }; 725 checkbox prefCbox{ newCustomerWindow }; 726 prefCbox.caption("Preferred"); 727 // button to confirm changes 728 button add{ newCustomerWindow, "Add" }; 729 add.bgcolor(color_rgb(0x7FEA78)); 730 // labels for input 731 label nameLabel{ newCustomerWindow, "Enter customer name:" }; 732 label ageLabel{ newCustomerWindow, "Enter customer age:" }; 733 label addressLabel{ newCustomerWindow, "Enter customer address:" }; 734 label preferredLabel{ newCustomerWindow, "Enter customer status:" }; 735 label message{ newCustomerWindow, "" }; 736 737 // create layout and set components 738 newCustomerWindow.div("vert <NAMELABEL weight = 10%><NAME><AGELABEL weight = 10%><AGE><ADDRESSLABEL weight = 10%>" 739 +"<ADDRESS><PREFLABEL weight = 10%><PREF><MESSAGE weight = 10%><ADD>"); 740 newCustomerWindow["NAMELABEL"] << nameLabel; 741 newCustomerWindow["NAME"] << nameInput; 742 newCustomerWindow["AGELABEL"] << ageLabel; 743 newCustomerWindow["AGE"] << ageInput; 744 newCustomerWindow["ADDRESSLABEL"] << addressLabel; 745 newCustomerWindow["ADDRESS"] << addressInput; 746 newCustomerWindow["PREFLABEL"] << preferredLabel; 747 newCustomerWindow["PREF"] << prefCbox; 748 newCustomerWindow["MESSAGE"] << message; 749 newCustomerWindow["ADD"] << add; 750 newCustomerWindow.collocate(); 751 752 // ensure preferred status cannot be checked if under 26 753 prefCbox.events().click([&] { 754 string age; 755 int ageNum; 756 try { 757 if (ageInput.getline(0, age)) 758 ageInput.getline(0, age); 759 ageNum = stoi(age); 760 if (age != "" && ageNum <= 25) 761 prefCbox.check(false); 762 } 763 catch (exception& ex) { 764 int i = 0; 765 prefCbox.check(false); 766 } 767 }); 768 ageInput.events().key_release([&] { 769 string age; 770 int ageNum; 771 try { 772 if (ageInput.getline(0, age)) 773 ageInput.getline(0, age); 774 ageNum = stoi(age); 775 if (age != "" && ageNum <= 25) 776 prefCbox.check(false); 777 } 778 catch (exception& ex) { 779 prefCbox.check(false); 780 }}); 781 782 // button after confirming 783 add.events().click([&] { 784 string name; 785 string age; 786 string address; 787 bool preferred = false; 788 bool digit = true; 789 790 // store the input 791 nameInput.getline(0, name); 792 ageInput.getline(0, age); 793 addressInput.getline(0, address); 794 // check preferred status 795 if (prefCbox.checked() == true) { 796 preferred = true; 797 } 798 799 // confirm age is an int 800 if (age.empty()) { 801 digit = false; 802 } 803 else { 804 for (char character : age) { 805 if (!isdigit(character)) { 806 digit = false; 807 break; 808 } 809 } 810 } 811 812 // confirm all information has been inputted and correct 813 if (digit == false) { 814 message.caption("Age must be an integer!"); 815 } 816 else if (stoi(age) <= 16) { 817 message.caption("Customers must be atleast 16 years of age!"); 818 } 819 else if (name.empty() || address.empty()) { 820 message.caption("Fill in all the information!"); 821 } else{ 822 // create and add customer to vector 823 customers.push_back(Customer(name, address, stoi(age), preferred)); 824 825 // print the added customer 826 text.caption(" Added " + customers.back().toString()); 827 // close window 828 newCustomerWindow.close(); 829 } 830 }); 831 API::modal_window(newCustomerWindow); 832 }); 833 834 // remove a customer button 835 removeCust.events().click([&] { 836 // create a pop up window 837 form removeCustomerWindow(window, rectangle(0, 0, 500, 120)); 838 // create comox box for input 839 combox custChoice{ removeCustomerWindow }; 840 841 // push the combox options 842 for (Customer cust : customers) { 843 custChoice.push_back(cust.toString()); 844 } 845 846 // button to confirm changes 847 button remove{ removeCustomerWindow, "Remove" }; 848 remove.bgcolor(color_rgb(0xEA7878)); 849 850 // labels for input 851 label custLabel{ removeCustomerWindow, "Choose which Customer to remove:" }; 852 label message{ removeCustomerWindow, "" }; 853 854 // create layout and set components 855 removeCustomerWindow.div("vert <CUSTLABEL weight = 15%><CUSTCHOICE><MESSAGE weight = 10%><REMOVE>"); 856 removeCustomerWindow["CUSTLABEL"] << custLabel; 857 removeCustomerWindow["CUSTCHOICE"] << custChoice; 858 removeCustomerWindow["MESSAGE"] << message; 859 removeCustomerWindow["REMOVE"] << remove; 860 removeCustomerWindow.collocate(); 861 862 // button after confirming 863 remove.events().click([&] { 864 string name; 865 int option; 866 867 // store the input 868 option = custChoice.option(); 869 870 // confirm a selection has been made 871 if (option == -1) { 872 message.caption("Make a selection!"); 873 } 874 else { 875 name = customers[option].toString(); 876 877 // check if they are currently renting 878 if (customers[option].rentals > 0) { 879 text.caption(" Cannot remove customers currently renting, " + name); 880 } 881 else { 882 // delete the customer 883 customers.erase(customers.begin() + option); 884 885 // print the removed customer 886 text.caption(" Removed " + name); 887 } 888 // close window 889 removeCustomerWindow.close(); 890 } 891 }); 892 API::modal_window(removeCustomerWindow); 893 }); 894 895 // define location specific buttons 896 // view all locations 897 allLoc.events().click([&] { 898 // update the information box 899 information = ""; 900 901 for (Location location : locations) { 902 information += location.toStringDetailed() + "\n"; 903 } 904 905 if (information == "") { 906 information = " There are no Locations"; 907 } 908 909 text.caption(information); 910 }); 911 912 // add a location 913 addLoc.events().click([&] { 914 // create a pop up window 915 form newLocationWindow(window, rectangle(50, 50, 550, 220)); 916 // create text boxes for input 917 textbox nameInput{ newLocationWindow }; 918 textbox addressInput{ newLocationWindow }; 919 // button to confirm changes 920 button add{ newLocationWindow, "Add" }; 921 add.bgcolor(color_rgb(0x7FEA78)); 922 // labels for input 923 label nameLabel{ newLocationWindow, "Enter location name:" }; 924 label adressLabel{ newLocationWindow, "Enter location address:" }; 925 label message{ newLocationWindow, "" }; 926 927 // create layout and set components 928 newLocationWindow.div("vert <NAMELABEL weight = 10%><NAME><ADRESSLABEL weight = 10%><ADDRESS>" 929 +"<MESSAGE weight = 10%><ADD>"); 930 newLocationWindow["NAMELABEL"] << nameLabel; 931 newLocationWindow["NAME"] << nameInput; 932 newLocationWindow["ADRESSLABEL"] << adressLabel; 933 newLocationWindow["ADDRESS"] << addressInput; 934 newLocationWindow["MESSAGE"] << message; 935 newLocationWindow["ADD"] << add; 936 newLocationWindow.collocate(); 937 938 // button after confirming 939 add.events().click([&] { 940 string name; 941 string address; 942 // store the input 943 nameInput.getline(0, name); 944 addressInput.getline(0, address); 945 946 // confirm input is not empty 947 if (name.empty() || address.empty()) { 948 message.caption("Enter all requested information!"); 949 } 950 else { 951 // create and add customer to vector 952 locations.push_back(Location(name, address)); 953 954 // print the added customer 955 text.caption(" Added " + locations.back().toString()); 956 // close window 957 newLocationWindow.close(); 958 } 959 }); 960 API::modal_window(newLocationWindow); 961 }); 962 963 // remove a location 964 removeLoc.events().click([&] { 965 // create a pop up window 966 form removeLocationWindow(window, rectangle(0, 0, 500, 120)); 967 // create comox box for input 968 combox locChoice{ removeLocationWindow }; 969 970 // push the combox options 971 for (Location loc : locations) { 972 locChoice.push_back(loc.toString()); 973 } 974 975 // button to confirm changes 976 button remove{ removeLocationWindow, "Remove" }; 977 remove.bgcolor(color_rgb(0xEA7878)); 978 979 // labels for input 980 label locLabel{ removeLocationWindow, "Choose which Location to remove:" }; 981 label message{ removeLocationWindow, "" }; 982 983 // create layout and set components 984 removeLocationWindow.div("vert <LOCLABEL weight = 15%><LOCCHOICE><MESSAGE weight = 10%><REMOVE>"); 985 removeLocationWindow["LOCLABEL"] << locLabel; 986 removeLocationWindow["LOCCHOICE"] << locChoice; 987 removeLocationWindow["MESSAGE"] << message; 988 removeLocationWindow["REMOVE"] << remove; 989 removeLocationWindow.collocate(); 990 991 // button after confirming 992 remove.events().click([&] { 993 string name; 994 int option; 995 996 // store the input 997 option = locChoice.option(); 998 999 // confirm a location has been selected 1000 if (option == -1) { 1001 message.caption("Make a selection!"); 1002 } 1003 else { 1004 name = locations[option].toString(); 1005 if (locations[option].cars > 0) { 1006 text.caption(" Cannot remove a location with vehicles, " + name); 1007 } 1008 else { 1009 // delete the location 1010 locations.erase(locations.begin() + option); 1011 1012 // print the removed location 1013 text.caption(" Removed " + name); 1014 } 1015 // close window 1016 removeLocationWindow.close(); 1017 } 1018 }); 1019 API::modal_window(removeLocationWindow); 1020 }); 1021 1022 // show the window 1023 window.show(); 1024 1025 // event loop until window is closed 1026 exec(); 1027 } 1028