From c92ad773c79e2dc71c2e33a626d56a61f7fd29a2 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Wed, 20 May 2026 19:55:54 +0530 Subject: [PATCH] Implement Configure Notifications functionality NOT006: Configure Notifications 1. Added notification subscription configuration in CustomerMenu to allow customers to enable or disable notifications for Payment Management Service and Service Management Service. 2. Updated Controller::configureNotifications() to attach or detach the authenticated user from service observers based on selected notification preferences. 3. Refactored Observer interface and User notification handling to support notification delivery through observer subscriptions. 4. Implemented observer attach, detach, and sendNotification logic in InventoryManagementService, PaymentManagementService, and ServiceManagementService to ensure notifications are sent only to subscribed users. Precondition: 1. Customer user is logged into the system. 2. Notification configuration option is available in Customer Menu. 3. Notification-triggering event exists for Payment Management Service or Service Management Service. Steps: 1. Navigate to Configure Notification Preferences in Customer Menu. 2. Enable notifications for one service and disable notifications for the other. 3. Trigger a notification event for both services. - Verify that notification is received only from the subscribed service. 4. Change preferences by disabling the subscribed service and enabling the other. 5. Trigger notification events again. - Verify that notification is received only from the newly subscribed service. Sreeja Reghukumar, please review --- .../controllers/Controller.cpp | 27 ++++++++- .../controllers/Controller.h | 9 ++- .../core/patterns/Observer.h | 2 +- .../models/User.cpp | 9 ++- .../models/User.h | 3 +- .../services/InventoryManagementService.cpp | 56 +++++++++++++++++++ .../services/NotificationManagementService.h | 1 + .../services/PaymentManagementService.cpp | 56 +++++++++++++++++++ .../services/ServiceManagementService.cpp | 56 +++++++++++++++++++ .../views/CustomerMenu.cpp | 31 ++++++++++ 10 files changed, 240 insertions(+), 10 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index d536e8a..f65c0c1 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -1,3 +1,4 @@ +#include #include "Controller.h" bool Controller::login(const std::string& username, const std::string& password) @@ -137,8 +138,32 @@ void Controller::deleteNotification(const std::string& notificationID) { } -void Controller::configureNotifications(const std::string& userID, bool paymentNotifications, bool serviceNotifications) +void Controller::configureNotifications(bool paymentNotifications, bool serviceNotifications) { + User* authenticatedUser = m_authenticationManagementService.getAuthenticatedUser(); + if (authenticatedUser) + { + if (paymentNotifications) + { + m_paymentManagementService.attach(authenticatedUser); + } + else + { + m_paymentManagementService.detach(authenticatedUser); + } + if (serviceNotifications) + { + m_serviceManagementService.attach(authenticatedUser); + } + else + { + m_serviceManagementService.detach(authenticatedUser); + } + } + else + { + throw std::runtime_error("No user is currently logged in!"); + } } void Controller::runSystemChecks() diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index 3aabb58..74e8edb 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -2,6 +2,9 @@ #include "Map.h" #include #include "Enums.h" +#include "AuthenticationManagementService.h" +#include "ServiceManagementService.h" +#include "PaymentManagementService.h" class Service; class ComboPackage; @@ -14,6 +17,10 @@ class Notification; class Controller { +private: + AuthenticationManagementService m_authenticationManagementService; + ServiceManagementService m_serviceManagementService; + PaymentManagementService m_paymentManagementService; public: bool login(const std::string& username, const std::string& password); void logout(); @@ -46,6 +53,6 @@ public: void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode); util::Vector getNotifications(); void deleteNotification(const std::string& notificationID); - void configureNotifications(const std::string& userID, bool paymentNotifications, bool serviceNotifications); + void configureNotifications(bool paymentNotifications, bool serviceNotifications); void runSystemChecks(); }; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h index 98f0efa..51fa582 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h @@ -6,5 +6,5 @@ class Observer { public: virtual ~Observer() = default; - virtual void update(Notification* notification) = 0; + virtual void addNotification(Notification* notification) = 0; }; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp index 52d85a9..6e0b531 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp @@ -104,7 +104,10 @@ void User::setEmail(const std::string& email) void User::addNotification(Notification* notification) { - m_notifications.insert(notification->getId(), notification); + if (notification) + { + m_notifications.insert(notification->getId(), notification); + } } void User::setRole(util::UserType role) @@ -116,7 +119,3 @@ void User::setState(util::State status) { m_status = status; } - -void User::update(Notification* notification) -{ -} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h index bde21e1..b12ea78 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h @@ -38,8 +38,7 @@ public: void setName(const std::string& name); void setPhone(const std::string& phone); void setEmail(const std::string& email); - void addNotification(Notification* notification); + void addNotification(Notification* notification) override; void setRole(util::UserType role); void setState(util::State status); - void update(Notification* notification) override; }; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp index 39ef719..0021c44 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp @@ -1 +1,57 @@ +#include #include "InventoryManagementService.h" +#include "User.h" +#include "Factory.h" +#include "Timestamp.h" + +util::Map InventoryManagementService::m_observers{}; + +void InventoryManagementService::attach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) == -1) + { + m_observers[userID] = user; + } + } +} + +void InventoryManagementService::detach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) != -1) + { + m_observers.remove(userID); + } + } +} + +void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message) +{ + if (user) + { + if (m_observers.find(user->getId()) != -1) + { + Notification* notification = + Factory::getObject( + user->getId(), + user, + "InventoryManagementService: " + title, + message, + util::Timestamp() + ); + if (notification) + { + user->addNotification(notification); + } + else + { + throw std::runtime_error("Failed to create notification"); + } + } + } +} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h index b193b1d..0b60c14 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h @@ -1,6 +1,7 @@ #pragma once #include #include "Subject.h" +#include "Notification.h" #include "User.h" class NotificationManagementService : public Subject diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 786ebcf..1979d00 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -1 +1,57 @@ +#include #include "PaymentManagementService.h" +#include "User.h" +#include "Factory.h" +#include "Timestamp.h" + +util::Map PaymentManagementService::m_observers{}; + +void PaymentManagementService::attach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) == -1) + { + m_observers[userID] = user; + } + } +} + +void PaymentManagementService::detach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) != -1) + { + m_observers.remove(userID); + } + } +} + +void PaymentManagementService::sendNotification(User* user, const std::string& title, const std::string& message) +{ + if (user) + { + if (m_observers.find(user->getId()) != -1) + { + Notification* notification = + Factory::getObject( + user->getId(), + user, + "PaymentManagementService: " + title, + message, + util::Timestamp() + ); + if (notification) + { + user->addNotification(notification); + } + else + { + throw std::runtime_error("Failed to create notification"); + } + } + } +} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 156c12b..ac518ed 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -1 +1,57 @@ +#include #include "ServiceManagementService.h" +#include "User.h" +#include "Factory.h" +#include "Timestamp.h" + +util::Map ServiceManagementService::m_observers{}; + +void ServiceManagementService::attach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) == -1) + { + m_observers[userID] = user; + } + } +} + +void ServiceManagementService::detach(User* user) +{ + if (user) + { + const std::string& userID = user->getId(); + if (m_observers.find(userID) != -1) + { + m_observers.remove(userID); + } + } +} + +void ServiceManagementService::sendNotification(User* user, const std::string& title, const std::string& message) +{ + if (user) + { + if (m_observers.find(user->getId()) != -1) + { + Notification* notification = + Factory::getObject( + user->getId(), + user, + "ServiceManagementService: " + title, + message, + util::Timestamp() + ); + if (notification) + { + user->addNotification(notification); + } + else + { + throw std::runtime_error("Failed to create notification"); + } + } + } +} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 047f471..c418def 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -67,6 +67,37 @@ void CustomerMenu::viewNotifications() { } +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(); + } +} + 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(); }