diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj index 819264c..fd7c056 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj @@ -181,6 +181,7 @@ + diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters index 7c17f4e..701e0c5 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters @@ -236,5 +236,8 @@ Header Files\Utilities + + Header Files\Views + \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 8b67c7d..c6e2f85 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -119,14 +119,17 @@ void PaymentManagementService::completePayment(const std::string& invoiceID, uti if (invoiceIndex != -1) { Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); - User* currentUser = invoice->getBooking()->getCustomer(); - invoice->setPaymentMethod(paymentMode); - invoice->setPaymentDate(util::Timestamp()); - invoice->setStatus(util::PaymentStatus::COMPLETED); - std::string title, message; - title = "Payment successful"; - message = "Payment successful for invoice ID " + invoiceID; - sendNotification(currentUser, title, message); + if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED) + { + User* currentUser = invoice->getBooking()->getCustomer(); + invoice->setPaymentMethod(paymentMode); + invoice->setPaymentDate(util::Timestamp()); + invoice->setStatus(util::PaymentStatus::COMPLETED); + std::string title, message; + title = "Payment successful"; + message = "Payment successful for invoice ID " + invoiceID; + sendNotification(currentUser, title, message); + } } else { diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 393fe8d..c9cb818 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -83,12 +83,16 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const for (int iterator = 0; iterator < inventoryItems.getSize(); iterator++) { InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iterator); - if (currentInventoryItem->getQuantity() == 0) + if (currentInventoryItem && currentInventoryItem->getQuantity() == 0) { std::string errorMessage = "Failed to create job card, " + currentInventoryItem->getPartName() + " is out of stock."; throw std::runtime_error(errorMessage); } - else + } + for (int iterator = 0; iterator < inventoryItems.getSize(); iterator++) + { + InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iterator); + if (currentInventoryItem) { int currentStockQuantity = currentInventoryItem->getQuantity(); currentInventoryItem->setQuantity(currentStockQuantity - 1); @@ -99,8 +103,15 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const std::string title = "Job card created"; std::string message = "Job card created for the service and you are assigned for that."; JobCard* jobCard = Factory::getObject(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp()); - currentJobCards.insert(jobCard->getId(), jobCard); - sendNotification(selectedTechnician,title, message); + if (jobCard) + { + currentJobCards.insert(jobCard->getId(), jobCard); + sendNotification(selectedTechnician, title, message); + } + else + { + throw std::runtime_error("Failed to create job card."); + } } /* @@ -177,7 +188,7 @@ Throws: */ void ServiceManagementService::removeService(const std::string& serviceID) { - util::Map currentServices = getServices(); + util::Map& currentServices = m_dataStore.getServices(); if (currentServices.find(serviceID) != -1) { currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE); @@ -238,7 +249,7 @@ util::Map ServiceManagementService::getJobCards(const std } /* -Function: hasAllJobCardsinServiceBookingCompleted (static helper) +Function: hasCompletedAllJobs (static helper) Description: Checks if all job cards for a given service booking are completed. Parameters: - bookingId: std::string, ID of the service booking @@ -246,7 +257,7 @@ Parameters: Returns: - bool: True if all job cards are completed, False otherwise */ -static bool hasAllJobCardsinServiceBookingCompleted(std::string bookingId, util::Map& currentAssignedJobs) +static bool hasCompletedAllJobs(std::string bookingId, util::Map& currentAssignedJobs) { for (int iterator = 0; iterator < currentAssignedJobs.getSize(); iterator++) { @@ -312,7 +323,7 @@ void ServiceManagementService::completeJob(const std::string& jobID) throw std::runtime_error("Failed to complete the job, some error occured or job already completed."); } - serviceBookingCompleted = hasAllJobCardsinServiceBookingCompleted(currentJob->getBookingId(), currentAssignedJobs); + serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs); if (serviceBookingCompleted) { currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h index f198108..7dda730 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h @@ -130,7 +130,7 @@ namespace util case ServiceJobStatus::COMPLETED: return "COMPLETED"; case ServiceJobStatus::PENDING: - return "STARTED"; + return "PENDING"; } throw std::invalid_argument("Invalid ServiceJobStatus"); } @@ -145,6 +145,10 @@ namespace util { return ServiceJobStatus::COMPLETED; } + if (value == "PENDING") + { + return ServiceJobStatus::PENDING; + } throw std::invalid_argument("Invalid ServiceJobStatus string"); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp index b539aa8..43cccc1 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp @@ -1,11 +1,11 @@ #include #include "AdminMenu.h" +#include "MenuHelper.h" #include "Service.h" #include "InputHelper.h" #include "OutputHelper.h" #include "ServiceBooking.h" #include "Enums.h" -#include "Service.h" #include "InventoryItem.h" void AdminMenu::showMenu() @@ -62,148 +62,6 @@ void AdminMenu::checkStockAvailability() { } -/* -Function: listServiceBookings (static helper) -Description: Lists all pending service bookings and maps them to indices for selection. -Parameters: - - currentBookings: util::Map&, current bookings - - bookingsSize: int&, number of bookings - - serviceBookingsMap: util::Map&, map of indexed bookings -Returns: - - bool: True if pending services exist, False otherwise -*/ -static bool listServiceBookings(util::Map& currentBookings, int& bookingsSize, util::Map& serviceBookingsMap) -{ - int currentIndex = 1; - bool hasPendingService = false; - std::cout << std::left - << std::setw(10) << "Index" - << std::setw(10) << "ID" - << std::setw(12) << "Status" - << std::setw(12) << "CustID" - << std::setw(20) << "Customer" - << std::setw(15) << "VehicleNo" - << std::setw(15) << "Brand" - << std::setw(15) << "Model" - << std::setw(20) << "Technician" - << std::setw(15) << "TechID" - << std::endl; - for (int iterator = 0; iterator < bookingsSize; iterator++) - { - const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator); - if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING) - { - hasPendingService = true; - std::cout << std::left - << std::setw(10) << currentIndex - << std::setw(10) << currentBooking->getId() - << std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus()) - << std::setw(12) << currentBooking->getCustomerId() - << std::setw(20) << currentBooking->getCustomer()->getName() - << std::setw(15) << currentBooking->getVehicleNumber() - << std::setw(15) << currentBooking->getVehicleBrand() - << std::setw(15) << currentBooking->getVehicleModel() - << std::setw(20) << (currentBooking->getAssignedTechnician() == nullptr ? "Null" : currentBooking->getAssignedTechnician()->getName()) - << std::setw(15) << (currentBooking->getAssignedTechnicianId().empty() ? "Null" : currentBooking->getAssignedTechnicianId()) - << std::endl; - serviceBookingsMap.insert(currentIndex++, currentBooking); - } - } - if (!hasPendingService) - { - std::cout << "No pending service available." << std::endl; - return false; - } - return true; -} - -/* -Function: selectPendingServiceBookings (static helper) -Description: Allows selection of a pending service booking by index. -Parameters: - - serviceBookingsMap: util::Map&, map of indexed bookings -Returns: - - const ServiceBooking*: Pointer to the selected booking, or nullptr if invalid -*/ -static const ServiceBooking* selectPendingServiceBookings(util::Map& serviceBookingsMap) -{ - int userInputIndex; - std::cout << "Enter a valid service index: "; - util::read(userInputIndex); - if (serviceBookingsMap.find(userInputIndex) != -1) - { - return serviceBookingsMap.getValueAt(userInputIndex); - } - else - { - std::cout << "Enter a valid index."; - return nullptr; - } -} - -/* -Function: listAvailableTechnicians (static helper) -Description: Lists all available technicians and maps them to indices for selection. -Parameters: - - currentAvailableTechnicians: util::Map, available technicians - - numberOfTechnicians: int, number of technicians - - currentAvailableTechniciansMap: util::Map&, map of indexed technicians -Returns: - - void -*/ -static void listAvailableTechnicians( util::Map currentAvailableTechnicians, int numberOfTechnicians, util::Map& currentAvailableTechniciansMap) -{ - bool hasTechnicians = false; - int currentIndex = 1; - std::cout << std::left - << std::setw(6) << "Index" - << std::setw(15) << "Technician ID" - << std::setw(20) << "Name" - << std::endl; - for (int iterator = 0; iterator < numberOfTechnicians; iterator++) - { - const User* currentTechnician = currentAvailableTechnicians.getValueAt(iterator); - if (currentTechnician->getState() == util::State::INACTIVE) - { - continue; - } - hasTechnicians = true; - std::cout << std::left - << std::setw(6) << currentIndex - << std::setw(15) << currentTechnician->getId() - << std::setw(20) << currentTechnician->getName() - << std::endl; - currentAvailableTechniciansMap.insert(currentIndex++, currentTechnician); - } - if (!hasTechnicians) - { - std::cout << "No technicians currently available."; - } -} - -/* -Function: selectTechnician (static helper) -Description: Allows selection of a technician by index. -Parameters: - - currentAvailableTechniciansMap: util::Map&, map of indexed technicians -Returns: - - const User*: Pointer to the selected technician, or nullptr if invalid -*/ -static const User* selectTechnician(util::Map& currentAvailableTechniciansMap) -{ - int userInputIndex; - util::read(userInputIndex); - if (currentAvailableTechniciansMap.find(userInputIndex) != -1) - { - return currentAvailableTechniciansMap.getValueAt(userInputIndex); - } - else - { - std::cout << "Enter a valid index."; - return nullptr; - } -} - /* Function: assignJob Description: Allows the admin to assign pending service bookings to available technicians. @@ -247,81 +105,7 @@ void AdminMenu::assignJob() } } } - -} - -/* -Function: selectInventoryItems (static helper) -Description: Allows selection of inventory items by index for creating a service. -Parameters: - - currentInventoryItems: util::Map&, available inventory items - - selectedInventoryItems: util::Vector&, vector to store selected item IDs -Returns: - - void -*/ -static void selectInventoryItems(util::Map& currentInventoryItems, util::Vector& selectedInventoryItems) -{ - bool doRun = true, hasInventoryItems = false; - util::Map currentInventoryMap; - int currentIndex = 1; - int choice; - if (currentInventoryItems.getSize() == 0) - { - std::cout << "Inventory empty."; - } - while (doRun) - { - bool hasInventoryItems = false; - int currentIndex = 1; - currentInventoryMap.clear(); - std::cout << std::left - << std::setw(6) << "Index" - << std::setw(12) << "Item ID" - << std::setw(20) << "Part Name" - << std::setw(10) << "Price" - << std::setw(10) << "Quantity" - << std::endl; - for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++) - { - const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator); - if (currentInventoryItem->getState() == util::State::INACTIVE) - { - continue; - } - std::cout << std::left - << std::setw(6) << currentIndex - << std::setw(12) << currentInventoryItem->getId() - << std::setw(20) << currentInventoryItem->getPartName() - << std::setw(10) << currentInventoryItem->getPrice() - << std::setw(10) << currentInventoryItem->getQuantity() - << std::endl; - - hasInventoryItems = true; - currentInventoryMap.insert(currentIndex++, currentInventoryItem); - } - if (!hasInventoryItems) - { - std::cout << "No items present in the inventory." << std::endl; - doRun = false; - break; - } - std::cout << "Select the item (Index) or enter -1 to exit: "; - util::read(choice); - - if (choice == -1) - { - doRun = false; - } - else if (currentInventoryMap.find(choice) != -1) - { - selectedInventoryItems.push_back(currentInventoryMap.getValueAt(choice)->getId()); - std::cout << "Item added successfully." << std::endl; - } - else - { - std::cout << "Enter a valid integer." << std::endl; - } - } + util::pressEnter(); } /* @@ -346,59 +130,7 @@ void AdminMenu::createService() util::read(labourCost); m_controller.createService(serviceName, selectedInventoryItems, labourCost); std::cout << "Service created sucessfully.\n"; -} - -/* -Function: selectServicesToRemove (static helper) -Description: Allows selection of a service to remove by index. -Parameters: - - currentServices: util::Map, available services -Returns: - - std::string: ID of the selected service, or empty string if invalid -*/ -static std::string selectServicesToRemove(util::Map currentServices) -{ - util::Map currentServicesMap; - bool hasServices = false; - int currentIndex = 1, choice; - std::cout << std::left - << std::setw(6) << "Index" - << std::setw(12) << "Service ID" - << std::setw(20) << "Name" - << std::setw(10) << "Labor Cost" - << std::endl; - for (int iterator = 0; iterator < currentServices.getSize(); iterator++) - { - const Service* currentService = currentServices.getValueAt(iterator); - if (currentService->getState() == util::State::INACTIVE) - { - continue; - } - std::cout << std::left - << std::setw(6) << currentIndex - << std::setw(12) << currentService->getId() - << std::setw(20) << currentService->getName() - << std::setw(10) << currentService->getLaborCost() - << std::endl; - hasServices = true; - currentServicesMap.insert(currentIndex++, currentService); - } - if (!hasServices) - { - std::cout << "No services currently available." << std::endl; - return ""; - } - std::cout << "Enter your choice: "; - util::read(choice); - if (currentServicesMap.find(choice) != -1) - { - return currentServicesMap.getValueAt(currentServicesMap.find(choice))->getId(); - } - else - { - std::cout << "Invalid choice." << std::endl; - return ""; - } + util::pressEnter(); } /* @@ -424,6 +156,7 @@ void AdminMenu::removeService() { std::cout << "Failed to remove service."; } + util::pressEnter(); } void AdminMenu::addTechnician() @@ -444,4 +177,4 @@ void AdminMenu::removeComboPackage() void AdminMenu::viewNotifications() { -} +} \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 11f3706..dde094c 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -2,6 +2,7 @@ #include #include "CustomerMenu.h" #include "InputHelper.h" +#include "MenuHelper.h" #include "OutputHelper.h" #include "Invoice.h" #include "Enums.h" @@ -109,98 +110,7 @@ void CustomerMenu::viewServiceHistory() { std::cout << "No history available." << std::endl; } -} - -/* -Function: selectInvoiceFromUserForPayment (static helper) -Description: Lists all pending invoices for the customer and allows selection by index. -Parameters: - - currentInvoices: util::Map&, map of customer invoices -Returns: - - std::string: ID of the selected invoice, or empty string if none selected -*/ -static std::string selectInvoiceFromUserForPayment(const util::Map& currentInvoices) -{ - int currentIndex = 1, choice; - util::Map pendingInvoicesForPayment; - std::cout << std::left - << std::setw(6) << "Index" - << std::setw(12) << "BookingID" - << std::setw(15) << "VehicleBrand" - << std::setw(15) << "VehicleNumber" - << std::setw(12) << "TechID" - << std::setw(20) << "TechnicianName" - << std::setw(10) << "Discount(%)" - << std::setw(12) << "TotalAmount" - << std::setw(20) << "InvoiceDate" - << std::endl; - for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++) - { - const Invoice* currentInvoice = currentInvoices.getValueAt(iterator); - if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING) - { - std::cout << std::left - << std::setw(6) << currentIndex - << std::setw(12) << currentInvoice->getBookingId() - << std::setw(15) << currentInvoice->getBooking()->getVehicleBrand() - << std::setw(15) << currentInvoice->getBooking()->getVehicleNumber() - << std::setw(12) << currentInvoice->getBooking()->getAssignedTechnician()->getId() - << std::setw(20) << currentInvoice->getBooking()->getAssignedTechnician()->getName() - << std::setw(10) << currentInvoice->getDiscountPercentage() - << std::setw(12) << currentInvoice->getTotalAmount() - << std::setw(20) << currentInvoice->getInvoiceDate().toString() - << std::endl; - pendingInvoicesForPayment.insert(currentIndex++, currentInvoice); - } - } - if (pendingInvoicesForPayment.getSize() == 0) - { - std::cout << "No pending invoices available for payment.\n"; - return ""; - } - std::cout << "Select the Invoice to pay (Index): "; - util::read(choice); - int selectedIndex = pendingInvoicesForPayment.find(choice); - if (selectedIndex != -1) - { - const Invoice* selectedInvoice = pendingInvoicesForPayment.getValueAt(selectedIndex); - return selectedInvoice->getId(); - } - else - { - std::cout << "Invalid choice.\n"; - return ""; - } -} - -/* -Function: selectPaymentMode (static helper) -Description: Allows the customer to select a payment mode (ONLINE or OFFLINE). -Parameters: - - None -Returns: - - util::PaymentMode: Selected payment mode -*/ -static util::PaymentMode selectPaymentMode() -{ - int choice; - std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: "; - util::read(choice); - if (choice == 1) - { - std::cout << "Offline mode selected.\n"; - return util::PaymentMode::OFFLINE; - } - else if (choice == 2) - { - std::cout << "Online mode selected.\n"; - return util::PaymentMode::ONLINE; - } - else - { - std::cout << "Invalid choice, Offline mode selected.\n"; - return util::PaymentMode::OFFLINE; - } + util::pressEnter(); } /* @@ -225,68 +135,7 @@ void CustomerMenu::completePayments() util::PaymentMode paymentMode = selectPaymentMode(); m_controller.completePayment(selectedID, paymentMode); std::cout << "Payment completed successfully.\n"; -} - -/* -Function: displayInvoices (static helper) -Description: Displays detailed information for all invoices associated with the customer, - including booking details, technician, discount, total amount, payment status, and items used. -Parameters: - - currentUserInvoices: util::Map, customer’s invoices -Returns: - - void -Throws: - - std::runtime_error if a null invoice is encountered -*/ -static void displayInvoices(util::Map currentUserInvoices) -{ - if (currentUserInvoices.getSize() == 0) - { - std::cout << "No invoices found for this account." << std::endl; - util::pressEnter(); - return; - } - else - { - for (int index = 0; index < currentUserInvoices.getSize(); index++) - { - const Invoice* currentInvoice = currentUserInvoices.getValueAt(index); - if (currentInvoice) - { - std::cout << "\nInvoice Details\n"; - std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl; - std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl; - std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl; - std::cout << "Technician ID: " << currentInvoice->getBooking()->getAssignedTechnician()->getId() << std::endl; - std::cout << "Technician Name: " << currentInvoice->getBooking()->getAssignedTechnician()->getName() << std::endl; - std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl; - std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl; - std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl; - std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl; - auto inventoryItemsInInvoice = currentInvoice->getParts(); - std::cout << "\nItems Used:\n"; - std::cout << std::left - << std::setw(20) << "ItemName" - << std::setw(10) << "Quantity" - << std::setw(10) << "Price" - << std::endl; - std::cout << std::string(40, '-') << std::endl; - for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++) - { - InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator); - std::cout << std::left - << std::setw(20) << currentItem->getPartName() - << std::setw(10) << currentItem->getQuantity() - << std::setw(10) << currentItem->getPrice() - << std::endl; - } - } - else - { - throw std::runtime_error("Null invoice encountered while displaying invoices."); - } - } - } + util::pressEnter(); } /* @@ -302,6 +151,7 @@ void CustomerMenu::viewInvoices() util::clear(); util::Map currentUserInvoices = m_controller.getInvoicesByUser(); displayInvoices(currentUserInvoices); + util::pressEnter(); } void CustomerMenu::viewNotifications() @@ -310,4 +160,4 @@ void CustomerMenu::viewNotifications() void CustomerMenu::configureNotifications() { -} +} \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h new file mode 100644 index 0000000..975fcc7 --- /dev/null +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h @@ -0,0 +1,501 @@ +#include +#include "Service.h" +#include "Enums.h" +#include "User.h" +#include "JobCard.h" +#include "InventoryItem.h" +#include "Invoice.h" +#include "ServiceBooking.h" +#include "Map.h" +#include "Timestamp.h" +#include "InputHelper.h" +#include "OutputHelper.h" + +/* +Function: selectServicesToRemove (static helper) +Description: Allows selection of a service to remove by index. +Parameters: + - currentServices: util::Map, available services +Returns: + - std::string: ID of the selected service, or empty string if invalid +*/ +inline std::string selectServicesToRemove(util::Map currentServices) +{ + util::Map currentServicesMap; + bool hasServices = false; + int currentIndex = 1, choice; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "Service ID" + << std::setw(20) << "Name" + << std::setw(10) << "Labor Cost" + << std::endl; + for (int iterator = 0; iterator < currentServices.getSize(); iterator++) + { + const Service* currentService = currentServices.getValueAt(iterator); + if (currentService->getState() == util::State::INACTIVE) + { + continue; + } + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentService->getId() + << std::setw(20) << currentService->getName() + << std::setw(10) << currentService->getLaborCost() + << std::endl; + hasServices = true; + currentServicesMap.insert(currentIndex++, currentService); + } + if (!hasServices) + { + std::cout << "No services currently available." << std::endl; + return ""; + } + std::cout << "Enter your choice: "; + util::read(choice); + if (currentServicesMap.find(choice) != -1) + { + return currentServicesMap.getValueAt(currentServicesMap.find(choice))->getId(); + } + else + { + std::cout << "Invalid choice." << std::endl; + return ""; + } +} + +/* +Function: selectInventoryItems (static helper) +Description: Allows selection of inventory items by index for creating a service. +Parameters: + - currentInventoryItems: util::Map&, available inventory items + - selectedInventoryItems: util::Vector&, vector to store selected item IDs +Returns: + - void +*/ +static void selectInventoryItems(util::Map& currentInventoryItems, util::Vector& selectedInventoryItems) +{ + bool doRun = true, hasInventoryItems = false; + util::Map currentInventoryMap; + int currentIndex = 1; + int choice; + if (currentInventoryItems.getSize() == 0) + { + std::cout << "Inventory empty."; + } + while (doRun) + { + bool hasInventoryItems = false; + int currentIndex = 1; + currentInventoryMap.clear(); + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "Item ID" + << std::setw(20) << "Part Name" + << std::setw(10) << "Price" + << std::setw(10) << "Quantity" + << std::endl; + for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++) + { + const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator); + if (currentInventoryItem->getState() == util::State::INACTIVE) + { + continue; + } + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentInventoryItem->getId() + << std::setw(20) << currentInventoryItem->getPartName() + << std::setw(10) << currentInventoryItem->getPrice() + << std::setw(10) << currentInventoryItem->getQuantity() + << std::endl; + + hasInventoryItems = true; + currentInventoryMap.insert(currentIndex++, currentInventoryItem); + } + if (!hasInventoryItems) + { + std::cout << "No items present in the inventory." << std::endl; + doRun = false; + break; + } + std::cout << "Select the item (Index) or enter -1 to exit: "; + util::read(choice); + + if (choice == -1) + { + doRun = false; + } + else if (currentInventoryMap.find(choice) != -1) + { + selectedInventoryItems.push_back(currentInventoryMap.getValueAt(choice)->getId()); + std::cout << "Item added successfully." << std::endl; + } + else + { + std::cout << "Enter a valid integer." << std::endl; + } + } +} + +/* +Function: listServiceBookings (static helper) +Description: Lists all pending service bookings and maps them to indices for selection. +Parameters: + - currentBookings: util::Map&, current bookings + - bookingsSize: int&, number of bookings + - serviceBookingsMap: util::Map&, map of indexed bookings +Returns: + - bool: True if pending services exist, False otherwise +*/ +static bool listServiceBookings(util::Map& currentBookings, int& bookingsSize, util::Map& serviceBookingsMap) +{ + int currentIndex = 1; + bool hasPendingService = false; + std::cout << std::left + << std::setw(10) << "Index" + << std::setw(10) << "ID" + << std::setw(12) << "Status" + << std::setw(12) << "CustID" + << std::setw(20) << "Customer" + << std::setw(15) << "VehicleNo" + << std::setw(15) << "Brand" + << std::setw(15) << "Model" + << std::setw(20) << "Technician" + << std::setw(15) << "TechnicianID" + << std::endl; + for (int iterator = 0; iterator < bookingsSize; iterator++) + { + const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator); + if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING) + { + hasPendingService = true; + const User* currentAssignedTechnician = currentBooking->getAssignedTechnician(); + std::cout << std::left + << std::setw(10) << currentIndex + << std::setw(10) << currentBooking->getId() + << std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus()) + << std::setw(12) << currentBooking->getCustomerId() + << std::setw(20) << currentBooking->getCustomer()->getName() + << std::setw(15) << currentBooking->getVehicleNumber() + << std::setw(15) << currentBooking->getVehicleBrand() + << std::setw(15) << currentBooking->getVehicleModel() + << std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "Null" : currentAssignedTechnician->getName()) + << std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "Null" : currentAssignedTechnician->getId()) + << std::endl; + serviceBookingsMap.insert(currentIndex++, currentBooking); + } + } + if (!hasPendingService) + { + std::cout << "No pending service available." << std::endl; + return false; + } + return true; +} + +/* +Function: selectPendingServiceBookings (static helper) +Description: Allows selection of a pending service booking by index. +Parameters: + - serviceBookingsMap: util::Map&, map of indexed bookings +Returns: + - const ServiceBooking*: Pointer to the selected booking, or nullptr if invalid +*/ +static const ServiceBooking* selectPendingServiceBookings(util::Map& serviceBookingsMap) +{ + int userInputIndex; + std::cout << "Enter a valid service index: "; + util::read(userInputIndex); + if (serviceBookingsMap.find(userInputIndex) != -1) + { + return serviceBookingsMap.getValueAt(userInputIndex); + } + else + { + std::cout << "Enter a valid index."; + return nullptr; + } +} + +/* +Function: listAvailableTechnicians (static helper) +Description: Lists all available technicians and maps them to indices for selection. +Parameters: + - currentAvailableTechnicians: util::Map, available technicians + - numberOfTechnicians: int, number of technicians + - currentAvailableTechniciansMap: util::Map&, map of indexed technicians +Returns: + - void +*/ +static void listAvailableTechnicians(util::Map currentAvailableTechnicians, int numberOfTechnicians, util::Map& currentAvailableTechniciansMap) +{ + bool hasTechnicians = false; + int currentIndex = 1; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(15) << "Technician ID" + << std::setw(20) << "Name" + << std::endl; + for (int iterator = 0; iterator < numberOfTechnicians; iterator++) + { + const User* currentTechnician = currentAvailableTechnicians.getValueAt(iterator); + if (currentTechnician->getState() == util::State::INACTIVE) + { + continue; + } + hasTechnicians = true; + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(15) << currentTechnician->getId() + << std::setw(20) << currentTechnician->getName() + << std::endl; + currentAvailableTechniciansMap.insert(currentIndex++, currentTechnician); + } + if (!hasTechnicians) + { + std::cout << "No technicians currently available."; + } +} + +/* +Function: selectTechnician (static helper) +Description: Allows selection of a technician by index. +Parameters: + - currentAvailableTechniciansMap: util::Map&, map of indexed technicians +Returns: + - const User*: Pointer to the selected technician, or nullptr if invalid +*/ +static const User* selectTechnician(util::Map& currentAvailableTechniciansMap) +{ + int userInputIndex; + util::read(userInputIndex); + if (currentAvailableTechniciansMap.find(userInputIndex) != -1) + { + return currentAvailableTechniciansMap.getValueAt(userInputIndex); + } + else + { + std::cout << "Enter a valid index."; + return nullptr; + } +} + +/* +Function: selectInvoiceFromUserForPayment (static helper) +Description: Lists all pending invoices for the customer and allows selection by index. +Parameters: + - currentInvoices: util::Map&, map of customer invoices +Returns: + - std::string: ID of the selected invoice, or empty string if none selected +*/ +static std::string selectInvoiceFromUserForPayment(const util::Map& currentInvoices) +{ + int currentIndex = 1, choice; + util::Map pendingInvoicesForPayment; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "BookingID" + << std::setw(15) << "VehicleBrand" + << std::setw(15) << "VehicleNumber" + << std::setw(12) << "TechID" + << std::setw(20) << "TechnicianName" + << std::setw(10) << "Discount(%)" + << std::setw(12) << "TotalAmount" + << std::setw(20) << "InvoiceDate" + << std::endl; + for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++) + { + const Invoice* currentInvoice = currentInvoices.getValueAt(iterator); + if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING) + { + const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician(); + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentInvoice->getBookingId() + << std::setw(15) << currentInvoice->getBooking()->getVehicleBrand() + << std::setw(15) << currentInvoice->getBooking()->getVehicleNumber() + << std::setw(12) << ((currentTechnician != nullptr && currentTechnician->getId() != "") ? + currentTechnician->getId() : "Null") + << std::setw(20) << ((currentTechnician != nullptr && currentTechnician->getName() != "") ? + currentTechnician->getName() : "Null") + << std::setw(10) << currentInvoice->getDiscountPercentage() + << std::setw(12) << currentInvoice->getTotalAmount() + << std::setw(20) << currentInvoice->getInvoiceDate().toString() + << std::endl; + pendingInvoicesForPayment.insert(currentIndex++, currentInvoice); + } + } + if (pendingInvoicesForPayment.getSize() == 0) + { + std::cout << "No pending invoices available for payment.\n"; + return ""; + } + std::cout << "Select the Invoice to pay (Index): "; + util::read(choice); + int selectedIndex = pendingInvoicesForPayment.find(choice); + if (selectedIndex != -1) + { + const Invoice* selectedInvoice = pendingInvoicesForPayment.getValueAt(selectedIndex); + return selectedInvoice->getId(); + } + else + { + std::cout << "Invalid choice.\n"; + return ""; + } +} + +/* +Function: selectPaymentMode (static helper) +Description: Allows the customer to select a payment mode (ONLINE or OFFLINE). +Parameters: + - None +Returns: + - util::PaymentMode: Selected payment mode +*/ +static util::PaymentMode selectPaymentMode() +{ + int choice; + std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: "; + util::read(choice); + if (choice == 1) + { + std::cout << "Offline mode selected.\n"; + return util::PaymentMode::OFFLINE; + } + else if (choice == 2) + { + std::cout << "Online mode selected.\n"; + return util::PaymentMode::ONLINE; + } + else + { + std::cout << "Invalid choice, Offline mode selected.\n"; + return util::PaymentMode::OFFLINE; + } +} + +/* +Function: displayInvoices (static helper) +Description: Displays detailed information for all invoices associated with the customer, + including booking details, technician, discount, total amount, payment status, and items used. +Parameters: + - currentUserInvoices: util::Map, customer’s invoices +Returns: + - void +Throws: + - std::runtime_error if a null invoice is encountered +*/ +static void displayInvoices(util::Map currentUserInvoices) +{ + if (currentUserInvoices.getSize() == 0) + { + std::cout << "No invoices found for this account." << std::endl; + util::pressEnter(); + return; + } + else + { + for (int index = 0; index < currentUserInvoices.getSize(); index++) + { + const Invoice* currentInvoice = currentUserInvoices.getValueAt(index); + if (currentInvoice) + { + const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician(); + std::cout << "\nInvoice Details\n"; + std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl; + std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl; + std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl; + std::cout << "Technician ID: " << + ((currentTechnician != nullptr && currentTechnician->getId() != "") ? + currentTechnician->getId() : "Null") << std::endl; + std::cout << "Technician Name: " << + ((currentTechnician != nullptr && currentTechnician->getName() != "") ? + currentTechnician->getName() : "Null") << std::endl; + std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl; + std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl; + std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl; + std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl; + auto inventoryItemsInInvoice = currentInvoice->getParts(); + std::cout << "\nItems Used:\n"; + std::cout << std::left + << std::setw(20) << "ItemName" + << std::setw(10) << "Quantity" + << std::setw(10) << "Price" + << std::endl; + std::cout << std::string(40, '-') << std::endl; + for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++) + { + InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator); + std::cout << std::left + << std::setw(20) << currentItem->getPartName() + << std::setw(10) << currentItem->getQuantity() + << std::setw(10) << currentItem->getPrice() + << std::endl; + } + } + else + { + throw std::runtime_error("Null invoice encountered while displaying invoices."); + util::pressEnter(); + } + } + } +} + +/* +Function: selectJobCardToComplete (static helper) +Description: Lists all incomplete job cards assigned to the technician and allows selection by index. +Parameters: + - assignedJobCards: util::Map&, job cards assigned to the technician + - incompleteJobCards: util::Map&, map of incomplete job cards indexed for selection +Returns: + - std::string: ID of the selected job card, or empty string if none selected +*/ +static std::string selectJobCardToComplete(util::Map& assignedJobCards, util::Map& incompleteJobCards) +{ + int currentIndex = 1; + int choice; + bool hasIncompleteJobCard = false; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "BookingID" + << std::setw(12) << "JobID" + << std::setw(20) << "ServiceName" + << std::setw(12) << "ServiceID" + << std::endl; + for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++) + { + const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator); + if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED)) + { + std::cout << std::left << std::setw(6) << currentIndex + << std::setw(12) << currentJobCard->getBookingId() + << std::setw(12) << currentJobCard->getId() + << std::setw(20) << currentJobCard->getService()->getName() + << std::setw(12) << currentJobCard->getServiceId() + << std::endl; + hasIncompleteJobCard = true; + incompleteJobCards.insert(currentIndex++, currentJobCard); + } + } + if (!hasIncompleteJobCard) + { + std::cout << "No pending jobs are present.\n"; + return ""; + } + std::cout << "Select the Job Card to complete (Index): "; + util::read(choice); + int selectedJobCardIndex = incompleteJobCards.find(choice); + if (selectedJobCardIndex != -1) + { + const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex); + return selectedJobCard->getId(); + } + else + { + std::cout << "Invalid choice.\n"; + return ""; + } +} \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp index 041877e..1779ff5 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.cpp @@ -1,6 +1,7 @@ #include #include "TechnicianMenu.h" #include "InputHelper.h" +#include "MenuHelper.h" #include "OutputHelper.h" #include "JobCard.h" #include "Enums.h" @@ -35,62 +36,6 @@ bool TechnicianMenu::handleOperation(int choice) return false; } -/* -Function: selectJobCardToComplete (static helper) -Description: Lists all incomplete job cards assigned to the technician and allows selection by index. -Parameters: - - assignedJobCards: util::Map&, job cards assigned to the technician - - incompleteJobCards: util::Map&, map of incomplete job cards indexed for selection -Returns: - - std::string: ID of the selected job card, or empty string if none selected -*/ -static std::string selectJobCardToComplete(util::Map& assignedJobCards, util::Map& incompleteJobCards) -{ - int currentIndex = 1; - int choice; - bool hasIncompleteJobCard = false; - std::cout << std::left - << std::setw(6) << "Index" - << std::setw(12) << "BookingID" - << std::setw(12) << "JobID" - << std::setw(20) << "ServiceName" - << std::setw(12) << "ServiceID" - << std::endl; - for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++) - { - const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator); - if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED)) - { - std::cout << std::left << std::setw(6) << currentIndex - << std::setw(12) << currentJobCard->getBookingId() - << std::setw(12) << currentJobCard->getId() - << std::setw(20) << currentJobCard->getService()->getName() - << std::setw(12) << currentJobCard->getServiceId() - << std::endl; - hasIncompleteJobCard = true; - incompleteJobCards.insert(currentIndex++, currentJobCard); - } - } - if (!hasIncompleteJobCard) - { - std::cout << "No pending jobs are present.\n"; - return ""; - } - std::cout << "Select the Job Card to complete (Index): "; - util::read(choice); - int selectedJobCardIndex = incompleteJobCards.find(choice); - if (selectedJobCardIndex != -1) - { - const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex); - return selectedJobCard->getId(); - } - else - { - std::cout << "Invalid choice.\n"; - return ""; - } -} - /* Function: completeJob Description: Allows the technician to mark a selected job card as completed. @@ -115,8 +60,9 @@ void TechnicianMenu::completeJob() m_controller.completeJob(selectedJobID); std::cout << "Job marked as completed.\n"; } + util::pressEnter(); } void TechnicianMenu::viewNotifications() { -} +} \ No newline at end of file