7646ce6644
- Assign Job to Technician: - Added heading for clearer user guidance. - Filtered only pending service bookings for assignment. - Improved technician listing and selection with clearer prompts. - Ensured booking status transitions correctly from PENDING to STARTED when job cards are created. - Enhanced feedback messages for technician availability and job card creation. - View Invoices: - Added heading "View Invoices" for better UI consistency. - Updated displayInvoices to take map by reference for efficiency. - Improved formatting of invoice details with consistent spacing and line breaks. - Added handling for empty invoice parts list (shows "No inventory items used"). - Enhanced error messages when encountering null invoices. Fixes #1745 Fixes #1752
397 lines
11 KiB
C++
397 lines
11 KiB
C++
/*
|
||
File: CustomerMenu.cpp
|
||
Description: Implementation file containing the method definitions of the
|
||
CustomerMenu class, including menu handling, service selection,
|
||
combo package booking, profile updates, and password management.
|
||
Author: Trenser
|
||
Date:19-May-2026
|
||
*/
|
||
|
||
#include <iomanip>
|
||
#include "ComboPackage.h"
|
||
#include "CustomerMenu.h"
|
||
#include "MenuHelper.h"
|
||
#include "Enums.h"
|
||
#include "InputHelper.h"
|
||
#include "OutputHelper.h"
|
||
#include "InventoryItem.h"
|
||
#include "Invoice.h"
|
||
#include "Map.h"
|
||
#include "Service.h"
|
||
#include "ServiceBooking.h"
|
||
#include "Timestamp.h"
|
||
#include "User.h"
|
||
#include "Validator.h"
|
||
#include "Vector.h"
|
||
|
||
/*
|
||
Function: showMenu
|
||
Description: Displays the customer menu and handles user input until logout is selected.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
|
||
void CustomerMenu::showMenu()
|
||
{
|
||
while (true)
|
||
{
|
||
try
|
||
{
|
||
int choice;
|
||
util::clear();
|
||
std::cout << "Customer Menu"
|
||
<< "\n1. Select a service"
|
||
<< "\n2. Select a combo package"
|
||
<< "\n3. Update Profile"
|
||
<< "\n4. Change Password"
|
||
<< "\n5. View Service History"
|
||
<< "\n6. Complete Payments"
|
||
<< "\n7. View Invoices"
|
||
<< "\n8. View Notifications"
|
||
<< "\n9. Configure Notifications"
|
||
<< "\n10. Logout"
|
||
<< "\nEnter a choice: ";
|
||
util::read(choice);
|
||
if (!handleOperation(choice))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
catch (const std::exception& e)
|
||
{
|
||
std::cout << "Exception: " << e.what() << std::endl;
|
||
util::pressEnter();
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
Function: handleOperation
|
||
Description: Executes the corresponding customer operation based on the selected menu choice.
|
||
Parameter: int choice - selected menu option
|
||
Return type: bool - true if menu continues, false if logout
|
||
*/
|
||
bool CustomerMenu::handleOperation(int choice)
|
||
{
|
||
switch (choice)
|
||
{
|
||
case 1:
|
||
selectService();
|
||
break;
|
||
case 2:
|
||
selectComboPackage();
|
||
break;
|
||
case 3:
|
||
updateDetails();
|
||
break;
|
||
case 4:
|
||
changePassword();
|
||
break;
|
||
case 5:
|
||
viewServiceHistory();
|
||
break;
|
||
case 6:
|
||
completePayments();
|
||
break;
|
||
case 7:
|
||
viewInvoices();
|
||
break;
|
||
case 8:
|
||
viewNotifications();
|
||
break;
|
||
case 9:
|
||
configureNotifications();
|
||
break;
|
||
case 10:
|
||
logout();
|
||
return false;
|
||
default:
|
||
std::cout << "Enter a valid choice!" << std::endl;
|
||
util::pressEnter();
|
||
}
|
||
return true;
|
||
}
|
||
|
||
/*
|
||
Function: logout
|
||
Description: Logs out the currently authenticated customer user.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
void CustomerMenu::logout()
|
||
{
|
||
m_controller.logout();
|
||
}
|
||
|
||
/*
|
||
Function: changePassword
|
||
Description: Allows the customer to change their password after validation.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
void CustomerMenu::changePassword()
|
||
{
|
||
changePasswordHelper(m_controller);
|
||
}
|
||
|
||
/*
|
||
Function: updateDetails
|
||
Description: Allows the customer to update their email and phone number after validation.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
void CustomerMenu::updateDetails()
|
||
{
|
||
std::string email, phone;
|
||
util::clear();
|
||
std::cout << "Update Details\n";
|
||
std::cout << "Enter new email: ";
|
||
util::read(email);
|
||
if (!util::isEmailValid(email))
|
||
{
|
||
std::cout << "Error: Email is invalid!\n";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
std::cout << "Enter new phone: ";
|
||
util::read(phone);
|
||
if (!util::isPhoneNumberValid(phone))
|
||
{
|
||
std::cout << "Error: Phone number is invalid!\n";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
m_controller.updateUserDetails(email, phone);
|
||
std::cout << "Profile details updated successfully\n";
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: selectService
|
||
Description: Allows the customer to select a service, provide vehicle details,
|
||
and book the service through the controller.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
void CustomerMenu::selectService()
|
||
{
|
||
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
||
util::clear();
|
||
std::cout << "Select a Service\n";
|
||
auto services = m_controller.getServices();
|
||
if (services.isEmpty())
|
||
{
|
||
std::cout << "No services available!";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
util::Vector<std::string> selectedServices;
|
||
const Service* selectedService = selectServiceFromServices(services);
|
||
if (selectedService == nullptr)
|
||
{
|
||
std::cout << "Failed to book service!";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
selectedServices.push_back(selectedService->getId());
|
||
util::clear();
|
||
std::cout << "Enter Vehicle Details\n";
|
||
std::cout << "Enter vehicle number: ";
|
||
util::read(vehicleNumber);
|
||
std::cout << "Enter vehicle brand: ";
|
||
util::read(vehicleBrand);
|
||
std::cout << "Enter vehicle model: ";
|
||
util::read(vehicleModel);
|
||
m_controller.purchaseService(selectedServices, vehicleNumber, vehicleBrand, vehicleModel);
|
||
std::cout << "Service has been booked successfully";
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: selectComboPackage
|
||
Description: Allows the customer to select a combo package, provide vehicle details,
|
||
and book the package through the controller.
|
||
Parameter: None
|
||
Return type: void
|
||
*/
|
||
void CustomerMenu::selectComboPackage()
|
||
{
|
||
std::string vehicleNumber, vehicleBrand, vehicleModel;
|
||
util::clear();
|
||
std::cout << "Select a Combo Package\n";
|
||
auto comboPackages = m_controller.getComboPackages();
|
||
if (comboPackages.isEmpty())
|
||
{
|
||
std::cout << "No combo packages available!";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(comboPackages);
|
||
if (selectedComboPackage == nullptr)
|
||
{
|
||
std::cout << "Failed to book combo package!";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
util::clear();
|
||
std::cout << "Enter vehicle number: ";
|
||
util::read(vehicleNumber);
|
||
std::cout << "Enter vehicle brand: ";
|
||
util::read(vehicleBrand);
|
||
std::cout << "Enter vehicle model: ";
|
||
util::read(vehicleModel);
|
||
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
|
||
std::cout << "Combo Package has been booked successfully";
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: viewServiceHistory
|
||
Description: Displays the customer’s past service bookings in tabular format,
|
||
including booking ID, technician, vehicle details, discount percentage, and status.
|
||
Parameters:
|
||
- None
|
||
Returns:
|
||
- void
|
||
*/
|
||
void CustomerMenu::viewServiceHistory()
|
||
{
|
||
util::clear();
|
||
bool hasServiceHistory = false;
|
||
const User* currentUser = m_controller.getAuthenticatedUser();
|
||
std::string currentUserID = currentUser->getId();
|
||
util::Map<std::string, const ServiceBooking*> serviceBookingsByCurrentUser = m_controller.getServiceBookingsByUser(currentUserID);
|
||
std::cout << "View Service History" << std::endl;
|
||
if (serviceBookingsByCurrentUser.getSize() != 0)
|
||
{
|
||
std::cout << std::left
|
||
<< std::setw(15) << "Booking ID"
|
||
<< std::setw(20) << "Technician"
|
||
<< std::setw(20) << "Vehicle Brand"
|
||
<< std::setw(20) << "Vehicle Number"
|
||
<< std::setw(20) << "Vehicle Model"
|
||
<< std::setw(20) << "Discount %"
|
||
<< std::setw(20) << "Status"
|
||
<< std::endl;
|
||
for (int iterator = 0; iterator < serviceBookingsByCurrentUser.getSize(); iterator++)
|
||
{
|
||
const ServiceBooking* currentBooking = serviceBookingsByCurrentUser.getValueAt(iterator);
|
||
std::string technicianName = currentBooking->getAssignedTechnician() == nullptr
|
||
? "Not Assigned"
|
||
: currentBooking->getAssignedTechnician()->getName();
|
||
std::cout << std::left
|
||
<< std::setw(15) << currentBooking->getId()
|
||
<< std::setw(20) << technicianName
|
||
<< std::setw(20) << currentBooking->getVehicleBrand()
|
||
<< std::setw(20) << currentBooking->getVehicleNumber()
|
||
<< std::setw(20) << currentBooking->getVehicleModel()
|
||
<< std::setw(20) << currentBooking->getDiscountPercentage()
|
||
<< std::setw(20) << util::getServiceJobStatusString(currentBooking->getStatus())
|
||
<< std::endl;
|
||
hasServiceHistory = true;
|
||
}
|
||
}
|
||
if (!hasServiceHistory)
|
||
{
|
||
std::cout << "No history available." << std::endl;
|
||
}
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: completePayments
|
||
Description: Allows the customer to complete pending payments for invoices.
|
||
Validates invoice selection and payment mode before completing payment.
|
||
Parameters:
|
||
- None
|
||
Returns:
|
||
- void
|
||
*/
|
||
void CustomerMenu::completePayments()
|
||
{
|
||
util::clear();
|
||
std::cout << "Complete Payments\n";
|
||
util::Map<std::string, const Invoice*> currentInvoices = m_controller.getInvoicesByUser();
|
||
if (currentInvoices.isEmpty())
|
||
{
|
||
std::cout << "No pending invoices available for payment.\n";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
bool hasPending = false;
|
||
for (int index = 0; index < currentInvoices.getSize(); ++index)
|
||
{
|
||
const Invoice* invoice = currentInvoices.getValueAt(index);
|
||
if (invoice && invoice->getStatus() == util::PaymentStatus::PENDING)
|
||
{
|
||
hasPending = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!hasPending)
|
||
{
|
||
std::cout << "No pending invoices available for payment.\n";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices);
|
||
if (selectedID == "")
|
||
{
|
||
std::cout << "Payment failed.\n";
|
||
util::pressEnter();
|
||
return;
|
||
}
|
||
util::PaymentMode paymentMode = selectPaymentMode();
|
||
m_controller.completePayment(selectedID, paymentMode);
|
||
std::cout << "Payment completed successfully.\n";
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: viewInvoices
|
||
Description: Displays invoices associated with the customer by calling displayInvoices.
|
||
Parameters:
|
||
- None
|
||
Returns:
|
||
- void
|
||
*/
|
||
void CustomerMenu::viewInvoices()
|
||
{
|
||
util::clear();
|
||
std::cout << "View Invoices\n";
|
||
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
||
displayInvoices(currentUserInvoices);
|
||
util::pressEnter();
|
||
}
|
||
|
||
/*
|
||
Function: viewNotifications
|
||
Description: Displays notifications for the customer and allows deletion of notifications.
|
||
Parameters:
|
||
- None
|
||
Returns:
|
||
- void
|
||
*/
|
||
void CustomerMenu::viewNotifications()
|
||
{
|
||
viewAndDeleteNotification(m_controller);
|
||
}
|
||
|
||
|
||
/*
|
||
Function: configureNotifications
|
||
Description: Allows the customer to configure notification preferences for payment and service management.
|
||
Parameters:
|
||
- None
|
||
Returns:
|
||
- void
|
||
*/
|
||
void CustomerMenu::configureNotifications()
|
||
{
|
||
bool paymentServiceNotifications = getNotificationPreference("Payment Management Service");
|
||
bool serviceManagementNotifications = getNotificationPreference("Service Management Service");
|
||
m_controller.configureNotifications(paymentServiceNotifications, serviceManagementNotifications);
|
||
util::clear();
|
||
std::cout << "Notification preferences updated successfully.\n";
|
||
util::pressEnter();
|
||
} |