Merge branch 'feature' into feature-1552-1560
This commit is contained in:
+41
@@ -7,11 +7,52 @@ Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include "AuthenticationManagementService.h"
|
||||
#include "User.h"
|
||||
|
||||
User* AuthenticationManagementService::m_authenticatedUser = nullptr;
|
||||
|
||||
/*
|
||||
Function: login
|
||||
Description: Authenticates a user by checking the provided username and password
|
||||
against the stored users in the DataStore. If successful, sets the
|
||||
authenticated user.
|
||||
Parameter: const std::string& username - user’s username
|
||||
const std::string& password - user’s password
|
||||
Return type: bool - true if login successful, false otherwise
|
||||
*/
|
||||
bool AuthenticationManagementService::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
util::Map<std::string, User*> users = m_dataStore.getUsers();
|
||||
int usersMapSize = users.getSize();
|
||||
for (int index = 0; index < usersMapSize; index++)
|
||||
{
|
||||
User* user = users.getValueAt(index);
|
||||
if (username == user->getUserName())
|
||||
{
|
||||
if (password == user->getPassword())
|
||||
{
|
||||
m_authenticatedUser = user;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: getAuthenticatedUser
|
||||
Description: Retrieves the currently authenticated user.
|
||||
Parameter: None
|
||||
Return type: User* - pointer to the authenticated user
|
||||
*/
|
||||
User* AuthenticationManagementService::getAuthenticatedUser()
|
||||
{
|
||||
return m_authenticatedUser;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: logout
|
||||
Description: Logs out the currently authenticated user by clearing the
|
||||
|
||||
+250
-7
@@ -1,15 +1,179 @@
|
||||
/*
|
||||
File: InventoryManagementService.cpp
|
||||
Description: Implementation file containing the method definitions of the
|
||||
InventoryManagementService class, including inventory operations
|
||||
and notification handling.
|
||||
Description: Implements the InventoryManagementService class, which manages inventory
|
||||
items and observer relationships within the system. Provides methods
|
||||
for loading and saving inventory items from persistent storage, as well
|
||||
as attaching and persisting observers for notification handling.
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
Date: 22-May-2026
|
||||
*/
|
||||
|
||||
#include "InventoryManagementService.h"
|
||||
#include "InventoryItem.h"
|
||||
#include <stdexcept>
|
||||
#include "Config.h"
|
||||
#include "Enums.h"
|
||||
#include "Factory.h"
|
||||
#include "FileManager.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "InventoryManagementService.h"
|
||||
#include "Timestamp.h"
|
||||
#include "User.h"
|
||||
#include "Utility.h"
|
||||
#include "Vector.h"
|
||||
|
||||
|
||||
util::Map<std::string, User*> InventoryManagementService::m_observers{};
|
||||
|
||||
/*
|
||||
Function: sendLowStockAlertsToAdmins (static helper)
|
||||
Description: Sends low stock alert notifications to all admin users for a given inventory item.
|
||||
Parameters:
|
||||
- inventoryManagementService: InventoryManagementService&, service used to send notifications
|
||||
- inventoryItem: const InventoryItem*, pointer to the low-stock inventory item
|
||||
- adminUsers: const util::Vector<User*>&, list of admin users to notify
|
||||
Returns:
|
||||
- None
|
||||
*/
|
||||
static void sendLowStockAlertsToAdmins(InventoryManagementService& inventoryManagementService, const InventoryItem* inventoryItem, const util::Vector<User*>& adminUsers)
|
||||
{
|
||||
int adminUsersSize = adminUsers.getSize();
|
||||
for (int index = 0; index < adminUsersSize; index++)
|
||||
{
|
||||
std::string title = "Low Stock Alert";
|
||||
std::string message = "The inventory item with ID " + inventoryItem->getId() + " has very low quantity in the inventory";
|
||||
inventoryManagementService.sendNotification(
|
||||
adminUsers[index],
|
||||
title,
|
||||
message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: sendLowStockAlerts
|
||||
Description: Sends alerts to user for inventory items with low stock
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- None
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: getObserverIDs
|
||||
Description: Retrieves the IDs of all observers currently attached to the
|
||||
InventoryManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- util::Vector<std::string>: Vector of observer user IDs
|
||||
*/
|
||||
util::Vector<std::string> InventoryManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> observerIDs;
|
||||
int numberOfObservers = m_observers.getSize();
|
||||
for (int index = 0; index < numberOfObservers; index++)
|
||||
{
|
||||
User* observer = m_observers.getValueAt(index);
|
||||
if (observer)
|
||||
{
|
||||
observerIDs.push_back(observer->getId());
|
||||
}
|
||||
}
|
||||
return observerIDs;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadInventoryItems
|
||||
Description: Loads inventory items from persistent storage into the datastore.
|
||||
Uses FileManager to deserialize inventory items from the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void InventoryManagementService::loadInventoryItems()
|
||||
{
|
||||
util::FileManager<InventoryItem> inventoryItemFileManager(config::file::INVENTORYITEM_FILE);
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
auto inventoryItemsMap = inventoryItemFileManager.load();
|
||||
int numberOfInventoryItems = inventoryItemsMap.getSize();
|
||||
for (int index = 0; index < numberOfInventoryItems; index++)
|
||||
{
|
||||
inventoryItems[inventoryItemsMap.getKeyAt(index)] = inventoryItemsMap.getValueAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveInventoryItems
|
||||
Description: Saves inventory items from the datastore to persistent storage.
|
||||
Uses FileManager to serialize inventory items into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void InventoryManagementService::saveInventoryItems()
|
||||
{
|
||||
util::FileManager<InventoryItem> inventoryItemFileManager(config::file::INVENTORYITEM_FILE);
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
inventoryItemFileManager.save(inventoryItems);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadObservers
|
||||
Description: Loads observer IDs from persistent storage and attaches corresponding
|
||||
users as observers to the InventoryManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void InventoryManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveObservers
|
||||
Description: Saves the current observer IDs of the InventoryManagementService
|
||||
to persistent storage for future retrieval.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void InventoryManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: addInventoryItem
|
||||
@@ -91,4 +255,83 @@ InventoryItem* InventoryManagementService::getInventoryItem(const std::string& i
|
||||
return m_dataStore.getInventoryItems().getValueAt(index);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: attach
|
||||
Description: Adds a user to the observer list for receiving inventory notifications.
|
||||
Parameters:
|
||||
- user: User*, pointer to the user to be attached as an observer
|
||||
Returns:
|
||||
- None
|
||||
*/
|
||||
void InventoryManagementService::attach(User* user)
|
||||
{
|
||||
if (user)
|
||||
{
|
||||
const std::string& userID = user->getId();
|
||||
if (m_observers.find(userID) == -1)
|
||||
{
|
||||
m_observers[userID] = user;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: detach
|
||||
Description: Removes a user from the observer list so they no longer receive inventory notifications.
|
||||
Parameters:
|
||||
- user: User*, pointer to the user to be detached from the observer list
|
||||
Returns:
|
||||
- None
|
||||
*/
|
||||
void InventoryManagementService::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 subscribed as an observer.
|
||||
Parameters:
|
||||
- user: User*, pointer to the user receiving the notification
|
||||
- title: std::string, title of the notification
|
||||
- message: std::string, body/content of the notification
|
||||
Returns:
|
||||
- None
|
||||
Throws:
|
||||
- std::runtime_error if notification creation fails
|
||||
*/
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -10,6 +10,7 @@ Date:19-May-2026
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
#include "Vector.h"
|
||||
#include "NotificationManagementService.h"
|
||||
#include "DataStore.h"
|
||||
|
||||
@@ -20,6 +21,7 @@ class InventoryManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
InventoryManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
util::Map<std::string, InventoryItem*> getInventoryItems();
|
||||
@@ -31,4 +33,8 @@ public:
|
||||
void sendNotification(User* user, const std::string& title, const std::string& message) override;
|
||||
void attach(User* user) override;
|
||||
void detach(User* user) override;
|
||||
void loadInventoryItems();
|
||||
void saveInventoryItems();
|
||||
void loadObservers();
|
||||
void saveObservers();
|
||||
};
|
||||
|
||||
+10
@@ -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
|
||||
@@ -10,4 +19,5 @@ public:
|
||||
virtual void sendNotification(User* recipient, const std::string& title, const std::string& message) = 0;
|
||||
virtual void attach(User* user) = 0;
|
||||
virtual void detach(User* user) = 0;
|
||||
virtual util::Vector<std::string> getObserverIDs() = 0;
|
||||
};
|
||||
|
||||
+254
@@ -1 +1,255 @@
|
||||
/*
|
||||
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 "Config.h"
|
||||
#include "Enums.h"
|
||||
#include "Factory.h"
|
||||
#include "FileManager.h"
|
||||
#include "Invoice.h"
|
||||
#include "PaymentManagementService.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "Timestamp.h"
|
||||
#include "User.h"
|
||||
#include "Utility.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)
|
||||
{
|
||||
std::string title = "Payment Reminder";
|
||||
std::string message = "Your payment for Invoice ID " + invoice->getId() + " is still pending. Please complete the payment.";
|
||||
sendNotification(customer, title, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: getObserverIDs
|
||||
Description: Retrieves the IDs of all observers currently attached to the
|
||||
PaymentManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- util::Vector<std::string>: Vector of observer user IDs
|
||||
*/
|
||||
util::Vector<std::string> PaymentManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> observerIDs;
|
||||
int numberOfObservers = m_observers.getSize();
|
||||
for (int index = 0; index < numberOfObservers; index++)
|
||||
{
|
||||
User* observer = m_observers.getValueAt(index);
|
||||
if (observer)
|
||||
{
|
||||
observerIDs.push_back(observer->getId());
|
||||
}
|
||||
}
|
||||
return observerIDs;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadInvoices
|
||||
Description: Loads invoices from persistent storage into the datastore.
|
||||
Validates associated service bookings and inventory parts before
|
||||
attaching them to each invoice. Throws exceptions if invalid IDs
|
||||
are encountered.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if a booking ID or part ID is invalid
|
||||
*/
|
||||
void PaymentManagementService::loadInvoices()
|
||||
{
|
||||
util::FileManager<Invoice> invoiceFileManager(config::file::INVOICE_FILE);
|
||||
auto& invoices = m_dataStore.getInvoices();
|
||||
auto& serviceBookings = m_dataStore.getServiceBookings();
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
auto invoicesMap = invoiceFileManager.load();
|
||||
for (int invoiceIndex = 0; invoiceIndex < invoicesMap.getSize(); invoiceIndex++)
|
||||
{
|
||||
Invoice* invoice = invoicesMap.getValueAt(invoiceIndex);
|
||||
int bookingIndex = serviceBookings.find(invoice->getBookingId());
|
||||
if (bookingIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Booking ID");
|
||||
}
|
||||
ServiceBooking* booking = serviceBookings.getValueAt(bookingIndex);
|
||||
invoice->setBooking(booking);
|
||||
util::Map<std::string, InventoryItem*> invoiceParts;
|
||||
auto& partIDs = invoice->getPartIDs();
|
||||
for (int partIndex = 0; partIndex < partIDs.getSize(); partIndex++)
|
||||
{
|
||||
const std::string& partID = partIDs[partIndex];
|
||||
int inventoryIndex = inventoryItems.find(partID);
|
||||
if (inventoryIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Part ID");
|
||||
}
|
||||
invoiceParts[partID] = inventoryItems.getValueAt(inventoryIndex);
|
||||
}
|
||||
invoice->setParts(invoiceParts);
|
||||
invoices[invoice->getId()] = invoice;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveInvoices
|
||||
Description: Saves invoices from the datastore to persistent storage.
|
||||
Uses FileManager to serialize invoices into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void PaymentManagementService::saveInvoices()
|
||||
{
|
||||
util::FileManager<Invoice> invoiceFileManager(config::file::INVOICE_FILE);
|
||||
auto& invoices = m_dataStore.getInvoices();
|
||||
invoiceFileManager.save(invoices);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadObservers
|
||||
Description: Loads observer IDs from persistent storage and attaches corresponding
|
||||
users as observers to the PaymentManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if an observer ID is invalid (not found in datastore)
|
||||
*/
|
||||
void PaymentManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveObservers
|
||||
Description: Saves the current observer IDs of the PaymentManagementService
|
||||
to persistent storage for future retrieval.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void PaymentManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
+14
@@ -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"
|
||||
@@ -13,6 +22,7 @@ class PaymentManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
PaymentManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
void generateInvoice(ServiceBooking* booking);
|
||||
@@ -22,4 +32,8 @@ public:
|
||||
void sendNotification(User* user, const std::string& title, const std::string& message) override;
|
||||
void attach(User* user) override;
|
||||
void detach(User* user) override;
|
||||
void loadInvoices();
|
||||
void saveInvoices();
|
||||
void loadObservers();
|
||||
void saveObservers();
|
||||
};
|
||||
|
||||
+496
-7
@@ -1,20 +1,509 @@
|
||||
/*
|
||||
File: ServiceManagementService.cpp
|
||||
Description: Implementation file containing the method definitions of the
|
||||
ServiceManagementService class, including service booking cancellation,
|
||||
job card management, combo package creation, and removal logic.
|
||||
ServiceManagementService class, including service and combo package
|
||||
purchasing logic, booking creation, and notification handling.
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "ServiceManagementService.h"
|
||||
#include <stdexcept>
|
||||
#include "AuthenticationManagementService.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "Config.h"
|
||||
#include "DataStore.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "Factory.h"
|
||||
#include "FileManager.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "JobCard.h"
|
||||
#include "Service.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "Factory.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "ServiceBooking.h"
|
||||
|
||||
#include "ServiceManagementService.h"
|
||||
#include "Timestamp.h"
|
||||
#include "User.h"
|
||||
#include "Utility.h"
|
||||
|
||||
/*
|
||||
Function: purchaseService
|
||||
Description: Creates a new service booking for the authenticated user. Validates
|
||||
service IDs, retrieves services from the DataStore, and generates a
|
||||
booking. Sends a notification upon successful booking.
|
||||
Parameter: const util::Vector<std::string>& serviceIDs - IDs of services to purchase
|
||||
const std::string& vehicleNumber - vehicle registration number
|
||||
const std::string& vehicleBrand - brand of the vehicle
|
||||
const std::string& vehicleModel - model of the vehicle
|
||||
Return type: void
|
||||
*/
|
||||
void ServiceManagementService::purchaseService(const util::Vector<std::string>& serviceIDs, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel)
|
||||
{
|
||||
AuthenticationManagementService m_authenticationManagementService;
|
||||
auto authenticatedUser = m_authenticationManagementService.getAuthenticatedUser();
|
||||
if (authenticatedUser == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No user is currently logged in!");
|
||||
}
|
||||
auto& servicesMap = m_dataStore.getServices();
|
||||
auto& serviceBookingMap = m_dataStore.getServiceBookings();
|
||||
util::Map<std::string, Service*> selectedServices;
|
||||
int selectedServicesCount = serviceIDs.getSize();
|
||||
for (int index = 0; index < selectedServicesCount; index++)
|
||||
{
|
||||
int serviceIndex = servicesMap.find(serviceIDs[index]);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Service not found!");
|
||||
}
|
||||
Service* service = servicesMap.getValueAt(serviceIndex);
|
||||
selectedServices[service->getId()] = service;
|
||||
}
|
||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::STARTED, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, 0);
|
||||
if (serviceBooking == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Failed to create service booking");
|
||||
}
|
||||
serviceBookingMap[serviceBooking->getId()] = serviceBooking;
|
||||
std::string title = "Service Booking succeeded";
|
||||
std::string message = "Your service booking has been successfully placed with ID " + serviceBooking->getId();
|
||||
sendNotification(authenticatedUser, title, message);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: purchaseComboPackage
|
||||
Description: Creates a new service booking for a combo package. Validates the combo
|
||||
package ID, retrieves services from the package, and generates a booking
|
||||
with the applicable discount. Sends a notification upon successful booking.
|
||||
Parameter: const std::string& comboPackageID - ID of the combo package
|
||||
const std::string& vehicleNumber - vehicle registration number
|
||||
const std::string& vehicleBrand - brand of the vehicle
|
||||
const std::string& vehicleModel - model of the vehicle
|
||||
Return type: void
|
||||
*/
|
||||
void ServiceManagementService::purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel)
|
||||
{
|
||||
AuthenticationManagementService m_authenticationManagementService;
|
||||
auto authenticatedUser = m_authenticationManagementService.getAuthenticatedUser();
|
||||
if (authenticatedUser == nullptr)
|
||||
{
|
||||
throw std::runtime_error("No user is currently logged in!");
|
||||
}
|
||||
auto& comboPackagesMap = m_dataStore.getComboPackages();
|
||||
auto& serviceBookingMap = m_dataStore.getServiceBookings();
|
||||
int comboPackageIndex = comboPackagesMap.find(comboPackageID);
|
||||
if (comboPackageIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Combo Package not found!");
|
||||
}
|
||||
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
||||
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::STARTED, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
||||
if (serviceBooking == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Failed to create combo package service booking");
|
||||
}
|
||||
serviceBookingMap[serviceBooking->getId()] = serviceBooking;
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: getObserverIDs
|
||||
Description: Retrieves the IDs of all observers currently attached to the
|
||||
ServiceManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- util::Vector<std::string>: Vector of observer user IDs
|
||||
*/
|
||||
util::Vector<std::string> ServiceManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> observerIDs;
|
||||
int numberOfObservers = m_observers.getSize();
|
||||
for (int index = 0; index < numberOfObservers; index++)
|
||||
{
|
||||
User* observer = m_observers.getValueAt(index);
|
||||
if (observer)
|
||||
{
|
||||
observerIDs.push_back(observer->getId());
|
||||
}
|
||||
}
|
||||
return observerIDs;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadServices
|
||||
Description: Loads services from persistent storage into the datastore.
|
||||
Validates required inventory items and attaches them to each service.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if an inventory item ID is invalid
|
||||
*/
|
||||
void ServiceManagementService::loadServices()
|
||||
{
|
||||
util::FileManager<Service> serviceFileManager(config::file::SERVICE_FILE);
|
||||
auto& services = m_dataStore.getServices();
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
auto servicesMap = serviceFileManager.load();
|
||||
for (int serviceIndex = 0; serviceIndex < servicesMap.getSize(); serviceIndex++)
|
||||
{
|
||||
Service* service = servicesMap.getValueAt(serviceIndex);
|
||||
services[service->getId()] = service;
|
||||
util::Map<std::string, InventoryItem*> inventoryItemsMap;
|
||||
auto& inventoryItemIDs = service->getRequiredInventoryItemIDs();
|
||||
for (int inventoryItemIndex = 0; inventoryItemIndex < inventoryItemIDs.getSize(); inventoryItemIndex++)
|
||||
{
|
||||
const std::string& inventoryItemID = inventoryItemIDs[inventoryItemIndex];
|
||||
int index = inventoryItems.find(inventoryItemID);
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Inventory Item ID");
|
||||
}
|
||||
inventoryItemsMap[inventoryItemID] = inventoryItems.getValueAt(index);
|
||||
}
|
||||
service->setRequiredInventoryItems(inventoryItemsMap);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveServices
|
||||
Description: Saves services from the datastore to persistent storage.
|
||||
Uses FileManager to serialize services into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void ServiceManagementService::saveServices()
|
||||
{
|
||||
util::FileManager<Service> serviceFileManager(config::file::SERVICE_FILE);
|
||||
auto& services = m_dataStore.getServices();
|
||||
serviceFileManager.save(services);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadComboPackages
|
||||
Description: Loads combo packages from persistent storage into the datastore.
|
||||
Validates associated services and attaches them to each package.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if a service ID is invalid
|
||||
*/
|
||||
void ServiceManagementService::loadComboPackages()
|
||||
{
|
||||
util::FileManager<ComboPackage> comboPackageFileManager(config::file::COMBOPACKAGE_FILE);
|
||||
auto& comboPackages = m_dataStore.getComboPackages();
|
||||
auto& services = m_dataStore.getServices();
|
||||
auto comboPackagesMap = comboPackageFileManager.load();
|
||||
for (int packageIndex = 0; packageIndex < comboPackagesMap.getSize(); packageIndex++)
|
||||
{
|
||||
ComboPackage* comboPackage = comboPackagesMap.getValueAt(packageIndex);
|
||||
util::Map<std::string, Service*> packageServices;
|
||||
auto& serviceIDs = comboPackage->getServiceIDs();
|
||||
for (int serviceIndex = 0; serviceIndex < serviceIDs.getSize(); serviceIndex++)
|
||||
{
|
||||
const std::string& serviceID = serviceIDs[serviceIndex];
|
||||
int serviceMapIndex = services.find(serviceID);
|
||||
if (serviceMapIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Service ID");
|
||||
}
|
||||
packageServices[serviceID] = services.getValueAt(serviceMapIndex);
|
||||
}
|
||||
comboPackage->setServices(packageServices);
|
||||
comboPackages[comboPackage->getId()] = comboPackage;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveComboPackages
|
||||
Description: Saves combo packages from the datastore to persistent storage.
|
||||
Uses FileManager to serialize combo packages into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void ServiceManagementService::saveComboPackages()
|
||||
{
|
||||
util::FileManager<ComboPackage> comboPackageFileManager(config::file::COMBOPACKAGE_FILE);
|
||||
auto& comboPackages = m_dataStore.getComboPackages();
|
||||
comboPackageFileManager.save(comboPackages);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadServiceBookings
|
||||
Description: Loads service bookings from persistent storage into the datastore.
|
||||
Validates associated services, customers, and technicians before
|
||||
attaching them to each booking.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if a service ID, customer ID, or technician ID is invalid
|
||||
- std::runtime_error if a user is not of the expected type (customer/technician)
|
||||
*/
|
||||
void ServiceManagementService::loadServiceBookings()
|
||||
{
|
||||
util::FileManager<ServiceBooking> bookingFileManager(config::file::SERVICEBOOKING_FILE);
|
||||
auto& serviceBookings = m_dataStore.getServiceBookings();
|
||||
auto& services = m_dataStore.getServices();
|
||||
auto& users = m_dataStore.getUsers();
|
||||
auto bookingsMap = bookingFileManager.load();
|
||||
for (int bookingIndex = 0; bookingIndex < bookingsMap.getSize(); bookingIndex++)
|
||||
{
|
||||
ServiceBooking* booking = bookingsMap.getValueAt(bookingIndex);
|
||||
util::Map<std::string, Service*> bookingServices;
|
||||
auto& serviceIDs = booking->getServiceIDs();
|
||||
for (int serviceIndex = 0; serviceIndex < serviceIDs.getSize(); serviceIndex++)
|
||||
{
|
||||
const std::string& serviceID = serviceIDs[serviceIndex];
|
||||
int serviceMapIndex = services.find(serviceID);
|
||||
if (serviceMapIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Service ID");
|
||||
}
|
||||
|
||||
bookingServices[serviceID] = services.getValueAt(serviceMapIndex);
|
||||
}
|
||||
booking->setServices(bookingServices);
|
||||
int customerIndex = users.find(booking->getCustomerId());
|
||||
if (customerIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Customer ID");
|
||||
}
|
||||
User* customer = users.getValueAt(customerIndex);
|
||||
if (customer->getUserType() != util::UserType::CUSTOMER)
|
||||
{
|
||||
throw std::runtime_error("User is not a customer");
|
||||
}
|
||||
booking->setCustomer(customer);
|
||||
const std::string& technicianId = booking->getAssignedTechnicianId();
|
||||
if (!technicianId.empty())
|
||||
{
|
||||
int technicianIndex = users.find(technicianId);
|
||||
if (technicianIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Technician ID");
|
||||
}
|
||||
User* technician = users.getValueAt(technicianIndex);
|
||||
if (technician->getUserType() != util::UserType::TECHNICIAN)
|
||||
{
|
||||
throw std::runtime_error("User is not a technician");
|
||||
}
|
||||
booking->setAssignedTechnician(technician);
|
||||
}
|
||||
serviceBookings[booking->getId()] = booking;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveServiceBookings
|
||||
Description: Saves service bookings from the datastore to persistent storage.
|
||||
Uses FileManager to serialize bookings into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void ServiceManagementService::saveServiceBookings()
|
||||
{
|
||||
util::FileManager<ServiceBooking> bookingFileManager(config::file::SERVICEBOOKING_FILE);
|
||||
auto& serviceBookings = m_dataStore.getServiceBookings();
|
||||
bookingFileManager.save(serviceBookings);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadJobCards
|
||||
Description: Loads job cards from persistent storage into the datastore.
|
||||
Validates associated bookings, services, and technicians before
|
||||
attaching them to each job card.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if a booking ID, service ID, or technician ID is invalid
|
||||
- std::runtime_error if a service does not belong to the booking
|
||||
- std::runtime_error if a user is not a technician
|
||||
*/
|
||||
void ServiceManagementService::loadJobCards()
|
||||
{
|
||||
util::FileManager<JobCard> jobCardFileManager(config::file::JOBCARD_FILE);
|
||||
auto& jobCards = m_dataStore.getJobCards();
|
||||
auto& serviceBookings = m_dataStore.getServiceBookings();
|
||||
auto& services = m_dataStore.getServices();
|
||||
auto& users = m_dataStore.getUsers();
|
||||
auto jobCardsMap = jobCardFileManager.load();
|
||||
for (int jobCardIndex = 0; jobCardIndex < jobCardsMap.getSize(); jobCardIndex++)
|
||||
{
|
||||
JobCard* jobCard = jobCardsMap.getValueAt(jobCardIndex);
|
||||
int bookingIndex = serviceBookings.find(jobCard->getBookingId());
|
||||
if (bookingIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Booking ID");
|
||||
}
|
||||
ServiceBooking* booking = serviceBookings.getValueAt(bookingIndex);
|
||||
jobCard->setBooking(booking);
|
||||
int serviceIndex = services.find(jobCard->getServiceId());
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Service ID");
|
||||
}
|
||||
Service* service = services.getValueAt(serviceIndex);
|
||||
if (booking->getServices().find(jobCard->getServiceId()) == -1)
|
||||
{
|
||||
throw std::runtime_error("Service does not belong to booking");
|
||||
}
|
||||
jobCard->setService(service);
|
||||
int technicianIndex = users.find(jobCard->getTechnicianId());
|
||||
if (technicianIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid Technician ID");
|
||||
}
|
||||
User* technician = users.getValueAt(technicianIndex);
|
||||
if (technician->getUserType() != util::UserType::TECHNICIAN)
|
||||
{
|
||||
throw std::runtime_error("User is not a technician");
|
||||
}
|
||||
jobCard->setTechnician(technician);
|
||||
jobCards[jobCard->getId()] = jobCard;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveJobCards
|
||||
Description: Saves job cards from the datastore to persistent storage.
|
||||
Uses FileManager to serialize job cards into the configured file.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void ServiceManagementService::saveJobCards()
|
||||
{
|
||||
util::FileManager<JobCard> jobCardFileManager(config::file::JOBCARD_FILE);
|
||||
auto& jobCards = m_dataStore.getJobCards();
|
||||
jobCardFileManager.save(jobCards);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadObservers
|
||||
Description: Loads observer IDs from persistent storage and attaches corresponding
|
||||
users as observers to the ServiceManagementService.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if an observer ID is invalid (not found in datastore)
|
||||
*/
|
||||
void ServiceManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveObservers
|
||||
Description: Saves the current observer IDs of the ServiceManagementService
|
||||
to persistent storage for future retrieval.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void ServiceManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: cancelCustomerServiceBookings
|
||||
|
||||
+11
@@ -23,6 +23,7 @@ class ServiceManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
ServiceManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
util::Map<std::string, Service*> getServices();
|
||||
@@ -43,4 +44,14 @@ public:
|
||||
void sendNotification(User* user, const std::string& title, const std::string& message) override;
|
||||
void attach(User* user) override;
|
||||
void detach(User* user) override;
|
||||
void loadServices();
|
||||
void saveServices();
|
||||
void loadComboPackages();
|
||||
void saveComboPackages();
|
||||
void loadServiceBookings();
|
||||
void saveServiceBookings();
|
||||
void loadJobCards();
|
||||
void saveJobCards();
|
||||
void loadObservers();
|
||||
void saveObservers();
|
||||
};
|
||||
|
||||
+239
-3
@@ -1,13 +1,249 @@
|
||||
/*
|
||||
File: UserManagementService.cpp
|
||||
Description: Implementation file containing the method definitions of the
|
||||
UserManagementService class, including user retrieval and removal logic.
|
||||
UserManagementService class, including user creation, updates,
|
||||
and ensuring an admin account exists.
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include "UserManagementService.h"
|
||||
#include "Config.h"
|
||||
#include "Enums.h"
|
||||
#include "Factory.h"
|
||||
#include "FileManager.h"
|
||||
#include "InventoryManagementService.h"
|
||||
#include "Notification.h"
|
||||
#include "PaymentManagementService.h"
|
||||
#include "ServiceManagementService.h"
|
||||
#include "User.h"
|
||||
#include "UserManagementService.h"
|
||||
#include "Vector.h"
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
/*
|
||||
Function: ensureAdminExists
|
||||
Description: Ensures that at least one admin user exists in the system.
|
||||
If no admin is found, creates a default admin user using
|
||||
configuration constants.
|
||||
Parameter: None
|
||||
Return type: void
|
||||
*/
|
||||
void UserManagementService::ensureAdminExists()
|
||||
{
|
||||
auto& usersMap = m_dataStore.getUsers();
|
||||
int usersMapSize = usersMap.getSize();
|
||||
bool isAdminFound = false;
|
||||
for (int index = 0; index < usersMapSize; index++)
|
||||
{
|
||||
User* user = usersMap.getValueAt(index);
|
||||
if (user && user->getUserType() == util::UserType::ADMIN)
|
||||
{
|
||||
isAdminFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isAdminFound)
|
||||
{
|
||||
createUser(
|
||||
config::admin::DEFAULT_ADMIN_USERNAME,
|
||||
config::admin::DEFAULT_ADMIN_NAME,
|
||||
config::admin::DEFAULT_ADMIN_PASSWORD,
|
||||
config::admin::DEFAULT_ADMIN_EMAIL,
|
||||
config::admin::DEFAULT_ADMIN_PHONE,
|
||||
util::UserType::ADMIN);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: createUser
|
||||
Description: Creates a new user with the provided details. Validates that
|
||||
the username is unique, then attaches the user to relevant
|
||||
management services (payment, service, inventory).
|
||||
Parameter: const std::string& username - user’s username
|
||||
const std::string& name - user’s name
|
||||
const std::string& password - user’s password
|
||||
const std::string& email - user’s email address
|
||||
const std::string& phone - user’s phone number
|
||||
util::UserType type - type of user (ADMIN, CUSTOMER, TECHNICIAN)
|
||||
Return type: void
|
||||
*/
|
||||
void UserManagementService::createUser(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone, util::UserType type)
|
||||
{
|
||||
InventoryManagementService inventoryManagementService;
|
||||
PaymentManagementService paymentManagementService;
|
||||
ServiceManagementService serviceManagementService;
|
||||
auto& usersMap = m_dataStore.getUsers();
|
||||
int index = usersMap.findIf(
|
||||
[&](const std::string&, User* user)
|
||||
{
|
||||
return user->getUserName() == username;
|
||||
}
|
||||
);
|
||||
if (index != -1)
|
||||
{
|
||||
throw std::runtime_error("Username already exists");
|
||||
}
|
||||
User* newUser = Factory::getObject<User>(username, password, name, phone, email, type);
|
||||
usersMap.insert(newUser->getId(), newUser);
|
||||
paymentManagementService.attach(newUser);
|
||||
serviceManagementService.attach(newUser);
|
||||
if (newUser->getUserType() == util::UserType::ADMIN)
|
||||
{
|
||||
inventoryManagementService.attach(newUser);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: updateUserDetails
|
||||
Description: Updates the email and phone details of an existing user.
|
||||
Throws an exception if the user does not exist.
|
||||
Parameter: const std::string& userID - ID of the user to update
|
||||
const std::string& email - new email address
|
||||
const std::string& phone - new phone number
|
||||
Return type: void
|
||||
*/
|
||||
void UserManagementService::updateUserDetails(const std::string& userID, const std::string& email, const std::string& phone)
|
||||
{
|
||||
auto& usersMap = m_dataStore.getUsers();
|
||||
int index = usersMap.find(userID);
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::runtime_error("User does not exist!");
|
||||
}
|
||||
User* user = usersMap.getValueAt(index);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: loadUsers
|
||||
Description: Loads users and notifications from persistent storage into the datastore.
|
||||
Validates that each notification’s recipient exists and attaches the
|
||||
notification to the corresponding user.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
Throws:
|
||||
- std::runtime_error if a notification recipient user ID is invalid
|
||||
*/
|
||||
void UserManagementService::loadUsers()
|
||||
{
|
||||
util::FileManager<User> userFileManager(config::file::USER_FILE);
|
||||
util::FileManager<Notification> notificationFileManager(config::file::NOTIFICATION_FILE);
|
||||
auto& users = m_dataStore.getUsers();
|
||||
auto usersMap = userFileManager.load();
|
||||
auto notificationsMap = notificationFileManager.load();
|
||||
int numberOfUsers = usersMap.getSize();
|
||||
int numberOfNotifications = notificationsMap.getSize();
|
||||
for (int index = 0; index < numberOfUsers; index++)
|
||||
{
|
||||
users[usersMap.getKeyAt(index)] = usersMap.getValueAt(index);
|
||||
}
|
||||
for (int index = 0; index < numberOfNotifications; index++)
|
||||
{
|
||||
Notification* notification = notificationsMap.getValueAt(index);
|
||||
const std::string& recipientUserId = notification->getRecipientUserId();
|
||||
int userIndex = users.find(recipientUserId);
|
||||
if (userIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid recipient user ID");
|
||||
}
|
||||
User* user = users.getValueAt(userIndex);
|
||||
user->addNotification(notification);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Function: saveUsers
|
||||
Description: Saves users and their notifications from the datastore to persistent storage.
|
||||
Collects notifications from all users into a single map before saving.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- void
|
||||
*/
|
||||
void UserManagementService::saveUsers()
|
||||
{
|
||||
util::FileManager<User> userFileManager(config::file::USER_FILE);
|
||||
util::FileManager<Notification> notificationFileManager(config::file::NOTIFICATION_FILE);
|
||||
auto& users = m_dataStore.getUsers();
|
||||
util::Map<std::string, Notification*> notifications;
|
||||
for (int userIndex = 0; userIndex < users.getSize(); userIndex++)
|
||||
{
|
||||
User* user = users.getValueAt(userIndex);
|
||||
auto& userNotifications = user->getNotifications();
|
||||
for (int notificationIndex = 0; notificationIndex < userNotifications.getSize(); notificationIndex++)
|
||||
{
|
||||
notifications[userNotifications.getKeyAt(notificationIndex)] =
|
||||
userNotifications.getValueAt(notificationIndex);
|
||||
}
|
||||
}
|
||||
userFileManager.save(users);
|
||||
notificationFileManager.save(notifications);
|
||||
}
|
||||
|
||||
/*
|
||||
Function: getUsers
|
||||
|
||||
+6
-3
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
File: UserManagementService.h
|
||||
Description: Header file declaring the UserManagementService class, which manages
|
||||
user creation, updates, retrieval, removal, and notification handling.
|
||||
user creation, updates, retrieval, removal, notifications, and ensures
|
||||
the existence of an admin account.
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
@@ -25,8 +25,11 @@ 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);
|
||||
void ensureAdminExists();
|
||||
void loadUsers();
|
||||
void saveUsers();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user