Merged PR 1199: Fix Multiple Notifications Contain Formatting Issues, Vague Messaging, and Duplicate Entries

Changes:

- Updated ServiceManagementService::createJobCard() to prevent duplicate
  "Technician assigned" notifications when multiple job cards exist for
  the same booking.
- Refined job card creation notification to include Job Card ID, Service
  ID, and Booking ID for clearer technician communication.
- Corrected service booking cancellation notification formatting by
  standardizing capitalization and improving message clarity.
- Improved service booking completion notification to explicitly mention
  the booking ID and confirm invoice generation.
- Ensured consistent notification titles and messages across the
  workflow for better user understanding.

Fixes

#2114

Related work items: #2114
This commit is contained in:
Jissin Mathew
2026-06-18 19:44:35 +05:30
committed by Joel Thomas
@@ -629,6 +629,7 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
DataStoreLockGuard lock(m_dataStore); DataStoreLockGuard lock(m_dataStore);
UserManagementService m_userManagementService; UserManagementService m_userManagementService;
ServiceBooking* currentBooking = getServiceBooking(bookingID); ServiceBooking* currentBooking = getServiceBooking(bookingID);
std::string title, message;
if (currentBooking == nullptr) if (currentBooking == nullptr)
{ {
throw std::runtime_error("Service Booking not available"); throw std::runtime_error("Service Booking not available");
@@ -684,18 +685,30 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
trackedCurrentInventoryItem.state = RecordState::MODIFIED; trackedCurrentInventoryItem.state = RecordState::MODIFIED;
} }
} }
currentBooking->setAssignedTechnician(selectedTechnician); const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
currentBooking->setAssignedTechnicianId(selectedTechnician->getId()); const std::string& currentAssignedTechnicianId = currentBooking->getAssignedTechnicianId();
if (!currentAssignedTechnician && currentAssignedTechnicianId.empty())
{
currentBooking->setAssignedTechnician(selectedTechnician);
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
title = "Technician assigned";
message = "A technician has been assigned to your Service Booking with ID " + bookingID;
sendNotification(currentBooking->getCustomer(), title, message);
}
if (currentBooking->getStatus() == util::ServiceJobStatus::PENDING) if (currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
{ {
currentBooking->setStatus(util::ServiceJobStatus::STARTED); currentBooking->setStatus(util::ServiceJobStatus::STARTED);
} }
currentTrackedServiceBooking.state = RecordState::MODIFIED; currentTrackedServiceBooking.state = RecordState::MODIFIED;
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<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp()); JobCard* jobCard = Factory::getObject<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
if (jobCard) if (jobCard)
{ {
title = "Job Card Assigned";
message = "A new Job Card (ID: " + jobCard->getId() +
") has been created for Service " + serviceID +
" in Booking " + bookingID +
". You have been assigned to this job.";
currentTrackedJobCards.insert(jobCard->getId(), util::createNewRecord(jobCard)); currentTrackedJobCards.insert(jobCard->getId(), util::createNewRecord(jobCard));
sendNotification(selectedTechnician, title, message); sendNotification(selectedTechnician, title, message);
} }
@@ -703,9 +716,6 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
{ {
throw std::runtime_error("Failed to create job card."); throw std::runtime_error("Failed to create job card.");
} }
title = "Technician assigned";
message = "A technician has been assigned to your Service Booking with ID " + bookingID;
sendNotification(currentBooking->getCustomer(), title, message);
m_dataStore.saveJobCards(); m_dataStore.saveJobCards();
m_dataStore.saveServiceBookings(); m_dataStore.saveServiceBookings();
m_dataStore.saveInventoryItems(); m_dataStore.saveInventoryItems();
@@ -852,8 +862,8 @@ void ServiceManagementService::removeServiceBooking(const std::string& bookingID
{ {
if (currentServiceBooking->getStatus() == util::ServiceJobStatus::PENDING) if (currentServiceBooking->getStatus() == util::ServiceJobStatus::PENDING)
{ {
const std::string title = "Service Booking cancelled."; const std::string title = "Service Booking Cancelled";
const std::string message = "Service Booking of id " + bookingID + " successfully cancelled."; const std::string message = "Service Booking (ID: " + bookingID + ") has been successfully cancelled";
currentServiceBooking->setStatus(util::ServiceJobStatus::CANCELLED); currentServiceBooking->setStatus(util::ServiceJobStatus::CANCELLED);
currentTrackedServiceBooking.state = RecordState::MODIFIED; currentTrackedServiceBooking.state = RecordState::MODIFIED;
serviceBookingRemoved = true; serviceBookingRemoved = true;
@@ -1025,8 +1035,8 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED); currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
trackedServiceBookings.getValueAt(trackedServiceBookings.find(bookingId)).state = RecordState::MODIFIED; trackedServiceBookings.getValueAt(trackedServiceBookings.find(bookingId)).state = RecordState::MODIFIED;
paymentManagementService.generateInvoice(currentJob->getBooking()); paymentManagementService.generateInvoice(currentJob->getBooking());
std::string title = "Service Booking completed. Invoice Generated."; std::string title = "Service Booking Completed";
std::string message = "Services completed for the booking and invoice generated."; std::string message = "Service Booking (ID: " + bookingId + ") has been completed successfully. An invoice has been generated.";
sendNotification(currentJob->getBooking()->getCustomer(), title, message); sendNotification(currentJob->getBooking()->getCustomer(), title, message);
} }
} }