diff --git a/.gitignore b/.gitignore
index fe37065..37b6ea3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -427,5 +427,5 @@ FodyWeavers.xsd
*.msm
*.msp
-# CSV Files
-*.csv
+# DAT Files
+*.dat
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
index 7c4bfd3..34bfc34 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
@@ -140,7 +140,6 @@
-
@@ -182,7 +181,6 @@
-
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
index 7e74b19..c13b320 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
@@ -114,9 +114,6 @@
Source Files\DataStores
-
- Source Files\Services
-
Source Files\Core\Patterns
@@ -245,9 +242,6 @@
Header Files\Utilities
-
- Header Files\Utilities
-
Header Files\Utilities
@@ -278,5 +272,8 @@
Header Files\DataStores\SharedMemory
+
+ Header Files\DataStores
+
\ 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 7fd7262..98e6f97 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h
@@ -7,11 +7,8 @@ Date: 19-May-2026
#pragma once
-class Notification;
-
class Observer
{
public:
virtual ~Observer() = default;
- virtual void addNotification(Notification* notification) = 0;
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
index bda9ac0..52b3e57 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
@@ -144,11 +144,6 @@ bool DataStore::initialize()
success = false;
break;
}
- if (!SharedMemory::createOrOpenMapping(m_payments))
- {
- success = false;
- break;
- }
if (!SharedMemory::createOrOpenMapping(m_serviceManagementObservers))
{
success = false;
@@ -193,7 +188,6 @@ void DataStore::shutdown()
SharedMemory::closeMapping(m_serviceBookings);
SharedMemory::closeMapping(m_jobCards);
SharedMemory::closeMapping(m_invoices);
- SharedMemory::closeMapping(m_payments);
SharedMemory::closeMapping(m_serviceManagementObservers);
SharedMemory::closeMapping(m_paymentManagementObservers);
SharedMemory::closeMapping(m_inventoryManagementObservers);
@@ -230,20 +224,6 @@ util::Map>& DataStore::getUsers()
{
auto users = loadRecords(m_users);
refreshCache(m_userCache, users);
- auto& notifications = getNotifications();
- int numberOfNotifications = m_notificationCache.getSize();
- for (int index = 0; index < numberOfNotifications; index++)
- {
- Notification* notification = notifications.getValueAt(index).data;
- const std::string& recipientUserId = notification->getRecipientUserId();
- int userIndex = m_userCache.find(recipientUserId);
- if (userIndex == -1)
- {
- throw std::runtime_error("Invalid recipient user ID");
- }
- User* user = m_userCache.getValueAt(userIndex).data;
- user->addNotification(notification);
- }
return m_userCache;
}
@@ -340,6 +320,37 @@ util::Map>& DataStore::getInvoices()
return m_invoiceCache;
}
+/*
+Function: getObservers
+Description: Retrieves observer records from the specified observer mapping
+ and resolves them to User objects.
+Parameters:
+ - mapping: Observer mapping to read from
+Returns:
+ - util::Map: Collection of observer records
+Throws:
+ - std::runtime_error if an observer references an invalid user ID
+*/
+util::Map DataStore::getObservers(MappingInfo& mapping)
+{
+ auto& users = getUsers();
+ util::Map observers;
+ SharedMemory::ensureLatestMapping(mapping);
+ size_t recordCount = SharedMemory::getRecordCount(mapping);
+ for (size_t index = 0; index < recordCount; index++)
+ {
+ const SerializedObserver* observer = static_cast(SharedMemory::getRecordAddress(mapping, index));
+ int userIndex = users.find(observer->id);
+ if (userIndex == -1)
+ {
+ throw std::runtime_error("Invalid observer user ID");
+ }
+ User* user = users.getValueAt(userIndex).data;
+ observers.insert(user->getId(), user);
+ }
+ return observers;
+}
+
/*
Function: getServiceManagementObservers
Description: Retrieves all service management observer records from the datastore.
@@ -350,7 +361,7 @@ Returns:
*/
util::Map DataStore::getServiceManagementObservers()
{
- return util::Map();
+ return getObservers(m_serviceManagementObservers);
}
/*
@@ -363,7 +374,7 @@ Returns:
*/
util::Map DataStore::getPaymentManagementObservers()
{
- return util::Map();
+ return getObservers(m_paymentManagementObservers);
}
/*
@@ -376,7 +387,7 @@ Returns:
*/
util::Map DataStore::getInventoryManagementObservers()
{
- return util::Map();
+ return getObservers(m_inventoryManagementObservers);
}
/*
@@ -390,7 +401,6 @@ Returns:
void DataStore::saveUsers()
{
saveRecords(m_users, m_userCache);
- saveNotifications();
}
/*
@@ -478,16 +488,49 @@ void DataStore::saveInvoices()
{
}
+/*
+Function: saveObservers
+Description: Persists observer records to the specified observer mapping.
+Parameters:
+ - mapping: MappingInfo&, observer mapping to save to
+ - observers: util::Map&, collection of observer records
+Returns:
+ - None
+*/
+void DataStore::saveObservers(MappingInfo& mapping, util::Map& observers)
+{
+ size_t observerCount = static_cast(observers.getSize());
+ size_t capacity = config::file::INITIAL_CAPACITY;
+ while (capacity < observerCount)
+ {
+ capacity *= config::file::GROWTH_FACTOR;
+ }
+ if (!SharedMemory::resizeMapping(mapping, capacity))
+ {
+ throw std::runtime_error("Failed to resize observer mapping");
+ }
+ SharedMemory::setRecordCount(mapping, observerCount);
+ for (size_t index = 0; index < observerCount; index++)
+ {
+ SerializedObserver serializedObserver;
+ User* user = observers.getValueAt(static_cast(index));
+ strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str());
+ SerializedObserver* destination = static_cast(SharedMemory::getRecordAddress(mapping, index));
+ *destination = serializedObserver;
+ }
+}
+
/*
Function: saveServiceManagementObservers
Description: Persists all service management observer records to the datastore.
Parameters:
- - observers: util::Map>&, collection of observer records
+ - observers: util::Map&, collection of observer records
Returns:
- None
*/
void DataStore::saveServiceManagementObservers(util::Map& observers)
{
+ saveObservers(m_serviceManagementObservers, observers);
}
/*
@@ -500,6 +543,7 @@ Returns:
*/
void DataStore::savePaymentManagementObservers(util::Map& observers)
{
+ saveObservers(m_paymentManagementObservers, observers);
}
/*
@@ -512,32 +556,7 @@ Returns:
*/
void DataStore::saveInventoryManagementObservers(util::Map& observers)
{
-}
-
-/*
-Function: lockDataStore
-Description: Acquires exclusive access to the datastore.
-Parameters:
- - None
-Returns:
- - bool: True if the datastore was successfully locked, otherwise false
-*/
-bool DataStore::lockDataStore()
-{
- return false;
-}
-
-/*
-Function: unlockDataStore
-Description: Releases exclusive access to the datastore.
-Parameters:
- - None
-Returns:
- - bool: True if the datastore was successfully unlocked, otherwise false
-*/
-bool DataStore::unlockDataStore()
-{
- return false;
+ saveObservers(m_inventoryManagementObservers, observers);
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
index 3950b11..265f8df 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
@@ -12,14 +12,14 @@ Date: 19-May-2026
#include "MappingInfo.h"
#include "TrackedRecord.h"
#include "SharedMemory.h"
-class User;
-class Notification;
-class Service;
-class ComboPackage;
-class InventoryItem;
-class ServiceBooking;
-class JobCard;
-class Invoice;
+#include "User.h"
+#include "Notification.h"
+#include "Service.h"
+#include "ComboPackage.h"
+#include "InventoryItem.h"
+#include "ServiceBooking.h"
+#include "JobCard.h"
+#include "Invoice.h"
class DataStore
{
@@ -39,7 +39,6 @@ private:
MappingInfo m_serviceBookings;
MappingInfo m_jobCards;
MappingInfo m_invoices;
- MappingInfo m_payments;
MappingInfo m_serviceManagementObservers;
MappingInfo m_paymentManagementObservers;
MappingInfo m_inventoryManagementObservers;
@@ -86,6 +85,8 @@ private:
void saveRecords(MappingInfo& mapping, util::Map>& records);
template void clearCache(util::Map>&cache);
template void refreshCache(util::Map>&cache, util::Map>&refreshedCache);
+ util::Map getObservers(MappingInfo& mapping);
+ void saveObservers(MappingInfo& mapping, util::Map& observers);
};
/*
@@ -229,9 +230,17 @@ void DataStore::refreshCache(util::Map>& cac
for (int index = 0; index < oldCache.getSize(); ++index)
{
const std::string& id = oldCache.getKeyAt(index);
+ const TrackedRecord& localTrackedRecord = oldCache.getValueAt(index);
if (cache.find(id) == -1)
{
- delete oldCache.getValueAt(index).data;
+ if (localTrackedRecord.state == RecordState::NEW_RECORD)
+ {
+ cache.insert(id, localTrackedRecord);
+ }
+ else
+ {
+ delete localTrackedRecord.data;
+ }
}
}
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp
index 4b151e3..0c5c7b1 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp
@@ -320,7 +320,7 @@ bool SharedMemory::ensureCapacityForInsert(MappingInfo& mapping)
{
return true;
}
- return resizeMapping(mapping, capacity * 2);
+ return resizeMapping(mapping, capacity * config::file::GROWTH_FACTOR);
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
index 941c2b3..29be6a9 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
@@ -12,6 +12,7 @@ Date: 19-May-2026
#include "Enums.h"
class Service;
+struct SerializedComboPackage;
class ComboPackage
{
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
index 0bae917..83532ec 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
@@ -1,12 +1,13 @@
/*
File: Notification.cpp
Description: Implements the Notification class which represents system notifications in the Vehicle Service Management System.
- Provides constructors, accessors, and mutators for notification details such as ID, recipient, title, message, and timestamp.
+ Provides constructors, accessors, and mutators for notification details such as ID, recipientID, title, message, and timestamp.
Author: Trenser
Date: 19-May-2026
*/
#include
+#include "SerializedRecords.h"
#include "Notification.h"
#include "StringHelper.h"
#include "Factory.h"
@@ -22,8 +23,8 @@ Returns:
- A new Notification object.
*/
Notification::Notification()
- : m_id("NOT" + std::to_string(++m_uid)),
- m_recipient(nullptr) {}
+ : m_id("NOT" + std::to_string(++m_uid)),
+ m_state(util::State::ACTIVE) {}
/*
Function: Notification
@@ -37,13 +38,14 @@ Parameters:
Returns:
- A new Notification object.
*/
-Notification::Notification(const std::string& recipientUserId, User* recipient, const std::string& title, const std::string& message, const util::Timestamp& createdAt)
+Notification::Notification(const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt)
: m_id("NOT" + std::to_string(++m_uid)),
m_recipientUserId(recipientUserId),
- m_recipient(recipient),
m_title(title),
m_message(message),
- m_createdAt(createdAt) {}
+ m_state(util::State::ACTIVE),
+ m_createdAt(createdAt) {
+}
/*
Function: Notification (parameterized constructor with ID)
@@ -58,13 +60,13 @@ Parameters:
Returns:
- A new Notification object
*/
-Notification::Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt)
+Notification::Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt, const util::State& state)
: m_id(id),
m_recipientUserId(recipientUserId),
- m_recipient(nullptr),
m_title(title),
m_message(message),
- m_createdAt(createdAt)
+ m_createdAt(createdAt),
+ m_state(state)
{
int idNumber = util::extractNumber(m_id);
if (idNumber > m_uid)
@@ -79,7 +81,7 @@ Description: Retrieves the unique ID of the notification.
Returns:
- const std::string& representing the notification ID.
*/
-const std::string& Notification::getId() const
+const std::string& Notification::getId() const
{
return m_id;
}
@@ -95,17 +97,6 @@ const std::string& Notification::getRecipientUserId() const
return m_recipientUserId;
}
-/*
-Function: getRecipient
-Description: Retrieves the pointer to the recipient user.
-Returns:
- - User* representing the recipient.
-*/
-User* Notification::getRecipient() const
-{
- return m_recipient;
-}
-
/*
Function: getTitle
Description: Retrieves the title of the notification.
@@ -139,6 +130,17 @@ const util::Timestamp& Notification::getCreatedAt() const
return m_createdAt;
}
+/*
+Function: getState
+Description: Retrieves the Notification state
+Returns:
+ - const util::Timestamp& representing the creation timestamp.
+*/
+util::State Notification::getState() const
+{
+ return m_state;
+}
+
/*
Function: setId
Description: Sets the unique ID of the notification.
@@ -165,19 +167,6 @@ void Notification::setRecipientUserId(const std::string& recipientUserId)
m_recipientUserId = recipientUserId;
}
-/*
-Function: setRecipient
-Description: Sets the recipient user pointer for the notification.
-Parameters:
- - recipient: Pointer to the User object.
-Returns:
- - void
-*/
-void Notification::setRecipient(User* recipient)
-{
- m_recipient = recipient;
-}
-
/*
Function: setTitle
Description: Sets the title of the notification.
@@ -217,71 +206,54 @@ void Notification::setCreatedAt(const util::Timestamp& createdAt)
m_createdAt = createdAt;
}
+/*
+Function: setState
+Description: Sets the Notification state.
+Parameters:
+ - state: Notification state value.
+Returns:
+ - void
+*/
+void Notification::setState(util::State state)
+{
+ m_state = state;
+}
+
/*
Function: serialize
-Description: Serializes the notification into a CSV-formatted string.
+Description: Serializes the Notification object into a SerializedNotification record.
Parameters:
- None
Returns:
- - std::string: Serialized notification record
+ - SerializedNotification: Serialized representation of the notification
*/
-std::string Notification::serialize() const
+SerializedNotification Notification::serialize() const
{
- std::ostringstream serializedNotification;
- serializedNotification << m_id << ','
- << m_recipientUserId << ','
- << m_title << ','
- << m_message << ','
- << m_createdAt.toString();
- return serializedNotification.str();
+ SerializedNotification serialized = {};
+ strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
+ strcpy_s(serialized.recipientUserId, sizeof(serialized.recipientUserId), m_recipientUserId.c_str());
+ strcpy_s(serialized.title, sizeof(serialized.title), m_title.c_str());
+ strcpy_s(serialized.message, sizeof(serialized.message), m_message.c_str());
+ serialized.createdAt = m_createdAt;
+ serialized.state = m_state;
+ return serialized;
}
/*
Function: deserialize
-Description: Deserializes a CSV-formatted string into a Notification object.
+Description: Deserializes a SerializedNotification record into a Notification object.
Parameters:
- - record: const std::string&, serialized notification record
+ - serializedNotification: const SerializedNotification&, serialized notification record
Returns:
- Notification*: Pointer to the deserialized Notification object
-Throws:
- - std::runtime_error if timestamp parsing fails
*/
-Notification* Notification::deserialize(const std::string& record)
+Notification* Notification::deserialize(const SerializedNotification& serializedNotification)
{
- std::string id, recipientUserId, title, message, createdAtTimestampString;
- std::istringstream serializedNotification(record);
- getline(serializedNotification, id, ',');
- getline(serializedNotification, recipientUserId, ',');
- getline(serializedNotification, title, ',');
- getline(serializedNotification, message, ',');
- getline(serializedNotification, createdAtTimestampString, ',');
- util::Timestamp createdAtTimestamp;
- try
- {
- createdAtTimestamp = util::Timestamp::fromString(createdAtTimestampString);
- }
- catch (...)
- {
- throw std::runtime_error("Invalid createdAt timestamp");
- }
return Factory::getObject(
- id,
- recipientUserId,
- title,
- message,
- createdAtTimestamp
- );
-}
-
-/*
-Function: getHeaders
-Description: Retrieves the CSV headers for notification serialization.
-Parameters:
- - None
-Returns:
- - std::string: Header string ("ID,RecipientID,Title,Message,Timestamp")
-*/
-std::string Notification::getHeaders()
-{
- return "ID,RecipientID,Title,Message,Timestamp";
+ serializedNotification.id,
+ serializedNotification.recipientUserId,
+ serializedNotification.title,
+ serializedNotification.message,
+ serializedNotification.createdAt,
+ serializedNotification.state);
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h
index 57869fa..a102cc6 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h
@@ -9,8 +9,10 @@ Date: 19-May-2026
#pragma once
#include
#include "Timestamp.h"
+#include "Enums.h"
class User;
+struct SerializedNotification;
class Notification
{
@@ -18,27 +20,26 @@ private:
static int m_uid;
std::string m_id;
std::string m_recipientUserId;
- User* m_recipient;
std::string m_title;
std::string m_message;
util::Timestamp m_createdAt;
+ util::State m_state;
public:
Notification();
- Notification(const std::string& recipientUserId, User* recipient, const std::string& title, const std::string& message, const util::Timestamp& createdAt);
- Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt);
+ Notification(const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt);
+ Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt, const util::State& state);
const std::string& getId() const;
const std::string& getRecipientUserId() const;
- User* getRecipient() const;
const std::string& getTitle() const;
const std::string& getMessage() const;
const util::Timestamp& getCreatedAt() const;
void setId(const std::string& id);
void setRecipientUserId(const std::string& recipientUserId);
- void setRecipient(User* recipient);
void setTitle(const std::string& title);
void setMessage(const std::string& message);
void setCreatedAt(const util::Timestamp& createdAt);
- std::string serialize() const;
- static Notification* deserialize(const std::string&);
- static std::string getHeaders();
+ util::State getState() const;
+ void setState(util::State state);
+ SerializedNotification serialize() const;
+ static Notification* deserialize(const SerializedNotification&);
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
index c4dc928..5794259 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
@@ -89,23 +89,6 @@ User::User(const std::string& userId, const std::string& userName, const std::st
}
}
-/*
-Function: ~User
-Description: Destructor that cleans up dynamically allocated notifications associated with the user.
-Parameters:
- - None
-Returns:
- - void
-*/
-User::~User()
-{
- auto values = m_notifications.getValues();
- for (int index = 0; index < values.getSize(); index++)
- {
- delete values[index];
- }
-}
-
/*
Function: getId
Description: Retrieves the unique ID of the user.
@@ -172,17 +155,6 @@ const std::string& User::getEmail() const
return m_email;
}
-/*
-Function: getNotifications
-Description: Retrieves the map of notifications associated with the user.
-Returns:
- - util::Map& representing the notifications.
-*/
-util::Map& User::getNotifications()
-{
- return m_notifications;
-}
-
/*
Function: getUserType
Description: Retrieves the role of the user.
@@ -283,22 +255,6 @@ void User::setEmail(const std::string& email)
m_email = email;
}
-/*
-Function: addNotification
-Description: Adds a new notification to the user’s notification map.
-Parameters:
- - notification: Pointer to the Notification object.
-Returns:
- - void
-*/
-void User::addNotification(Notification* notification)
-{
- if (notification)
- {
- m_notifications.insert(notification->getId(), notification);
- }
-}
-
/*
Function: setRole
Description: Sets the role of the user.
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
index 1026bd3..1a0f93f 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
@@ -26,21 +26,19 @@ private:
std::string m_name;
std::string m_phone;
std::string m_email;
- util::Map m_notifications;
util::UserType m_type;
util::State m_status;
public:
User();
User(const std::string& userName, const std::string& password, const std::string& name, const std::string& phone, const std::string& email, util::UserType role);
User(const std::string& userId, const std::string& userName, const std::string& password, const std::string& name, const std::string& phone, const std::string& email, util::UserType role, util::State status);
- ~User();
+ ~User() = default;
const std::string& getId() const;
const std::string& getUserName() const;
const std::string& getPassword() const;
const std::string& getName() const;
const std::string& getPhone() const;
const std::string& getEmail() const;
- util::Map& getNotifications();
util::UserType getUserType() const;
util::State getState() const;
void setId(const std::string& id);
@@ -49,7 +47,6 @@ public:
void setName(const std::string& name);
void setPhone(const std::string& phone);
void setEmail(const std::string& email);
- void addNotification(Notification* notification) override;
void setRole(util::UserType role);
void setState(util::State status);
SerializedUser serialize() const;
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
index d08d957..32e2453 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
@@ -12,14 +12,13 @@ Date: 22-May-2026
#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"
-
+#include "DataStoreLockGuard.h"
util::Map InventoryManagementService::m_observers{};
@@ -90,95 +89,6 @@ void InventoryManagementService::sendLowStockAlerts()
}
}
-/*
-Function: getObserverIDs
-Description: Retrieves the IDs of all observers currently attached to the
- InventoryManagementService.
-Parameters:
- - None
-Returns:
- - util::Vector: Vector of observer user IDs
-*/
-util::Vector InventoryManagementService::getObserverIDs()
-{
- util::Vector 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 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 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
Description: Creates a new inventory item using the Factory and inserts it
@@ -271,6 +181,9 @@ Returns:
*/
void InventoryManagementService::attach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getInventoryManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -279,6 +192,7 @@ void InventoryManagementService::attach(User* user)
m_observers[userID] = user;
}
}
+ m_dataStore.saveInventoryManagementObservers(m_observers);
}
/*
@@ -291,6 +205,9 @@ Returns:
*/
void InventoryManagementService::detach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getInventoryManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -299,6 +216,7 @@ void InventoryManagementService::detach(User* user)
m_observers.remove(userID);
}
}
+ m_dataStore.saveInventoryManagementObservers(m_observers);
}
/*
@@ -315,27 +233,27 @@ Throws:
*/
void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message)
{
- if (user)
+ if (!user)
{
- if (m_observers.find(user->getId()) != -1)
- {
- Notification* notification =
- Factory::getObject(
- user->getId(),
- user,
- title,
- message,
- util::Timestamp()
- );
- if (notification)
- {
- user->addNotification(notification);
- }
- else
- {
- throw std::runtime_error("Failed to create notification");
- }
- }
+ return;
}
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers = m_dataStore.getInventoryManagementObservers();
+ if (m_observers.find(user->getId()) == -1)
+ {
+ return;
+ }
+ Notification* notification = Factory::getObject(
+ user->getId(),
+ title,
+ message,
+ util::Timestamp());
+ if (!notification)
+ {
+ throw std::runtime_error("Failed to create notification");
+ }
+ auto& trackedNotificationsMap = m_dataStore.getNotifications();
+ trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
+ m_dataStore.saveNotifications();
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
index f5db383..2c3736c 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
@@ -21,7 +21,6 @@ class InventoryManagementService : public NotificationManagementService
private:
DataStore& m_dataStore;
static util::Map m_observers;
- util::Vector getObserverIDs() override;
public:
InventoryManagementService() : m_dataStore(DataStore::getInstance()) {}
util::Map getInventoryItems();
@@ -33,8 +32,4 @@ 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();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp
deleted file mode 100644
index cc23059..0000000
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "NotificationManagementService.h"
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
index 33d214a..18d0dda 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
@@ -19,5 +19,4 @@ 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 getObserverIDs() = 0;
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
index 1fc1ff8..b8b9af1 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
@@ -11,7 +11,6 @@ Date: 20-May-2026
#include "Config.h"
#include "Enums.h"
#include "Factory.h"
-#include "FileManager.h"
#include "InventoryItem.h"
#include "Invoice.h"
#include "JobCard.h"
@@ -21,6 +20,7 @@ Date: 20-May-2026
#include "Timestamp.h"
#include "User.h"
#include "Utility.h"
+#include "DataStoreLockGuard.h"
util::Map PaymentManagementService::m_observers{};
@@ -34,6 +34,9 @@ Returns:
*/
void PaymentManagementService::attach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getPaymentManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -42,6 +45,7 @@ void PaymentManagementService::attach(User* user)
m_observers[userID] = user;
}
}
+ m_dataStore.savePaymentManagementObservers(m_observers);
}
/*
@@ -54,6 +58,9 @@ Returns:
*/
void PaymentManagementService::detach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getPaymentManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -62,6 +69,7 @@ void PaymentManagementService::detach(User* user)
m_observers.remove(userID);
}
}
+ m_dataStore.savePaymentManagementObservers(m_observers);
}
/*
@@ -78,28 +86,28 @@ Throws:
*/
void PaymentManagementService::sendNotification(User* user, const std::string& title, const std::string& message)
{
- if (user)
+ if (!user)
{
- if (m_observers.find(user->getId()) != -1)
- {
- Notification* notification =
- Factory::getObject(
- user->getId(),
- user,
- title,
- message,
- util::Timestamp()
- );
- if (notification)
- {
- user->addNotification(notification);
- }
- else
- {
- throw std::runtime_error("Failed to create notification");
- }
- }
+ return;
}
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers = m_dataStore.getPaymentManagementObservers();
+ if (m_observers.find(user->getId()) == -1)
+ {
+ return;
+ }
+ Notification* notification = Factory::getObject(
+ user->getId(),
+ title,
+ message,
+ util::Timestamp());
+ if (!notification)
+ {
+ throw std::runtime_error("Failed to create notification");
+ }
+ auto& trackedNotificationsMap = m_dataStore.getNotifications();
+ trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
+ m_dataStore.saveNotifications();
}
/*
@@ -140,123 +148,6 @@ void PaymentManagementService::sendPaymentReminders()
}
}
-/*
-Function: getObserverIDs
-Description: Retrieves the IDs of all observers currently attached to the
- PaymentManagementService.
-Parameters:
- - None
-Returns:
- - util::Vector: Vector of observer user IDs
-*/
-util::Vector PaymentManagementService::getObserverIDs()
-{
- util::Vector 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 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 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 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);
-}
-
/*
Function: createInventoryItemsMap (static helper)
Description: Builds a map of inventory items required for a given service and adds them to the booking’s inventory map.
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
index 8961a2d..f6e2e75 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
@@ -22,7 +22,6 @@ class PaymentManagementService : public NotificationManagementService
private:
DataStore& m_dataStore;
static util::Map m_observers;
- util::Vector getObserverIDs() override;
public:
PaymentManagementService() : m_dataStore(DataStore::getInstance()) {}
void generateInvoice(ServiceBooking* booking);
@@ -34,8 +33,4 @@ 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();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
index 1a9f753..e294249 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
@@ -14,7 +14,6 @@ Date:19-May-2026
#include "DataStore.h"
#include "Enums.h"
#include "Factory.h"
-#include "FileManager.h"
#include "InventoryItem.h"
#include "JobCard.h"
#include "NotificationManagementService.h"
@@ -26,6 +25,7 @@ Date:19-May-2026
#include "User.h"
#include "UserManagementService.h"
#include "Utility.h"
+#include "DataStoreLockGuard.h"
/*
Function: purchaseService
@@ -122,6 +122,9 @@ Returns:
*/
void ServiceManagementService::attach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getServiceManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -130,6 +133,7 @@ void ServiceManagementService::attach(User* user)
m_observers[userID] = user;
}
}
+ m_dataStore.saveServiceManagementObservers(m_observers);
}
/*
@@ -142,6 +146,9 @@ Returns:
*/
void ServiceManagementService::detach(User* user)
{
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers.clear();
+ m_observers = m_dataStore.getServiceManagementObservers();
if (user)
{
const std::string& userID = user->getId();
@@ -150,6 +157,7 @@ void ServiceManagementService::detach(User* user)
m_observers.remove(userID);
}
}
+ m_dataStore.saveServiceManagementObservers(m_observers);
}
/*
@@ -166,345 +174,28 @@ Throws:
*/
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,
- 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: Vector of observer user IDs
-*/
-util::Vector ServiceManagementService::getObserverIDs()
-{
- util::Vector 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 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++)
+ if (!user)
{
- Service* service = servicesMap.getValueAt(serviceIndex);
- services[service->getId()] = service;
- util::Map 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);
+ return;
}
-}
-
-/*
-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 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 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++)
+ DataStoreLockGuard lock(m_dataStore);
+ m_observers = m_dataStore.getServiceManagementObservers();
+ if (m_observers.find(user->getId()) == -1)
{
- ComboPackage* comboPackage = comboPackagesMap.getValueAt(packageIndex);
- util::Map 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;
+ return;
}
-}
-
-/*
-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 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 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++)
+ Notification* notification = Factory::getObject(
+ user->getId(),
+ title,
+ message,
+ util::Timestamp());
+ if (!notification)
{
- ServiceBooking* booking = bookingsMap.getValueAt(bookingIndex);
- util::Map 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;
+ throw std::runtime_error("Failed to create notification");
}
-}
-
-/*
-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 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 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 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);
+ auto& trackedNotificationsMap = m_dataStore.getNotifications();
+ trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification));
+ m_dataStore.saveNotifications();
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
index b2a4384..2fcfd6d 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
@@ -23,7 +23,6 @@ class ServiceManagementService : public NotificationManagementService
private:
DataStore& m_dataStore;
static util::Map m_observers;
- util::Vector getObserverIDs() override;
public:
ServiceManagementService() : m_dataStore(DataStore::getInstance()) {}
util::Map getServices();
@@ -45,14 +44,4 @@ 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();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
index 9b1c61c..e923e1c 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
@@ -11,7 +11,6 @@ Date:19-May-2026
#include "Config.h"
#include "Enums.h"
#include "Factory.h"
-#include "FileManager.h"
#include "InventoryManagementService.h"
#include "Notification.h"
#include "PaymentManagementService.h"
@@ -170,12 +169,16 @@ util::Vector UserManagementService::getUserNotifications(const st
User* user = trackedUsersMap[userID].data;
if (user)
{
- auto& notifications = user->getNotifications();
- int numberOfNotifications = notifications.getSize();
+ auto& trackedNotificationMap = m_dataStore.getNotifications();
+ int numberOfNotifications = trackedNotificationMap.getSize();
util::Vector notificationsVector;
for (int index = 0; index < numberOfNotifications; index++)
{
- notificationsVector.push_back(notifications.getValueAt(index));
+ Notification* notification = trackedNotificationMap.getValueAt(index).data;
+ if (notification->getRecipientUserId() == userID && notification->getState() == util::State::ACTIVE)
+ {
+ notificationsVector.push_back(notification);
+ }
}
return notificationsVector;
}
@@ -208,20 +211,18 @@ void UserManagementService::deleteNotification(const std::string& notificationID
{
throw std::runtime_error("No user found with given UserID");
}
- User* user = trackedUsersMap.getValueAt(userIndex).data;
- auto& notifications = user->getNotifications();
- if (notifications.find(notificationID) == -1)
- {
- throw std::runtime_error("No notification found with given NotificationID");
- }
int notificationIndex = trackedNotificationsMap.find(notificationID);
if (notificationIndex == -1)
{
throw std::runtime_error("No notification found with given NotificationID");
}
- notifications[notificationID]->setState(util::State::INACTIVE);
- trackedNotificationsMap.getValueAt(notificationIndex).state = RecordState::MODIFIED;
- m_dataStore.saveNotifications();
+ Notification* notification = trackedNotificationsMap.getValueAt(notificationIndex).data;
+ if (notification->getRecipientUserId() == userID)
+ {
+ notification->setState(util::State::INACTIVE);
+ trackedNotificationsMap.getValueAt(notificationIndex).state = RecordState::MODIFIED;
+ m_dataStore.saveNotifications();
+ }
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
index 2eef19d..a2995b4 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
@@ -29,6 +29,7 @@ namespace config
namespace file
{
const size_t INITIAL_CAPACITY = 100;
+ const size_t GROWTH_FACTOR = 2;
constexpr const char* DIRECTORY = "files/";
constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.dat";
constexpr const char* USER_FILE = "files/User.dat";
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
index c8bf96f..f73fba4 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
@@ -43,67 +43,4 @@ namespace util
position++;
}
}
-
- /*
- Function: loadRecords
- Description: Loads records from a given file path into a vector of strings.
- Skips the header line if present. Creates the file if it does not exist.
- Parameters:
- - filePath: const std::string&, path to the file
- Returns:
- - util::Vector: Vector containing all records (excluding header)
- Throws:
- - None (creates file if missing)
- */
- inline util::Vector loadRecords(const std::string& filePath)
- {
- util::Vector records;
- std::ifstream file(filePath);
- if (!file.is_open())
- {
- ensureDirectoryExists(filePath);
- std::ofstream newFile(filePath);
- newFile.close();
- file.open(filePath);
- }
- std::string line;
- bool isHeader = true;
- while (std::getline(file, line))
- {
- if (isHeader)
- {
- isHeader = false;
- continue;
- }
- records.push_back(line);
- }
- return records;
- }
-
- /*
- Function: saveRecords
- Description: Saves records to a given file path. Overwrites existing content
- and writes a header line followed by all records.
- Parameters:
- - filePath: const std::string&, path to the file
- - records: const util::Vector&, vector of records to save
- Returns:
- - void
- Throws:
- - std::runtime_error if the file cannot be opened for writing
- */
- inline void saveRecords(const std::string& filePath, const util::Vector& records)
- {
- std::ofstream file(filePath, std::ios::trunc);
- if (!file.is_open())
- {
- throw std::runtime_error("Failed to open file " + filePath);
- }
- file << "Values" << '\n';
- int numberOfRecords = records.getSize();
- for (int index = 0; index < numberOfRecords; index++)
- {
- file << records[index] << '\n';
- }
- }
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h
deleted file mode 100644
index 1ea66c7..0000000
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-File: FileManager.h
-Description: Declares and implements a generic FileManager template class for
- loading and saving objects to and from files. Uses serialization
- and deserialization methods defined in the object type T.
- Provides persistence support for system entities such as Users,
- Services, InventoryItems, etc.
-Author: Trenser
-Date: 22-May-2026
-*/
-
-#pragma once
-#include
-#include
-#include
-#include "Vector.h"
-#include "Map.h"
-#include "FileHelper.h"
-
-namespace util
-{
- template using objects = util::Map;
-
- template
- class FileManager
- {
- private:
- std::string m_filePath;
- public:
- FileManager() : m_filePath("") {}
- FileManager(const std::string& filePath) : m_filePath(filePath) {}
- objects load();
- void save(const objects&);
- };
-
- /*
- Function: load
- Description: Loads records from the file into a map of objects.
- Skips the header line, deserializes each record into an object of type T,
- and stores them in a map keyed by object ID.
- Parameters:
- - None
- Returns:
- - util::Map containing deserialized objects
- Throws:
- - std::runtime_error if deserialization fails for any record
- */
- template
- objects FileManager::load()
- {
- objects records;
- std::ifstream file(m_filePath);
- if (!file.is_open())
- {
- ensureDirectoryExists(m_filePath);
- std::ofstream newFile(m_filePath);
- newFile.close();
- file.open(m_filePath);
- }
- util::Vector lines;
- std::string line;
- while (std::getline(file, line))
- {
- lines.push_back(line);
- }
- int numberOfLines = lines.getSize();
- bool isHeader = true;
- for (int lineIndex = 0; lineIndex < numberOfLines; lineIndex++)
- {
- const auto& record = lines[lineIndex];
- if (isHeader)
- {
- isHeader = false;
- continue;
- }
- auto object = T::deserialize(record);
- if (!object)
- {
- throw std::runtime_error("Failed to deserialize record");
- }
- records[object->getId()] = object;
- }
- return records;
- }
-
- /*
- Function: save
- Description: Saves records to the file. Serializes each object of type T into a string,
- writes a header line, and then writes all serialized records to the file.
- Parameters:
- - records: const util::Map&, map of objects to save
- Returns:
- - void
- Throws:
- - std::runtime_error if the file cannot be opened for writing
- */
- template
- void FileManager::save(const objects& records)
- {
- util::Vector lines;
- lines.push_back(T::getHeaders());
- int numberOfRecords = records.getSize();
- for (int recordIndex = 0; recordIndex < numberOfRecords; recordIndex++)
- {
- const auto& record = records.getValueAt(recordIndex);
- lines.push_back(record->serialize());
- }
- std::ofstream file(m_filePath, std::ios::trunc);
- if (!file.is_open())
- {
- throw std::runtime_error("Failed to open file " + m_filePath);
- }
- int numberOfLines = lines.getSize();
- for (int lineIndex = 0; lineIndex < numberOfLines; lineIndex++)
- {
- file << lines[lineIndex] << '\n';
- }
- }
-}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
index dffc199..065a197 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
@@ -28,7 +28,7 @@ namespace util
if (!(std::cin >> value))
{
std::cin.clear();
- std::cin.ignore(std::numeric_limits::max(), '\n');
+ std::cin.ignore((std::numeric_limits::max)(), '\n');
throw std::runtime_error("Invalid console input");
}
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
index 9b6bc9d..56dd765 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
@@ -54,52 +54,6 @@ namespace util
return cost;
}
- /*
- Function: loadObservers
- Description: Loads observer IDs from a file and attaches the corresponding users
- to the notification management service. Validates that each observer ID
- exists in the datastore before attaching.
- Parameters:
- - filePath: const std::string&, path to the file containing observer IDs
- - service: NotificationManagementService*, pointer to the notification service
- - dataStore: DataStore&, reference to the datastore containing users
- Returns:
- - void
- Throws:
- - std::runtime_error if an observer ID is invalid (not found in datastore)
- */
- inline void loadObservers(const std::string& filePath, NotificationManagementService* service, DataStore& dataStore)
- {
- auto observerIDs = util::loadRecords(filePath);
- auto& users = dataStore.getUsers();
- for (int index = 0; index < observerIDs.getSize(); index++)
- {
- const std::string& observerID = observerIDs[index];
- int userIndex = users.find(observerID);
- if (userIndex == -1)
- {
- throw std::runtime_error("Invalid Observer ID");
- }
- service->attach(users.getValueAt(userIndex));
- }
- }
-
- /*
- Function: saveObservers
- Description: Saves the current observer IDs from the notification management service
- to a file for persistence.
- Parameters:
- - filePath: const std::string&, path to the file where observer IDs will be saved
- - service: NotificationManagementService*, pointer to the notification service
- Returns:
- - void
- */
- inline void saveObservers(const std::string& filePath, NotificationManagementService* service)
- {
- auto observerIDs = service->getObserverIDs();
- util::saveRecords(filePath, observerIDs);
- }
-
template
Map getObjects(const Map>& trackedRecords);