Merge branch 'feature-notification-management' into feature-1551-1561-1708

This commit is contained in:
2026-05-25 11:48:25 +05:30
40 changed files with 1983 additions and 58 deletions
@@ -1 +1,105 @@
#include <stdexcept>
#include "InventoryManagementService.h"
#include "Vector.h"
#include "Enums.h"
#include "InventoryItem.h"
#include "Config.h"
#include "User.h"
#include "Factory.h"
#include "Timestamp.h"
util::Map<std::string, User*> 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<Notification>(
user->getId(),
user,
"InventoryManagementService: " + title,
message,
util::Timestamp()
);
if (notification)
{
user->addNotification(notification);
}
else
{
throw std::runtime_error("Failed to create notification");
}
}
}
}
static void sendLowStockAlertsToAdmins(InventoryManagementService& inventoryManagementService, const InventoryItem* inventoryItem, const util::Vector<User*>& adminUsers)
{
int adminUsersSize = adminUsers.getSize();
for (int index = 0; index < adminUsersSize; index++)
{
inventoryManagementService.sendNotification(
adminUsers[index],
"Low Stock Alert",
"The inventory item with ID " + inventoryItem->getId() +
" has very low quantity in the inventory"
);
}
}
void InventoryManagementService::sendLowStockAlerts()
{
auto& inventoryItems = m_dataStore.getInventoryItems();
int inventoryItemsSize = inventoryItems.getSize();
auto& usersMap = m_dataStore.getUsers();
int usersMapSize = usersMap.getSize();
util::Vector<User*> adminUsers;
for (int index = 0; index < usersMapSize; index++)
{
User* user = usersMap.getValueAt(index);
if (user->getUserType() == util::UserType::ADMIN)
{
adminUsers.push_back(user);
}
}
int adminUsersSize = adminUsers.getSize();
if (adminUsersSize < 1)
{
throw std::runtime_error("The system has no admins present!");
}
for (int index = 0; index <= inventoryItemsSize; index++)
{
InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
{
sendLowStockAlertsToAdmins(*this, inventoryItem, adminUsers);
}
}
}
@@ -1,3 +1,11 @@
/*
File: InventoryManagementService.h
Description: Declares the InventoryManagementService class which manages inventory operations in the Vehicle Service Management System.
Provides functionality to retrieve, add, and remove inventory items, send low stock alerts, and handle notifications using the Observer pattern.
Author: Trenser
Date: 19-May-2026
*/
#pragma once
#include <string>
#include "Map.h"
@@ -1,6 +1,15 @@
/*
File: NotificationManagementService.h
Description: Declares the NotificationManagementService abstract class which defines the contract for managing notifications in the Vehicle Service Management System.
Implements the Subject interface and provides pure virtual methods for sending notifications and managing user subscriptions (attach/detach).
Author: Trenser
Date: 19-May-2026
*/
#pragma once
#include <string>
#include "Subject.h"
#include "Notification.h"
#include "User.h"
class NotificationManagementService : public Subject
@@ -1 +1,136 @@
/*
File: PaymentManagementService.cpp
Description: Implements the PaymentManagementService class which manages payment-related operations
in the Vehicle Service Management System. Provides functionality for attaching/detaching observers,
sending notifications, and issuing payment reminders based on invoice status and thresholds.
Author: Trenser
Date: 20-May-2026
*/
#include <stdexcept>
#include "PaymentManagementService.h"
#include "Invoice.h"
#include "ServiceBooking.h"
#include "Enums.h"
#include "Timestamp.h"
#include "Config.h"
#include "User.h"
#include "Factory.h"
util::Map<std::string, User*> PaymentManagementService::m_observers{};
/*
Function: attach
Description: Attaches a user as an observer to the PaymentManagementService for receiving notifications.
Parameters:
- user: Pointer to the User object to be attached.
Returns:
- void
*/
void PaymentManagementService::attach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) == -1)
{
m_observers[userID] = user;
}
}
}
/*
Function: detach
Description: Detaches a user from the observer list of the PaymentManagementService.
Parameters:
- user: Pointer to the User object to be detached.
Returns:
- void
*/
void PaymentManagementService::detach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) != -1)
{
m_observers.remove(userID);
}
}
}
/*
Function: sendNotification
Description: Sends a notification to a user if they are registered as an observer.
Parameters:
- user: Pointer to the User object to receive the notification.
- title: Title of the notification.
- message: Message content of the notification.
Returns:
- void
Throws:
- std::runtime_error if notification creation fails.
*/
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<Notification>(
user->getId(),
user,
"PaymentManagementService: " + title,
message,
util::Timestamp()
);
if (notification)
{
user->addNotification(notification);
}
else
{
throw std::runtime_error("Failed to create notification");
}
}
}
}
/*
Function: sendPaymentReminders
Description: Iterates through all invoices in the datastore and sends payment reminders to customers
whose invoices are pending beyond the configured threshold duration.
Parameters:
- None
Returns:
- void
*/
void PaymentManagementService::sendPaymentReminders()
{
auto& invoicesMap = m_dataStore.getInvoices();
int invoicesMapSize = invoicesMap.getSize();
for (int index = 0; index < invoicesMapSize; index++)
{
const Invoice* invoice = invoicesMap.getValueAt(index);
if (invoice && invoice->getStatus() == util::PaymentStatus::PENDING)
{
util::Timestamp invoiceCreationTimestamp = invoice->getInvoiceDate();
util::Timestamp currentTimestamp;
if (util::Timestamp::getDurationInHours(invoiceCreationTimestamp, currentTimestamp) >= config::threshold::PAYMENT_REMINDER_THRESHOLD_HOURS)
{
const ServiceBooking* serviceBooking = invoice->getBooking();
if (serviceBooking)
{
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());
}
}
}
}
}
}
@@ -1,3 +1,12 @@
/*
File: PaymentManagementService.h
Description: Declares the PaymentManagementService class which manages payment operations in the Vehicle Service Management System.
Provides functionality to generate invoices, retrieve customer invoices, complete payments, send payment reminders,
and handle notifications using the Observer pattern.
Author: Trenser
Date: 19-May-2026
*/
#pragma once
#include <string>
#include "Map.h"
@@ -7,12 +7,14 @@ Author: Trenser
Date:19-May-2026
*/
#include <stdexcept>
#include "ServiceManagementService.h"
#include "AuthenticationManagementService.h"
#include "Service.h"
#include "ServiceBooking.h"
#include "ComboPackage.h"
#include "Factory.h"
#include "Service.h"
#include "ServiceBooking.h"
#include "ServiceManagementService.h"
#include "Timestamp.h"
#include "User.h"
/*
Function: purchaseService
@@ -96,3 +98,83 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack
"Combo Package Service Booking succeeded",
"Your service booking for the combo package has been successfully placed with ID " + serviceBooking->getId());
}
util::Map<std::string, User*> ServiceManagementService::m_observers{};
/*
Function: attach
Description: Attaches a user as an observer to the ServiceManagementService for receiving notifications.
Parameters:
- user: Pointer to the User object to be attached.
Returns:
- void
*/
void ServiceManagementService::attach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) == -1)
{
m_observers[userID] = user;
}
}
}
/*
Function: detach
Description: Detaches a user from the observer list of the ServiceManagementService.
Parameters:
- user: Pointer to the User object to be detached.
Returns:
- void
*/
void ServiceManagementService::detach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) != -1)
{
m_observers.remove(userID);
}
}
}
/*
Function: sendNotification
Description: Sends a notification to a user if they are registered as an observer.
Parameters:
- user: Pointer to the User object to receive the notification.
- title: Title of the notification.
- message: Message content of the notification.
Returns:
- void
Throws:
- std::runtime_error if notification creation fails.
*/
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<Notification>(
user->getId(),
user,
"ServiceManagementService: " + title,
message,
util::Timestamp()
);
if (notification)
{
user->addNotification(notification);
}
else
{
throw std::runtime_error("Failed to create notification");
}
}
}
}
@@ -7,14 +7,16 @@ Author: Trenser
Date:19-May-2026
*/
#include <stdexcept>
#include "User.h"
#include "Enums.h"
#include "Config.h"
#include "UserManagementService.h"
#include "ServiceManagementService.h"
#include "PaymentManagementService.h"
#include "InventoryManagementService.h"
#include "Enums.h"
#include "Factory.h"
#include "InventoryManagementService.h"
#include "PaymentManagementService.h"
#include "ServiceManagementService.h"
#include "User.h"
#include "UserManagementService.h"
#include "Vector.h"
/*
Function: ensureAdminExists
@@ -110,3 +112,65 @@ void UserManagementService::updateUserDetails(const std::string& userID, const s
user->setEmail(email);
user->setPhone(phone);
}
/*
Function: getUserNotifications
Description: Retrieves all notifications associated with a given user ID.
Parameters:
- userID: The unique ID of the user whose notifications are to be retrieved.
Returns:
- util::Vector<Notification*> containing all notifications for the user.
Throws:
- std::runtime_error if no user is found with the given UserID or if the User object is invalid.
*/
util::Vector<Notification*> UserManagementService::getUserNotifications(const std::string& userID)
{
auto& usersMap = m_dataStore.getUsers();
if (usersMap.find(userID) == -1)
{
throw std::runtime_error("No user found with given UserID");
}
User* user = usersMap[userID];
if (user)
{
auto& notifications = user->getNotifications();
int numberOfNotifications = notifications.getSize();
util::Vector<Notification*> notificationsVector;
for (int index = 0; index < numberOfNotifications; index++)
{
notificationsVector.push_back(notifications.getValueAt(index));
}
return notificationsVector;
}
else
{
throw std::runtime_error("Invalid User object");
}
}
/*
Function: deleteNotification
Description: Deletes a specific notification associated with a given user ID.
Parameters:
- notificationID: The unique ID of the notification to be deleted.
- userID: The unique ID of the user whose notification is to be deleted.
Returns:
- void
Throws:
- std::runtime_error if no user is found with the given UserID or if no notification is found with the given NotificationID.
*/
void UserManagementService::deleteNotification(const std::string& notificationID, const std::string& userID)
{
auto& usersMap = m_dataStore.getUsers();
if (usersMap.find(userID) == -1)
{
throw std::runtime_error("No user found with given UserID");
}
User* user = usersMap[userID];
auto& notifications = user->getNotifications();
if (notifications.find(notificationID) == -1)
{
throw std::runtime_error("No notification found with given NotificationID");
}
notifications.remove(notificationID);
}
@@ -25,7 +25,7 @@ public:
void updateUserDetails(const std::string& userID, const std::string& email, const std::string& phone);
util::Map<std::string, User*> getUsers();
util::Map<std::string, User*> getUsers(util::UserType type);
User* getUser(const std::string& userID);
User* getUser (const std::string& userID);
void removeUser(const std::string& userID);
util::Vector<Notification*> getUserNotifications(const std::string& userID);
void deleteNotification(const std::string& notificationID, const std::string& userID);