From c67bf962c124bc0d90ea83e0607d9d828b109eae Mon Sep 17 00:00:00 2001 From: Jissin Mathew Date: Wed, 27 May 2026 16:38:18 +0530 Subject: [PATCH] Fix Customer Menu View Invoices UI and Navigation Issues - Added tabular invoice list for better navigation - Enabled user to select an invoice before viewing full details - Displayed Payment Mode in detailed invoice view - Removed duplicate pressEnter() calls - Improved console messages and formatting for clarity Fixes #1784 --- .../views/MenuHelper.h | 168 ++++++++++++++---- 1 file changed, 137 insertions(+), 31 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h index d89d34e..f91e33b 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h @@ -201,8 +201,6 @@ inline bool listServiceBookings(util::Map& c << 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++) { @@ -219,8 +217,6 @@ inline bool listServiceBookings(util::Map& c << 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); } @@ -239,7 +235,7 @@ Returns: inline const ServiceBooking* selectPendingServiceBookings(util::Map& serviceBookingsMap) { int userInputIndex; - std::cout << "\nEnter a valid service index: "; + std::cout << "\nEnter a service index: "; util::read(userInputIndex); if (serviceBookingsMap.find(userInputIndex) != -1) { @@ -304,7 +300,7 @@ Returns: inline const User* selectTechnician(util::Map& currentAvailableTechniciansMap) { int userInputIndex; - std::cout << "\nEnter valid technician index: "; + std::cout << "\nEnter technician index: "; util::read(userInputIndex); if (currentAvailableTechniciansMap.find(userInputIndex) != -1) { @@ -416,6 +412,73 @@ inline util::PaymentMode selectPaymentMode() } } +/* +Function: displayInvoicesInTabularForm +Description: + Displays all invoices in a tabular format. Each row shows booking details, + vehicle info, technician details, discount, total amount, invoice date, + and payment status. If inventory items exist for an invoice, they are + displayed in a separate table below the invoice row. +Parameters: + - currentInvoices: util::Map + Map of invoice IDs to Invoice pointers. +Returns: + - void +*/ +inline const Invoice* selectInvoiceToDisplay(util::Map& currentInvoices) +{ + int currentIndex = 1, choice; + util::Map currentInvoicesIndexMap; + if (currentInvoices.isEmpty()) + { + std::cout << "No invoices available.\n\n"; + return nullptr; + } + std::cout + << std::left + << std::setw(10) << "Index" + << std::setw(12) << "BookingID" + << std::setw(15) << "VehicleNumber" + << std::setw(20) << "TechnicianName" + << std::setw(15) << "TotalAmount" + << std::setw(25) << "InvoiceDate" + << std::setw(15) << "PaymentStatus" + << std::setw(15) << "PaymentMode" + << std::endl; + for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++) + { + const Invoice* currentInvoice = currentInvoices.getValueAt(iterator); + if (!currentInvoice) + { + continue; + } + const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician(); + std::cout << std::left + << std::setw(10) << currentIndex + << std::setw(12) << currentInvoice->getBookingId() + << std::setw(15) << currentInvoice->getBooking()->getVehicleNumber() + << std::setw(20) << ((currentTechnician && !currentTechnician->getName().empty()) ? currentTechnician->getName() : "NULL") + << std::setw(15) << currentInvoice->getTotalAmount() + << std::setw(25) << currentInvoice->getInvoiceDate().toString() + << std::setw(15) << util::getPaymentStatusString(currentInvoice->getStatus()) + << std::setw(15) << util::getPaymentModeString(currentInvoice->getPaymentMethod()) + << std::endl; + currentInvoicesIndexMap.insert(currentIndex++, currentInvoice); + } + std::cout << "Enter an index: "; + util::read(choice); + int currentSelectedIndex = currentInvoicesIndexMap.find(choice); + if (currentSelectedIndex != -1) + { + return currentInvoicesIndexMap.getValueAt(currentSelectedIndex); + } + else + { + std::cout << "Enter a valid index.\n"; + return nullptr; + } +} + /* Function: displayInvoices Description: Displays detailed information for all invoices associated with the customer, @@ -429,34 +492,48 @@ Throws: */ inline void displayInvoices(util::Map currentUserInvoices) { + std::cout << std::endl; if (currentUserInvoices.getSize() == 0) { - std::cout << "No invoices found for this account." << std::endl << std::endl; + std::cout << "No invoices found for this account.\n\n"; return; } else { - for (int index = 0; index < currentUserInvoices.getSize(); index++) + bool doRun = true; + do { - const Invoice* currentInvoice = currentUserInvoices.getValueAt(index); - if (currentInvoice) + const Invoice* selectedInvoice; + int choice; + selectedInvoice = selectInvoiceToDisplay(currentUserInvoices); + if (selectedInvoice) { - 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(); + const User* currentTechnician = selectedInvoice->getBooking()->getAssignedTechnician(); + util::clear(); + std::cout << "Invoice Details\n"; + std::cout << std::left << std::setw(20) << "Booking ID:" + << selectedInvoice->getBookingId() << std::endl; + std::cout << std::left << std::setw(20) << "Vehicle Brand:" + << selectedInvoice->getBooking()->getVehicleBrand() << std::endl; + std::cout << std::left << std::setw(20) << "Vehicle Number:" + << selectedInvoice->getBooking()->getVehicleNumber() << std::endl; + std::cout << std::left << std::setw(20) << "Technician ID:" + << ((currentTechnician != nullptr && !currentTechnician->getId().empty()) + ? currentTechnician->getId() : "NULL") << std::endl; + std::cout << std::left << std::setw(20) << "Technician Name:" + << ((currentTechnician != nullptr && !currentTechnician->getName().empty()) + ? currentTechnician->getName() : "NULL") << std::endl; + std::cout << std::left << std::setw(20) << "Discount(%):" + << selectedInvoice->getDiscountPercentage() << std::endl; + std::cout << std::left << std::setw(20) << "Total Amount:" + << selectedInvoice->getTotalAmount() << std::endl; + std::cout << std::left << std::setw(20) << "Invoice Date:" + << selectedInvoice->getInvoiceDate().toString() << std::endl; + std::cout << std::left << std::setw(20) << "Payment Status:" + << util::getPaymentStatusString(selectedInvoice->getStatus()) << std::endl; + std::cout << std::left << std::setw(20) << "Payment Mode:" + << util::getPaymentModeString(selectedInvoice->getPaymentMethod()) << std::endl; + auto inventoryItemsInInvoice = selectedInvoice->getParts(); if (inventoryItemsInInvoice.isEmpty()) { std::cout << "No inventory items used.\n\n"; @@ -478,14 +555,31 @@ inline void displayInvoices(util::Map currentUserIn << std::setw(10) << currentItem->getPrice() << std::endl; } + std::cout << "\n\nDo you want to display another Invoice (1-Yes, 2-No): "; + util::read(choice); + if (choice == 1) + { + doRun = true; + util::clear(); + } + else if (choice == 2) + { + doRun = false; + } + else + { + std::cout << "Invalid choice\n"; + doRun = false; + } } else { - throw std::runtime_error("Null invoice encountered while displaying invoices."); + std::cout << "Unable to fetch the selected invoice\n"; + doRun = false; } - } + + } while (doRun); } - util::pressEnter(); } /* @@ -803,6 +897,7 @@ inline const Service* selectServiceFromServices(const util::Map activeServicesMap; int currentIndex = 1; int userInputIndex; @@ -849,6 +944,17 @@ inline const Service* selectServiceFromServices(const util::Map& + Map of combo package IDs to ComboPackage pointers. +Returns: + - util::Map + Map containing only active combo packages. +*/ inline util::Map filterComboPackages(util::Map& comboPackages) { util::Map activeComboPackages; @@ -878,7 +984,7 @@ inline const ComboPackage* selectComboPackageFromPackages(const util::MapgetId() - << std::setw(25) << util::truncateString(currentComboPackage->getPackageName(), 20) + << std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30) << std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage) << std::endl; currentIndex++;