From 1e8fd2829fd8019105fa61d667acf1021055b8e2 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Mon, 25 May 2026 15:46:11 +0530 Subject: [PATCH] Fix PR review comments and refactor menu helper logic Changes: - Added name parameter to createTechnician for consistency - Added function headers for notification-related methods in InventoryManagementService - Used variables for notification title and message instead of passing strings directly - Fixed payment reminder notification message formatting - Moved common helper functions to MenuHelper.h - Updated CustomerMenu to use shared helper functions instead of duplicate code - Added missing includes in MenuHelper.h - Removed redundant helper code from CustomerMenu.cpp - Minor formatting and comment cleanup --- .../controllers/Controller.cpp | 3 +- .../controllers/Controller.h | 2 +- .../services/InventoryManagementService.cpp | 56 +++++- .../services/PaymentManagementService.cpp | 7 +- .../services/ServiceManagementService.cpp | 12 +- .../views/CustomerMenu.cpp | 145 +-------------- .../views/CustomerMenu.h | 1 + .../views/MenuHelper.h | 173 ++++++++++++++++++ .../views/UserInterface.cpp | 1 + 9 files changed, 240 insertions(+), 160 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index b0c4802..b0a1c25 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -55,6 +55,7 @@ Parameter: const std::string& username - customer const std::string& phone - customer’s phone number Return type: void */ + void Controller::createCustomer(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone) { m_userManagementService.createUser(username, name, password, email, phone, util::UserType::CUSTOMER); @@ -71,7 +72,7 @@ const User* Controller::getAuthenticatedUser() return m_authenticationManagementService.getAuthenticatedUser(); } -void Controller::createTechnician(const std::string& username, const std::string& password, const std::string& email, const std::string& phone) +void Controller::createTechnician(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone) { } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index 1b534ea..1cb9603 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -43,7 +43,7 @@ public: void changePassword(const std::string& newPassword); void createCustomer(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone); const User* getAuthenticatedUser(); - void createTechnician(const std::string& username, const std::string& password, const std::string& email, const std::string& phone); + void createTechnician(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone); void updateUserDetails(const std::string& email, const std::string& phone); util::Map getServices(); util::Map getComboPackages(); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp index 6f675eb..dd702bc 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp @@ -22,6 +22,14 @@ Date: 22-May-2026 util::Map InventoryManagementService::m_observers{}; +/* +Function: attach +Description: Adds a user to the observer list for receiving inventory notifications. +Parameters: + - user: User*, pointer to the user to be attached as an observer +Returns: + - None +*/ void InventoryManagementService::attach(User* user) { if (user) @@ -34,6 +42,14 @@ void InventoryManagementService::attach(User* user) } } +/* +Function: detach +Description: Removes a user from the observer list so they no longer receive inventory notifications. +Parameters: + - user: User*, pointer to the user to be detached from the observer list +Returns: + - None +*/ void InventoryManagementService::detach(User* user) { if (user) @@ -46,6 +62,18 @@ void InventoryManagementService::detach(User* user) } } +/* +Function: sendNotification +Description: Sends a notification to a user if they are subscribed as an observer. +Parameters: + - user: User*, pointer to the user receiving the notification + - title: std::string, title of the notification + - message: std::string, body/content of the notification +Returns: + - None +Throws: + - std::runtime_error if notification creation fails +*/ void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message) { if (user) @@ -72,20 +100,39 @@ void InventoryManagementService::sendNotification(User* user, const std::string& } } +/* +Function: sendLowStockAlertsToAdmins (static helper) +Description: Sends low stock alert notifications to all admin users for a given inventory item. +Parameters: + - inventoryManagementService: InventoryManagementService&, service used to send notifications + - inventoryItem: const InventoryItem*, pointer to the low-stock inventory item + - adminUsers: const util::Vector&, list of admin users to notify +Returns: + - None +*/ static void sendLowStockAlertsToAdmins(InventoryManagementService& inventoryManagementService, const InventoryItem* inventoryItem, const util::Vector& adminUsers) { int adminUsersSize = adminUsers.getSize(); for (int index = 0; index < adminUsersSize; index++) { + std::string title = "Low Stock Alert"; + std::string message = "The inventory item with ID " + inventoryItem->getId() + " has very low quantity in the inventory"; inventoryManagementService.sendNotification( adminUsers[index], - "Low Stock Alert", - "The inventory item with ID " + inventoryItem->getId() + - " has very low quantity in the inventory" - ); + title, + message + ); } } +/* +Function: sendLowStockAlerts +Description: Sends alerts to user for inventory items with low stock +Parameters: + - None +Returns: + - None +*/ void InventoryManagementService::sendLowStockAlerts() { auto& inventoryItems = m_dataStore.getInventoryItems(); @@ -116,7 +163,6 @@ void InventoryManagementService::sendLowStockAlerts() } } - /* Function: getObserverIDs Description: Retrieves the IDs of all observers currently attached to the diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index b7946bf..7cdd80a 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -19,7 +19,6 @@ Date: 20-May-2026 #include "User.h" #include "Utility.h" - util::Map PaymentManagementService::m_observers{}; /* @@ -128,9 +127,9 @@ void PaymentManagementService::sendPaymentReminders() User* customer = serviceBooking->getCustomer(); if (customer) { - sendNotification(customer, - "Payment Reminder", - "Your payment for Invoice ID " + invoice->getId() + " is still pending.Please complete the payment." + invoice->getId()); + std::string title = "Payment Reminder"; + std::string message = "Your payment for Invoice ID " + invoice->getId() + " is still pending. Please complete the payment."; + sendNotification(customer, title, message); } } } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index e958839..54210e8 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -60,9 +60,9 @@ void ServiceManagementService::purchaseService(const util::Vector& throw std::runtime_error("Failed to create service booking"); } serviceBookingMap[serviceBooking->getId()] = serviceBooking; - sendNotification(authenticatedUser, - "Service Booking succeeded", - "Your service booking has been successfully placed with ID " + serviceBooking->getId()); + std::string title = "Service Booking succeeded"; + std::string message = "Your service booking has been successfully placed with ID " + serviceBooking->getId(); + sendNotification(authenticatedUser, title, message); } /* @@ -99,9 +99,9 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack throw std::runtime_error("Failed to create combo package service booking"); } serviceBookingMap[serviceBooking->getId()] = serviceBooking; - sendNotification(authenticatedUser, - "Combo Package Service Booking succeeded", - "Your service booking for the combo package has been successfully placed with ID " + serviceBooking->getId()); + std::string title = "Combo Package Service Booking succeeded"; + std::string message = "Your service booking for the combo package has been successfully placed with ID " + serviceBooking->getId(); + sendNotification(authenticatedUser, title, message); } util::Map ServiceManagementService::m_observers{}; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 213fb0d..dbbf27c 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -15,7 +15,6 @@ Date:19-May-2026 #include "MenuHelper.h" #include "OutputHelper.h" #include "Service.h" -#include "Utility.h" #include "Validator.h" #include "Vector.h" @@ -25,6 +24,7 @@ Description: Displays the customer menu and handles user input until logout is s Parameter: None Return type: void */ + void CustomerMenu::showMenu() { while (true) @@ -125,19 +125,7 @@ Return type: void */ void CustomerMenu::changePassword() { - std::string newPassword; - util::clear(); - std::cout << "Enter new password: "; - util::read(newPassword); - m_controller.changePassword(newPassword); - if (!util::isPasswordValid(newPassword)) - { - std::cout << "Error: Password is not strong enough!"; - util::pressEnter(); - return; - } - std::cout << "Password changed successfully"; - util::pressEnter(); + changePasswordHelper(m_controller); } /* @@ -171,55 +159,6 @@ void CustomerMenu::updateDetails() util::pressEnter(); } -/* -Function: selectServiceFromServices -Description: Displays active services and allows the customer to select one by index. -Parameter: const util::Map& services - list of services -Return type: const Service* - selected service -*/ -static const Service* selectServiceFromServices(const util::Map& services) -{ - util::Map activeServicesMap; - int currentIndex = 1; - int userInputIndex; - std::cout << std::left - << std::setw(10) << "Index" - << std::setw(15) << "Service ID" - << std::setw(25) << "Service Name" - << std::setw(15) << "Estimated Cost" - << std::endl; - for (int index = 0; index < services.getSize(); index++) - { - const Service* currentService = services.getValueAt(index); - if (currentService->getState() != util::State::ACTIVE) - { - continue; - } - activeServicesMap.insert(currentIndex, currentService); - double partsCost = util::calculatePartsCost(currentService); - std::cout << std::left - << std::setw(10) << currentIndex - << std::setw(15) << currentService->getId() - << std::setw(25) << currentService->getName() - << std::setw(15) << (currentService->getLaborCost() + partsCost) - << std::endl; - currentIndex++; - } - if (activeServicesMap.getSize() == 0) - { - std::cout << "No active services available." << std::endl; - return nullptr; - } - std::cout << "Enter service index: "; - util::read(userInputIndex); - if (activeServicesMap.find(userInputIndex) == -1) - { - std::cout << "Invalid service index." << std::endl; - return nullptr; - } - return activeServicesMap[userInputIndex]; -} - /* Function: selectService Description: Allows the customer to select a service, provide vehicle details, @@ -253,54 +192,6 @@ void CustomerMenu::selectService() util::pressEnter(); } -/* -Function: selectComboPackageFromPackages -Description: Displays active combo packages and allows the customer to select one by index. -Parameter: const util::Map& comboPackages - list of combo packages -Return type: const ComboPackage* - selected combo package -*/ -static const ComboPackage* selectComboPackageFromPackages(const util::Map& comboPackages) -{ - util::Map activeComboPackages; - int currentIndex = 1; - int userInputIndex; - std::cout << std::left - << std::setw(10) << "Index" - << std::setw(15) << "Combo Package ID" - << std::setw(15) << "Combo Package Name" - << std::setw(15) << "Estimate Cost" - << std::endl; - for (int index = 0; index < comboPackages.getSize(); index++) - { - const ComboPackage* currentComboPackage = comboPackages.getValueAt(index); - if (currentComboPackage->getState() != util::State::ACTIVE) - { - continue; - } - activeComboPackages.insert(currentIndex, currentComboPackage); - std::cout << std::left - << std::setw(10) << currentIndex - << std::setw(15) << currentComboPackage->getId() - << std::setw(25) << currentComboPackage->getPackageName() - << std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage) - << std::endl; - currentIndex++; - } - if (activeComboPackages.getSize() == 0) - { - std::cout << "No active combo packages available." << std::endl; - return nullptr; - } - std::cout << "Enter combo package index: "; - util::read(userInputIndex); - if (activeComboPackages.find(userInputIndex) == -1) - { - std::cout << "Invalid combo package index." << std::endl; - return nullptr; - } - return activeComboPackages[userInputIndex]; -} - /* Function: selectComboPackage Description: Allows the customer to select a combo package, provide vehicle details, @@ -357,38 +248,6 @@ void CustomerMenu::viewNotifications() viewAndDeleteNotification(m_controller); } -/* -Function: getNotificationPreference (static helper) -Description: Helper function to configure notification preferences for a specific service. -Parameters: - - serviceName: Name of the service for which notifications are being configured. -Returns: - - bool: True if notifications are enabled, False if disabled. -*/ -static bool getNotificationPreference(const std::string& serviceName) -{ - int choice; - while (true) - { - util::clear(); - std::cout << " Configure Notification Preferences\n"; - std::cout << "\n" << serviceName << " Notifications\n"; - std::cout << "1. Enable Notifications\n"; - std::cout << "2. Disable Notifications\n"; - std::cout << "Enter your choice: "; - util::read(choice); - if (choice == 1) - { - return true; - } - if (choice == 2) - { - return false; - } - std::cout << "\nInvalid choice. Please enter 1 or 2.\n"; - util::pressEnter(); - } -} /* Function: configureNotifications diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.h index 3dbb439..d491720 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.h @@ -7,6 +7,7 @@ Description: Header file declaring the CustomerMenu class, which provides Author: Trenser Date:19-May-2026 */ + #pragma once #include "Controller.h" diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h index 3dfbeba..0bb708b 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h @@ -16,6 +16,10 @@ Date: 21-May-2026 #include "Notification.h" #include "OutputHelper.h" #include "Vector.h" +#include "Validator.h" +#include "Service.h" +#include "ComboPackage.h" +#include "Utility.h" /* Function: selectNotification @@ -112,3 +116,172 @@ inline void viewAndDeleteNotification(Controller& controller) controller.deleteNotification(selectedNotification->getId()); util::pressEnter(); } + +/* +Function: changePassword +Description: Helper function to change password +Parameter: controller: Reference to the Controller object used to manage notifications. +Return type: void +*/ +inline void changePasswordHelper(Controller& controller) +{ + std::string newPassword; + while (true) + { + util::clear(); + std::cout << "Enter new password: "; + util::read(newPassword); + if (!util::isPasswordValid(newPassword)) + { + std::cout << "Error: Password is not strong enough!\n"; + util::pressEnter(); + continue; + } + controller.changePassword(newPassword); + std::cout << "Password changed successfully\n"; + util::pressEnter(); + break; + } +} + +/* +Function: selectServiceFromServices +Description: Displays active services and allows the customer to select one by index. +Parameter: const util::Map& services - list of services +Return type: const Service* - selected service +*/ +inline const Service* selectServiceFromServices(const util::Map& services) +{ + util::Map activeServicesMap; + int currentIndex = 1; + int userInputIndex; + std::cout << std::left + << std::setw(10) << "Index" + << std::setw(15) << "Service ID" + << std::setw(25) << "Service Name" + << std::setw(15) << "Estimated Cost" + << std::endl; + for (int index = 0; index < services.getSize(); index++) + { + const Service* currentService = services.getValueAt(index); + if (currentService->getState() != util::State::ACTIVE) + { + continue; + } + activeServicesMap.insert(currentIndex, currentService); + double partsCost = util::calculatePartsCost(currentService); + std::cout << std::left + << std::setw(10) << currentIndex + << std::setw(15) << currentService->getId() + << std::setw(25) << currentService->getName() + << std::setw(15) << (currentService->getLaborCost() + partsCost) + << std::endl; + currentIndex++; + } + if (activeServicesMap.getSize() == 0) + { + std::cout << "No active services available." << std::endl; + return nullptr; + } + std::cout << "Enter service index: "; + util::read(userInputIndex); + if (activeServicesMap.find(userInputIndex) == -1) + { + std::cout << "Invalid service index." << std::endl; + return nullptr; + } + return activeServicesMap[userInputIndex]; +} + +/* +Function: selectComboPackageFromPackages +Description: Displays active combo packages and allows the customer to select one by index. +Parameter: const util::Map& comboPackages - list of combo packages +Return type: const ComboPackage* - selected combo package +*/ +inline const ComboPackage* selectComboPackageFromPackages(const util::Map& comboPackages) +{ + util::Map activeComboPackages; + int currentIndex = 1; + int userInputIndex; + std::cout << std::left + << std::setw(10) << "Index" + << std::setw(15) << "Combo Package ID" + << std::setw(15) << "Combo Package Name" + << std::setw(15) << "Estimate Cost" + << std::endl; + for (int index = 0; index < comboPackages.getSize(); index++) + { + const ComboPackage* currentComboPackage = comboPackages.getValueAt(index); + if (currentComboPackage->getState() != util::State::ACTIVE) + { + continue; + } + activeComboPackages.insert(currentIndex, currentComboPackage); + std::cout << std::left + << std::setw(10) << currentIndex + << std::setw(15) << currentComboPackage->getId() + << std::setw(25) << currentComboPackage->getPackageName() + << std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage) + << std::endl; + currentIndex++; + } + if (activeComboPackages.getSize() == 0) + { + std::cout << "No active combo packages available." << std::endl; + return nullptr; + } + std::cout << "Enter combo package index: "; + util::read(userInputIndex); + if (activeComboPackages.find(userInputIndex) == -1) + { + std::cout << "Invalid combo package index." << std::endl; + return nullptr; + } + return activeComboPackages[userInputIndex]; +} + +/* +Function: sendLowStockAlertsToAdmins (static helper) +Description: Sends low stock alert notifications to all admin users for a given inventory item. +Parameters: + - inventoryManagementService: InventoryManagementService&, service used to send notifications + - inventoryItem: const InventoryItem*, pointer to the low-stock inventory item + - adminUsers: const util::Vector&, list of admin users to notify +Returns: + - None +*/ + +/* +Function: getNotificationPreference (static helper) +Description: Helper function to configure notification preferences for a specific service. +Parameters: + - serviceName: Name of the service for which notifications are being configured. +Returns: + - bool: True if notifications are enabled, False if disabled. +*/ +inline bool getNotificationPreference(const std::string& serviceName) +{ + int choice; + while (true) + { + util::clear(); + std::cout << " Configure Notification Preferences\n"; + std::cout << "\n" << serviceName << " Notifications\n"; + std::cout << "1. Enable Notifications\n"; + std::cout << "2. Disable Notifications\n"; + std::cout << "Enter your choice: "; + util::read(choice); + if (choice == 1) + { + return true; + } + if (choice == 2) + { + return false; + } + std::cout << "\nInvalid choice. Please enter 1 or 2.\n"; + util::pressEnter(); + } +} + diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp index 4f91641..04f240f 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp @@ -5,6 +5,7 @@ Description: Implementation file containing the method definitions of the and customer registration logic. Author: Trenser Date:19-May-2026 + */ #include "UserInterface.h" #include "InputHelper.h"