diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h index 021d831..03eb0eb 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h @@ -220,6 +220,12 @@ void DataStore::refreshCache(util::Map>& cac if (oldIndex != -1) { TrackedRecord& oldRecord = oldCache.getValueAt(oldIndex); + if (oldRecord.state == RecordState::MODIFIED) + { + delete refreshedRecord.data; + cache.insert(id, oldRecord); + continue; + } *oldRecord.data = *refreshedRecord.data; oldRecord.slotIndex = refreshedRecord.slotIndex; oldRecord.state = refreshedRecord.state; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp index 56137e5..dd80cd9 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.cpp @@ -14,10 +14,29 @@ Date:19-May-2026 #include "DataStoreLockGuard.h" User* AuthenticationManagementService::m_authenticatedUser = nullptr; +bool AuthenticationManagementService::m_isAuthorized = false; EventManager AuthenticationManagementService::m_eventManager; HANDLE AuthenticationManagementService::m_accountDisabledEvent = NULL; HANDLE AuthenticationManagementService::m_notificationsAvailableEvent = NULL; + +/* +Function: ensureAuthorization +Description: Verifies that a user is currently authenticated before allowing + access to a protected operation. Throws an exception if no + authorized user session exists. +Parameter: None +Return type: void +Throws: std::runtime_error - if the user is not authorized +*/ +void AuthenticationManagementService::ensureAuthorization() +{ + if (!m_authenticatedUser || !m_isAuthorized) + { + throw std::runtime_error("You are not authorized to do this operation!"); + } +} + /* Function: login Description: Authenticates a user by checking the provided username and password @@ -40,12 +59,14 @@ bool AuthenticationManagementService::login(const std::string& username, const s if (password == user->getPassword()) { m_authenticatedUser = user; + m_isAuthorized = true; m_eventManager.initialize( user->getId(), []() { if (m_accountDisabledEvent) { + AuthenticationManagementService::m_isAuthorized = false; SetEvent(m_accountDisabledEvent); } }, @@ -86,6 +107,7 @@ void AuthenticationManagementService::logout() { m_eventManager.shutdown(); m_authenticatedUser = nullptr; + m_isAuthorized = false; m_accountDisabledEvent = NULL; m_notificationsAvailableEvent = NULL; } @@ -99,6 +121,7 @@ Return type: void */ void AuthenticationManagementService::changePassword(const std::string& newPassword) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedUsersMap = m_dataStore.getUsers(); if (m_authenticatedUser == nullptr) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h index d512892..e927187 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/AuthenticationManagementService.h @@ -19,12 +19,14 @@ class AuthenticationManagementService { private: static User* m_authenticatedUser; + static bool m_isAuthorized; static EventManager m_eventManager; static HANDLE m_accountDisabledEvent; static HANDLE m_notificationsAvailableEvent; DataStore& m_dataStore; public: AuthenticationManagementService() : m_dataStore(DataStore::getInstance()) {} + static void ensureAuthorization(); bool login(const std::string& username, const std::string& password); void logout(); void changePassword(const std::string& newPassword); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp index a007ac1..6152fd3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp @@ -14,6 +14,7 @@ Date: 22-May-2026 #include "Factory.h" #include "InventoryItem.h" #include "InventoryManagementService.h" +#include "AuthenticationManagementService.h" #include "Timestamp.h" #include "User.h" #include "Utility.h" @@ -102,6 +103,7 @@ Return type: void */ void InventoryManagementService::addInventoryItem(const std::string& partName, int quantity, double price) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedInventoryItemMap = m_dataStore.getInventoryItems(); InventoryItem* newItem = Factory::getObject(partName, quantity, price); @@ -118,6 +120,7 @@ Return type: void */ void InventoryManagementService::addInventoryItemStock(const std::string& selectedItemId, int quantity) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedInventoryItemMap = m_dataStore.getInventoryItems(); int index = trackedInventoryItemMap.find(selectedItemId); @@ -144,6 +147,7 @@ Return type: util::Map */ util::Map InventoryManagementService::getInventoryItems() { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedInventoryItemMap = m_dataStore.getInventoryItems(); auto inventoryMap = util::getObjects(trackedInventoryItemMap); @@ -158,6 +162,7 @@ Return type: void */ void InventoryManagementService::removeInventoryItem(const std::string& inventoryItemID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedInventoryItemMap = m_dataStore.getInventoryItems(); int index = trackedInventoryItemMap.find(inventoryItemID); @@ -183,6 +188,7 @@ Return type: InventoryItem* */ InventoryItem* InventoryManagementService::getInventoryItem(const std::string& inventoryItemID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedInventoryItemMap = m_dataStore.getInventoryItems(); int index = trackedInventoryItemMap.find(inventoryItemID); @@ -270,6 +276,7 @@ void InventoryManagementService::sendNotification(User* user, const std::string& { return; } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); Notification* notification = Factory::getObject( user->getId(), title, @@ -279,7 +286,6 @@ void InventoryManagementService::sendNotification(User* user, const std::string& { throw std::runtime_error("Failed to create notification"); } - auto& trackedNotificationsMap = m_dataStore.getNotifications(); trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); m_dataStore.saveNotifications(); EventManager::sendNotificationAvailableEvent(user->getId()); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 09bf1da..b09b9bf 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -15,6 +15,7 @@ Date: 20-May-2026 #include "Invoice.h" #include "JobCard.h" #include "PaymentManagementService.h" +#include "AuthenticationManagementService.h" #include "DataStoreLockGuard.h" #include "Service.h" #include "ServiceBooking.h" @@ -98,6 +99,7 @@ void PaymentManagementService::sendNotification(User* user, const std::string& t { return; } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); Notification* notification = Factory::getObject( user->getId(), title, @@ -107,7 +109,6 @@ void PaymentManagementService::sendNotification(User* user, const std::string& t { throw std::runtime_error("Failed to create notification"); } - auto& trackedNotificationsMap = m_dataStore.getNotifications(); trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); m_dataStore.saveNotifications(); EventManager::sendNotificationAvailableEvent(user->getId()); @@ -233,6 +234,7 @@ Returns: */ util::Map PaymentManagementService::getInvoices(const std::string& customerID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& currentTrackedInvoices = m_dataStore.getInvoices(); util::Map currentUserInvoices; @@ -261,6 +263,7 @@ Throws: */ void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& currentTrackedInvoices = m_dataStore.getInvoices(); int invoiceIndex = currentTrackedInvoices.find(invoiceID); @@ -289,7 +292,7 @@ void PaymentManagementService::completePayment(const std::string& invoiceID, uti } /* -Function: getAllInvoice +Function: getAllInvoices Description: Provides access to all invoices stored in the data store. Parameters: - none @@ -298,6 +301,7 @@ Returns: */ util::Map PaymentManagementService::getAllInvoices() { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); util::Map invoices; invoices = util::getObjects(m_dataStore.getInvoices()); @@ -317,6 +321,7 @@ Throws: */ void PaymentManagementService::confirmPayment(const std::string& invoiceID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& currentTrackedInvoices = m_dataStore.getInvoices(); int invoiceIndex = currentTrackedInvoices.find(invoiceID); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 879ed73..e975ac5 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -29,6 +29,31 @@ Date:19-May-2026 #include "DataStoreLockGuard.h" #include "EventManager.h" +/* +Function: notifyAllAdmins +Description: Sends a notification to all users with the ADMIN role. + Iterates through the provided user collection and delivers + the specified notification to each administrator using the + ServiceManagementService notification mechanism. +Parameter: const std::string& title - notification title +Parameter: const std::string& message - notification message +Parameter: const util::Map>& users - collection of tracked users +Parameter: ServiceManagementService* serviceManagementService - service used to dispatch notifications +Return type: void +*/ +static void notifyAllAdmins(const std::string& title, const std::string& message, const util::Map>& users, ServiceManagementService* serviceManagementService) +{ + int numberOfUsers = users.getSize(); + for (int index = 0; index < numberOfUsers; index++) + { + User* user = users.getValueAt(index).data; + if (user->getUserType() == util::UserType::ADMIN) + { + serviceManagementService->sendNotification(user, title, message); + } + } +} + /* Function: purchaseService Description: Creates a new service booking for the authenticated user. Validates @@ -42,6 +67,7 @@ Return type: void */ void ServiceManagementService::purchaseService(const util::Vector& serviceIDs, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel) { + AuthenticationManagementService::ensureAuthorization(); AuthenticationManagementService m_authenticationManagementService; auto authenticatedUser = m_authenticationManagementService.getAuthenticatedUser(); if (authenticatedUser == nullptr) @@ -73,6 +99,7 @@ void ServiceManagementService::purchaseService(const util::Vector& std::string message = "Your service booking has been successfully placed with ID " + serviceBooking->getId(); sendNotification(authenticatedUser, title, message); m_dataStore.saveServiceBookings(); + notifyAllAdmins("New Service Order Available", "A new service order has been placed with Service Booking ID " + serviceBooking->getId(), m_dataStore.getUsers(), this); } /* @@ -88,6 +115,7 @@ Return type: void */ void ServiceManagementService::purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel) { + AuthenticationManagementService::ensureAuthorization(); AuthenticationManagementService m_authenticationManagementService; auto authenticatedUser = m_authenticationManagementService.getAuthenticatedUser(); if (authenticatedUser == nullptr) @@ -113,6 +141,7 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack 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); + notifyAllAdmins("New Combo Package Order Available", "A new combo package order has been placed with Service Booking ID " + serviceBooking->getId(), m_dataStore.getUsers(), this); } util::Map ServiceManagementService::m_observers{}; @@ -189,6 +218,7 @@ void ServiceManagementService::sendNotification(User* user, const std::string& t { return; } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); Notification* notification = Factory::getObject( user->getId(), title, @@ -198,7 +228,6 @@ void ServiceManagementService::sendNotification(User* user, const std::string& t { throw std::runtime_error("Failed to create notification"); } - auto& trackedNotificationsMap = m_dataStore.getNotifications(); trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); m_dataStore.saveNotifications(); EventManager::sendNotificationAvailableEvent(user->getId()); @@ -434,6 +463,7 @@ Return type: void */ void ServiceManagementService::createComboPackage(const std::string& packageName, const util::Vector& serviceIDsInNewCombo, double discountPercentage) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); if (packageName.empty()) { @@ -503,6 +533,7 @@ Return type: util::Map */ util::Map ServiceManagementService::getComboPackages() { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); util::Map comboPackages; comboPackages = util::getObjects(m_dataStore.getComboPackages()); @@ -517,6 +548,7 @@ Return type: void */ void ServiceManagementService::removeComboPackage(const std::string& comboPackageID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); bool removed = false; auto& trackedComboPackages = m_dataStore.getComboPackages(); @@ -549,6 +581,7 @@ Returns: */ util::Map ServiceManagementService::getServiceBookings() { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); util::Map serviceBookings; serviceBookings = util::getObjects(m_dataStore.getServiceBookings()); @@ -565,6 +598,7 @@ Returns: */ ServiceBooking* ServiceManagementService::getServiceBooking(const std::string& serviceID) { + AuthenticationManagementService::ensureAuthorization(); auto currentServiceBookings = getServiceBookings(); for (int iterator = 0; iterator < currentServiceBookings.getSize(); iterator++) { @@ -591,6 +625,7 @@ Throws: */ void ServiceManagementService::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); UserManagementService m_userManagementService; ServiceBooking* currentBooking = getServiceBooking(bookingID); @@ -668,6 +703,7 @@ Throws: */ void ServiceManagementService::createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); util::Map currentServiceInventoryItems; auto& trackedInventoryItems = m_dataStore.getInventoryItems(); @@ -714,6 +750,7 @@ Returns: */ util::Map ServiceManagementService::getServices() { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); util::Map services; services = util::getObjects(m_dataStore.getServices()); @@ -732,6 +769,7 @@ Throws: */ void ServiceManagementService::removeService(const std::string& serviceID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& currentTrackedServices = m_dataStore.getServices(); auto& currentTrackedComboPackages = m_dataStore.getComboPackages(); @@ -779,6 +817,7 @@ Returns: */ util::Map ServiceManagementService::getServiceBookings(const std::string& customerID) { + AuthenticationManagementService::ensureAuthorization(); util::Map currentServiceBookings = getServiceBookings(); util::Map currentUserServiceBookings; if (currentServiceBookings.getSize() != 0) @@ -805,6 +844,7 @@ Returns: */ util::Map ServiceManagementService::getJobCards(const std::string& technicianID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedJobCards = m_dataStore.getJobCards(); util::Map technicianJobCards; @@ -859,6 +899,7 @@ Returns: */ void ServiceManagementService::updateJobStatus(const std::string& jobID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); AuthenticationManagementService authenticationManagementService; PaymentManagementService paymentManagementService; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp index ab85936..0c3991d 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp @@ -15,6 +15,7 @@ Date:19-May-2026 #include "Notification.h" #include "PaymentManagementService.h" #include "ServiceManagementService.h" +#include "AuthenticationManagementService.h" #include "User.h" #include "UserManagementService.h" #include "Vector.h" @@ -114,6 +115,7 @@ Return type: void */ void UserManagementService::updateUserDetails(const std::string& userID, const std::string& email, const std::string& phone) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedUsersMap = m_dataStore.getUsers(); auto usersMap = util::getObjects(trackedUsersMap); @@ -161,6 +163,7 @@ Throws: */ util::Vector UserManagementService::getUserNotifications(const std::string& userID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedUsersMap = m_dataStore.getUsers(); if (trackedUsersMap.find(userID) == -1) @@ -204,6 +207,7 @@ Throws: */ void UserManagementService::deleteNotification(const std::string& notificationID, const std::string& userID) { + AuthenticationManagementService::ensureAuthorization(); DataStoreLockGuard lock(m_dataStore); auto& trackedUsersMap = m_dataStore.getUsers(); auto& trackedNotificationsMap = m_dataStore.getNotifications(); @@ -265,6 +269,7 @@ Return type: void */ void UserManagementService::removeUser(const std::string& userID) { + AuthenticationManagementService::ensureAuthorization(); InventoryManagementService inventoryManagementService; PaymentManagementService paymentManagementService; ServiceManagementService serviceManagementService;