From 20475ace73ac2ba051225352e984930af23313ad Mon Sep 17 00:00:00 2001 From: Avinash Rajesh Date: Mon, 1 Jun 2026 17:46:55 +0530 Subject: [PATCH 1/2] Fix Duplicate Customer Notification Sent When Assigned Technician Is Removed - Refactored processBookingCancellation to simplify parameters and remove redundant notification arguments. - Added util::UserType parameter to differentiate cancellation flows for CUSTOMER vs TECHNICIAN. - Updated cancelCustomerServiceBookings to use processBookingCancellation with util::UserType::CUSTOMER. - Updated cancelTechnicianJobs to use processBookingCancellation with util::UserType::TECHNICIAN. - Enhanced booking status handling by including IN_PROGRESS status in cancellation checks. - Ensured job cards are consistently marked CANCELLED and inventory restored. - Fixed duplicate notification issue where customers received multiple alerts when technician was removed. Fixes #1807 --- .../services/ServiceManagementService.cpp | 98 +++++++++---------- 1 file changed, 44 insertions(+), 54 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index f6d3905..e12d9a3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -541,52 +541,55 @@ static void restoreInventory(ServiceBooking* booking) } } -/* -Function: processBookingCancellation -Description: Cancels jobs and updates the status of a given booking. Sends notifications to the - specified user, resets technician assignment if needed, and restores inventory items. -Parameter: ServiceBooking* booking - Pointer to the booking being cancelled - util::ServiceJobStatus newServiceBookingStatus - New status to assign to the booking - const std::string& notificationTitle - Title of the booking cancellation notification - const std::string& notificationMessage - Message body of the booking cancellation notification - User* notifyUser - User to notify about the cancellation - util::ServiceJobStatus jobCardStatus - New status to assign to associated job cards - const std::string& jobNotificationTitle - Title of the job cancellation notification - const std::string& jobNotificationMessage - Message body of the job cancellation notification - util::Map& jobs - Collection of job cards to update - ServiceManagementService& currentService - Reference to the service for sending notifications -Return type: void -*/ static void processBookingCancellation(ServiceBooking* booking, - util::ServiceJobStatus newServiceBookingStatus, - const std::string& notificationTitle, - const std::string& notificationMessage, - User* notifyUser, - util::ServiceJobStatus jobCardStatus, - const std::string& jobNotificationTitle, - const std::string& jobNotificationMessage, - util::Map& jobs, ServiceManagementService& currentService) + util::Map& jobs, + ServiceManagementService& currentService, + util::UserType userType) { - if (!booking || !notifyUser) + if (!booking) { return; } for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator) { JobCard* jobCard = jobs.getValueAt(jobIterator); - if (jobCard && jobCard->getBookingId() == booking->getId()) + if (!jobCard || jobCard->getBookingId() != booking->getId() || jobCard->getStatus() == util::ServiceJobStatus::CANCELLED) { - jobCard->setStatus(jobCardStatus); - currentService.sendNotification(notifyUser, jobNotificationTitle, jobNotificationMessage); + continue; + } + jobCard->setStatus(util::ServiceJobStatus::CANCELLED); + if (userType == util::UserType::CUSTOMER) + { + if (User* technician = booking->getAssignedTechnician()) + { + const std::string jobTitle = "Job Cancelled"; + const std::string jobMessage = "Your job card has been cancelled and the inventory has been restocked."; + currentService.sendNotification(technician, jobTitle, jobMessage); + } } } - booking->setStatus(newServiceBookingStatus); - currentService.sendNotification(notifyUser, notificationTitle, notificationMessage); - if (newServiceBookingStatus == util::ServiceJobStatus::PENDING) + if (userType == util::UserType::CUSTOMER) { - booking->setAssignedTechnician(nullptr); - booking->setAssignedTechnicianId(""); + booking->setStatus(util::ServiceJobStatus::CANCELLED); + if (User* technician = booking->getAssignedTechnician()) + { + const std::string title = "Customer Service Cancelled"; + const std::string message = "Your assigned job card has been cancelled and the inventory has been restocked."; + currentService.sendNotification(technician, title, message); + } } + else if (userType == util::UserType::TECHNICIAN) + { + booking->setStatus(util::ServiceJobStatus::PENDING); + if (User* customer = booking->getCustomer()) + { + const std::string title = "Technician Unavailable"; + const std::string message = "Your booking has been reset to pending and we will reassign a new technician shortly."; + currentService.sendNotification(customer, title, message); + } + } + booking->setAssignedTechnician(nullptr); + booking->setAssignedTechnicianId(""); restoreInventory(booking); } @@ -624,21 +627,13 @@ void ServiceManagementService::cancelCustomerServiceBookings(const std::string& { continue; } - if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED) + if (booking->getStatus() != util::ServiceJobStatus::PENDING && + booking->getStatus() != util::ServiceJobStatus::STARTED && + booking->getStatus() != util::ServiceJobStatus::IN_PROGRESS) { continue; } - User* assignedTechnician = booking->getAssignedTechnician(); - std::string titleToTechnician = "Customer Service Cancelled"; - std::string messageToTechnician = "The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked."; - std::string jobTitle = "Job Cancelled"; - std::string jobMessage = "The job has been cancelled. Your job card has been cancelled and the inventory has been restocked."; - processBookingCancellation(booking, - util::ServiceJobStatus::CANCELLED, - titleToTechnician, messageToTechnician, assignedTechnician, - util::ServiceJobStatus::CANCELLED, - jobTitle, jobMessage, jobs, *this - ); + processBookingCancellation(booking, jobs, *this, util::UserType::CUSTOMER); } } @@ -676,7 +671,9 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia { continue; } - if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED) + if (booking->getStatus() != util::ServiceJobStatus::PENDING && + booking->getStatus() != util::ServiceJobStatus::STARTED && + booking->getStatus() != util::ServiceJobStatus::IN_PROGRESS) { continue; } @@ -685,14 +682,7 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia { continue; } - std::string title = "Technician Unavailable"; - std::string message = "Your assigned technician is no longer available. Your booking has been reset to pending and we will reassign a new technician shortly."; - processBookingCancellation(booking, - util::ServiceJobStatus::PENDING, - title, message, customer, - util::ServiceJobStatus::CANCELLED, - title, message, jobs, *this - ); + processBookingCancellation(booking, jobs, *this, util::UserType::TECHNICIAN); } } From c64f3cff72afc47b5fc0486e98888eb619d85d6f Mon Sep 17 00:00:00 2001 From: Avinash Rajesh Date: Mon, 1 Jun 2026 18:13:11 +0530 Subject: [PATCH 2/2] Implemented Review Fixes --- .../services/ServiceManagementService.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index e12d9a3..1a9f753 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -541,6 +541,18 @@ static void restoreInventory(ServiceBooking* booking) } } +/* +Function: processBookingCancellation +Description: Handles cancellation or reassignment of a service booking based on user type. + Cancels associated job cards, updates booking status, clears technician assignments, + restores inventory, and sends appropriate notifications. +Parameters: + ServiceBooking* booking - The booking to cancel or reset + util::Map& jobs - Collection of job cards to update + ServiceManagementService& currentService - Service layer for notifications + util::UserType userType - Type of user initiating cancellation (CUSTOMER or TECHNICIAN) +Return type: void +*/ static void processBookingCancellation(ServiceBooking* booking, util::Map& jobs, ServiceManagementService& currentService,