diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
index 6a269f5..7c4bfd3 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
@@ -157,6 +157,7 @@
+
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
index 1cade32..a7d41d9 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
@@ -228,6 +228,22 @@ Returns:
*/
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;
}
@@ -280,6 +296,8 @@ Returns:
*/
util::Map>& DataStore::getInventoryItems()
{
+ auto inventoryItems = loadRecords(m_inventoryItems);
+ refreshCache(m_inventoryItemCache, inventoryItems);
return m_inventoryItemCache;
}
@@ -419,6 +437,7 @@ Returns:
*/
void DataStore::saveInventoryItems()
{
+ saveRecords(m_inventoryItems, m_inventoryItemCache);
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h
new file mode 100644
index 0000000..2e04eb0
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h
@@ -0,0 +1,28 @@
+/*
+File: DataStoreLockGuard.h
+Description: Defines the DataStoreLockGuard class used to manage DataStore
+ locking and unlocking automatically within a scope.
+Author: Trenser
+Date: 12-June-2026
+*/
+
+#pragma once
+#include "DataStore.h"
+
+class DataStoreLockGuard
+{
+public:
+ explicit DataStoreLockGuard(DataStore& dataStore)
+ : m_dataStore(dataStore)
+ {
+ m_dataStore.lockDataStore();
+ }
+ ~DataStoreLockGuard()
+ {
+ m_dataStore.unlockDataStore();
+ }
+ DataStoreLockGuard(const DataStoreLockGuard&) = delete;
+ DataStoreLockGuard& operator=(const DataStoreLockGuard&) = delete;
+private:
+ DataStore& m_dataStore;
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
index d08d957..bdc4e39 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
@@ -19,7 +19,7 @@ Date: 22-May-2026
#include "User.h"
#include "Utility.h"
#include "Vector.h"
-
+#include "DataStoreLockGuard.h"
util::Map InventoryManagementService::m_observers{};
@@ -58,18 +58,19 @@ Returns:
*/
void InventoryManagementService::sendLowStockAlerts()
{
- auto& inventoryItems = m_dataStore.getInventoryItems();
- if (inventoryItems.isEmpty())
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemsMap = m_dataStore.getInventoryItems();
+ auto& trackedUserMap = m_dataStore.getUsers();
+ if (trackedInventoryItemsMap.isEmpty())
{
return;
}
- int inventoryItemsSize = inventoryItems.getSize();
- auto& usersMap = m_dataStore.getUsers();
- int usersMapSize = usersMap.getSize();
+ int inventoryItemsSize = trackedInventoryItemsMap.getSize();
+ int usersMapSize = trackedUserMap.getSize();
util::Vector adminUsers;
for (int index = 0; index < usersMapSize; index++)
{
- User* user = usersMap.getValueAt(index);
+ User* user = trackedUserMap.getValueAt(index).data;
if (user->getUserType() == util::UserType::ADMIN)
{
adminUsers.push_back(user);
@@ -82,7 +83,7 @@ void InventoryManagementService::sendLowStockAlerts()
}
for (int index = 0; index < inventoryItemsSize; index++)
{
- InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
+ InventoryItem* inventoryItem = trackedInventoryItemsMap.getValueAt(index).data;
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
{
sendLowStockAlertsToAdmins(*this, inventoryItem, adminUsers);
@@ -90,95 +91,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
@@ -190,8 +102,11 @@ Return type: void
*/
void InventoryManagementService::addInventoryItem(const std::string& partName, int quantity, double price)
{
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
InventoryItem* newItem = Factory::getObject(partName, quantity, price);
- m_dataStore.getInventoryItems().insert(newItem->getId(), newItem);
+ trackedInventoryItemMap.insert(newItem->getId(), util::createNewRecord(newItem));
+ m_dataStore.saveInventoryItems();
}
/*
@@ -203,16 +118,22 @@ Return type: void
*/
void InventoryManagementService::addInventoryItemStock(const std::string& selectedItemId, int quantity)
{
- int index = m_dataStore.getInventoryItems().find(selectedItemId);
- if (index != -1)
- {
- InventoryItem* item = m_dataStore.getInventoryItems().getValueAt(index);
- if (item != nullptr)
- {
- int totalQuantity = item->getQuantity() + quantity;
- item->setQuantity(totalQuantity);
- }
- }
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
+ int index = trackedInventoryItemMap.find(selectedItemId);
+ if (index == -1)
+ {
+ throw std::runtime_error("Inventory update failed: Item ID '" + selectedItemId + "' not found.");
+ }
+ InventoryItem* item = trackedInventoryItemMap.getValueAt(index).data;
+ if (item == nullptr)
+ {
+ throw std::runtime_error("Inventory update failed. Item does not exist.\n");
+ }
+ int totalQuantity = item->getQuantity() + quantity;
+ item->setQuantity(totalQuantity);
+ trackedInventoryItemMap.getValueAt(index).state = RecordState::MODIFIED;
+ m_dataStore.saveInventoryItems();
}
/*
@@ -223,7 +144,10 @@ Return type: util::Map
*/
util::Map InventoryManagementService::getInventoryItems()
{
- return m_dataStore.getInventoryItems();
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
+ auto inventoryMap = util::getObjects(trackedInventoryItemMap);
+ return inventoryMap;
}
/*
@@ -234,15 +158,21 @@ Return type: void
*/
void InventoryManagementService::removeInventoryItem(const std::string& inventoryItemID)
{
- int index = m_dataStore.getInventoryItems().find(inventoryItemID);
- if (index != -1)
- {
- InventoryItem* item = m_dataStore.getInventoryItems().getValueAt(index);
- if (item != nullptr)
- {
- item->setState(util::State::INACTIVE);
- }
- }
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
+ int index = trackedInventoryItemMap.find(inventoryItemID);
+ if (index == -1)
+ {
+ throw std::runtime_error("Inventory removal failed: Item ID '" + inventoryItemID + "' not found.");
+ }
+ InventoryItem* item = trackedInventoryItemMap.getValueAt(index).data;
+ if (item == nullptr)
+ {
+ throw std::runtime_error("Inventory removal failed: Item ID does not exist.");
+ }
+ item->setState(util::State::INACTIVE);
+ trackedInventoryItemMap.getValueAt(index).state = RecordState::MODIFIED;
+ m_dataStore.saveInventoryItems();
}
/*
@@ -253,12 +183,19 @@ Return type: InventoryItem*
*/
InventoryItem* InventoryManagementService::getInventoryItem(const std::string& inventoryItemID)
{
- int index = m_dataStore.getInventoryItems().find(inventoryItemID);
- if (index != -1)
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
+ int index = trackedInventoryItemMap.find(inventoryItemID);
+ if (index == -1)
{
- return m_dataStore.getInventoryItems().getValueAt(index);
+ return nullptr;
}
- return nullptr;
+ InventoryItem* inventoryItem = trackedInventoryItemMap.getValueAt(index).data;
+ if (inventoryItem == nullptr)
+ {
+ throw std::runtime_error("Item ID does not exist.");
+ }
+ return inventoryItem;
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
index f5db383..bb7cda1 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
@@ -33,8 +33,6 @@ 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();
};