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/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
index 7e74b19..94301c4 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
@@ -278,5 +278,8 @@
Header Files\DataStores\SharedMemory
+
+ Header Files\DataStores
+
\ 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 1cade32..0f71bce 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
@@ -12,6 +12,8 @@ Date: 19-May-2026
#include "Config.h"
#include "SerializedRecords.h"
#include "FileHelper.h"
+#include "ServiceBooking.h"
+#include "JobCard.h"
/*
Function: DataStore
@@ -254,6 +256,28 @@ Returns:
*/
util::Map>& DataStore::getServices()
{
+ util::Map> services = loadRecords(m_services);
+ refreshCache(m_serviceCache, services);
+ util::Map>& inventoryItems = getInventoryItems();
+ size_t numberOfServices = m_serviceCache.getSize();
+ for (int iteratorOne =0; iteratorOne < numberOfServices; iteratorOne++)
+ {
+ Service* currentService = m_serviceCache.getValueAt(iteratorOne).data;
+ util::Map inventoryItemMap;
+ util::Vector currentServiceInventoryItem = currentService->getRequiredInventoryItemIDs();
+ for (int iteratorTwo = 0; iteratorTwo < currentServiceInventoryItem.getSize(); iteratorTwo++)
+ {
+ const std::string& currentInventoryItemId = currentServiceInventoryItem[iteratorTwo];
+ int currentInventoryItemIndex = inventoryItems.find(currentInventoryItemId);
+ if (currentInventoryItemIndex == -1)
+ {
+ throw std::runtime_error("Invalid inventory item ID");
+ }
+ InventoryItem* currentItem = inventoryItems.getValueAt(currentInventoryItemIndex).data;
+ inventoryItemMap[currentInventoryItemId] = currentItem;
+ }
+ currentService->setRequiredInventoryItems(inventoryItemMap);
+ }
return m_serviceCache;
}
@@ -267,6 +291,28 @@ Returns:
*/
util::Map>& DataStore::getComboPackages()
{
+ util::Map> comboPackages = loadRecords(m_comboPackages);
+ refreshCache(m_comboPackageCache, comboPackages);
+ util::Map>& services = getServices();
+ size_t numberOfComboPackages = m_comboPackageCache.getSize();
+ for (int iteratorOne = 0; iteratorOne < numberOfComboPackages; iteratorOne++)
+ {
+ ComboPackage* currentComboPackage = m_comboPackageCache.getValueAt(iteratorOne).data;
+ util::Vector currentServiceIds = currentComboPackage->getServiceIDs();
+ util::Map currentComboPackageServices;
+ for (int iteratorTwo = 0; iteratorTwo < currentServiceIds.getSize(); iteratorTwo++)
+ {
+ const std::string& currentServiceId = currentServiceIds[iteratorTwo];
+ int serviceIndex = services.find(currentServiceId);
+ if (serviceIndex == -1)
+ {
+ throw std::runtime_error("Invalid service ID");
+ }
+ Service* currentService = services.getValueAt(serviceIndex).data;
+ currentComboPackageServices[currentServiceId] = currentService;
+ }
+ currentComboPackage->setServices(currentComboPackageServices);
+ }
return m_comboPackageCache;
}
@@ -293,6 +339,49 @@ Returns:
*/
util::Map>& DataStore::getServiceBookings()
{
+ util::Map> serviceBookings = loadRecords(m_serviceBookings);
+ refreshCache(m_serviceBookingCache, serviceBookings);
+ auto& users = getUsers();
+ auto& services = getServices();
+ size_t numberOfServiceBookings = m_serviceBookingCache.getSize();
+ for (int iteratorOne = 0; iteratorOne < numberOfServiceBookings; iteratorOne++)
+ {
+ ServiceBooking* serviceBooking = m_serviceBookingCache.getValueAt(iteratorOne).data;
+ auto& serviceIds = serviceBooking->getServiceIDs();
+ util::Map servicesInBooking;
+ for (int iteratorTwo = 0; iteratorTwo < serviceIds.getSize(); iteratorTwo++)
+ {
+ const std::string& currentServiceId = serviceIds[iteratorTwo];
+ int serviceIndex = services.find(currentServiceId);
+ if (serviceIndex == -1)
+ {
+ throw std::runtime_error("Invalid service index.");
+ }
+ auto currentService = services.getValueAt(serviceIndex);
+ servicesInBooking[currentServiceId] = currentService.data;
+ }
+ serviceBooking->setServices(servicesInBooking);
+ if (!serviceBooking->getCustomerId().empty())
+ {
+ int userIndex = users.find(serviceBooking->getCustomerId());
+ if (userIndex == -1)
+ {
+ throw std::runtime_error("Invalid user index.");
+ }
+ auto customer = users.getValueAt(userIndex);
+ serviceBooking->setCustomer(customer.data);
+ }
+ if (!serviceBooking->getAssignedTechnicianId().empty())
+ {
+ int technicianIndex = users.find(serviceBooking->getAssignedTechnicianId());
+ if (technicianIndex == -1)
+ {
+ throw std::runtime_error("Invalid technician index.");
+ }
+ auto technician = users.getValueAt(technicianIndex);
+ serviceBooking->setAssignedTechnician(technician.data);
+ }
+ }
return m_serviceBookingCache;
}
@@ -306,9 +395,51 @@ Returns:
*/
util::Map>& DataStore::getJobCards()
{
+ util::Map> jobCards = loadRecords(m_jobCards);
+ refreshCache(m_jobCardCache, jobCards);
+ auto& serviceBookings = getServiceBookings();
+ auto& services = getServices();
+ auto& users = getUsers();
+ int numberOfJobCards = m_jobCardCache.getSize();
+ for (int iterator = 0; iterator < numberOfJobCards; iterator++)
+ {
+ JobCard* jobCard = m_jobCardCache.getValueAt(iterator).data;
+ if (!jobCard)
+ {
+ continue;
+ }
+ const std::string& bookingId = jobCard->getBookingId();
+ int bookingIndex = serviceBookings.find(bookingId);
+ if (bookingIndex == -1)
+ {
+ throw std::runtime_error("Invalid booking ID: " + bookingId);
+ }
+ auto trackedBooking = serviceBookings.getValueAt(bookingIndex);
+ jobCard->setBooking(trackedBooking.data);
+ const std::string& serviceId = jobCard->getServiceId();
+ int serviceIndex = services.find(serviceId);
+ if (serviceIndex == -1)
+ {
+ throw std::runtime_error("Invalid service ID: " + serviceId);
+ }
+ auto trackedService = services.getValueAt(serviceIndex);
+ jobCard->setService(trackedService.data);
+ const std::string& technicianId = jobCard->getTechnicianId();
+ if (!technicianId.empty())
+ {
+ int technicianIndex = users.find(technicianId);
+ if (technicianIndex == -1)
+ {
+ throw std::runtime_error("Invalid technician ID: " + technicianId);
+ }
+ auto trackedTechnician = users.getValueAt(technicianIndex);
+ jobCard->setTechnician(trackedTechnician.data);
+ }
+ }
return m_jobCardCache;
}
+
/*
Function: getInvoices
Description: Retrieves all invoice records from the datastore.
@@ -395,6 +526,7 @@ Returns:
*/
void DataStore::saveServices()
{
+ saveRecords(m_services, m_serviceCache);
}
/*
@@ -407,6 +539,7 @@ Returns:
*/
void DataStore::saveComboPackages()
{
+ saveRecords(m_comboPackages, m_comboPackageCache);
}
/*
@@ -431,6 +564,7 @@ Returns:
*/
void DataStore::saveServiceBookings()
{
+ saveRecords(m_serviceBookings, m_serviceBookingCache);
}
/*
@@ -443,6 +577,7 @@ Returns:
*/
void DataStore::saveJobCards()
{
+ saveRecords(m_jobCards, m_jobCardCache);
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
index 3950b11..cbfd5b3 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
@@ -11,6 +11,7 @@ Date: 19-May-2026
#include "Map.h"
#include "MappingInfo.h"
#include "TrackedRecord.h"
+#include "SerializedRecords.h"
#include "SharedMemory.h"
class User;
class Notification;
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/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
index 1a9f753..f372bef 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
@@ -25,6 +25,7 @@ Date:19-May-2026
#include "Timestamp.h"
#include "User.h"
#include "UserManagementService.h"
+#include "DataStoreLockGuard.h"
#include "Utility.h"
/*
@@ -46,18 +47,19 @@ void ServiceManagementService::purchaseService(const util::Vector&
{
throw std::runtime_error("No user is currently logged in!");
}
- auto& servicesMap = m_dataStore.getServices();
- auto& serviceBookingMap = m_dataStore.getServiceBookings();
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedServicesMap = m_dataStore.getServices();
+ auto& trackedServiceBookingMap = m_dataStore.getServiceBookings();
util::Map selectedServices;
int selectedServicesCount = serviceIDs.getSize();
for (int index = 0; index < selectedServicesCount; index++)
{
- int serviceIndex = servicesMap.find(serviceIDs[index]);
+ int serviceIndex = trackedServicesMap.find(serviceIDs[index]);
if (serviceIndex == -1)
{
throw std::runtime_error("Service not found!");
}
- Service* service = servicesMap.getValueAt(serviceIndex);
+ Service* service = trackedServicesMap.getValueAt(serviceIndex).data;
selectedServices[service->getId()] = service;
}
ServiceBooking* serviceBooking = Factory::getObject(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, 0);
@@ -65,7 +67,7 @@ void ServiceManagementService::purchaseService(const util::Vector&
{
throw std::runtime_error("Failed to create service booking");
}
- serviceBookingMap[serviceBooking->getId()] = serviceBooking;
+ trackedServiceBookingMap[serviceBooking->getId()] = util::createNewRecord(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);
@@ -90,21 +92,22 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack
{
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);
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedComboPackagesMap = m_dataStore.getComboPackages();
+ auto& trackedServiceBookingMap = m_dataStore.getServiceBookings();
+ int comboPackageIndex = trackedComboPackagesMap.find(comboPackageID);
if (comboPackageIndex == -1)
{
throw std::runtime_error("Combo Package not found!");
}
- const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
+ const ComboPackage* comboPackage = trackedComboPackagesMap[comboPackageID].data;
util::Map selectedServices = comboPackage->getServices();
ServiceBooking* serviceBooking = Factory::getObject(util::ServiceJobStatus::PENDING, 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;
+ trackedServiceBookingMap[serviceBooking->getId()] = util::createNewRecord(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);
@@ -514,7 +517,7 @@ Description: Restores inventory quantities for all required items in the service
Parameter: ServiceBooking* booking - Pointer to the booking whose inventory items need to be restored
Return type: void
*/
-static void restoreInventory(ServiceBooking* booking)
+static void restoreInventory(ServiceBooking* booking, util::Map>& trackedInventoryItems)
{
const int INCREMENT_VALUE = 1;
if (!booking)
@@ -533,9 +536,17 @@ static void restoreInventory(ServiceBooking* booking)
for (int InventoryIterator = 0; InventoryIterator < items.getSize(); ++InventoryIterator)
{
InventoryItem* item = items.getValueAt(InventoryIterator);
+ const std::string& currentItemId = item->getId();
+ int itemIndex = trackedInventoryItems.find(currentItemId);
+ if (itemIndex == -1)
+ {
+ continue;
+ }
+ auto& currentTrackedInventoryItem = trackedInventoryItems.getValueAt(itemIndex);
if (item)
{
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
+ currentTrackedInventoryItem.state = RecordState::MODIFIED;
}
}
}
@@ -553,23 +564,28 @@ Parameters:
util::UserType userType - Type of user initiating cancellation (CUSTOMER or TECHNICIAN)
Return type: void
*/
-static void processBookingCancellation(ServiceBooking* booking,
- util::Map& jobs,
+static void processBookingCancellation(TrackedRecord& trackedBooking,
+ util::Map>& jobs,
ServiceManagementService& currentService,
- util::UserType userType)
+ util::UserType userType,
+ util::Map>& trackedInventoryItems)
{
+ ServiceBooking* booking = trackedBooking.data;
if (!booking)
{
return;
}
+ const std::string& bookingId = booking->getId();
for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator)
{
- JobCard* jobCard = jobs.getValueAt(jobIterator);
+ auto& trackedJobCard = jobs.getValueAt(jobIterator);
+ JobCard* jobCard = trackedJobCard.data;
if (!jobCard || jobCard->getBookingId() != booking->getId() || jobCard->getStatus() == util::ServiceJobStatus::CANCELLED)
{
continue;
}
jobCard->setStatus(util::ServiceJobStatus::CANCELLED);
+ trackedJobCard.state = RecordState::MODIFIED;
if (userType == util::UserType::CUSTOMER)
{
if (User* technician = booking->getAssignedTechnician())
@@ -602,7 +618,8 @@ static void processBookingCancellation(ServiceBooking* booking,
}
booking->setAssignedTechnician(nullptr);
booking->setAssignedTechnicianId("");
- restoreInventory(booking);
+ trackedBooking.state = RecordState::MODIFIED;
+ restoreInventory(booking, trackedInventoryItems);
}
/*
@@ -615,22 +632,25 @@ Return type: void
*/
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& customerID)
{
- auto& users = m_dataStore.getUsers();
- int userIndex = users.find(customerID);
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedUsers = m_dataStore.getUsers();
+ int userIndex = trackedUsers.find(customerID);
if (userIndex == -1)
{
throw std::runtime_error("User not found: " + customerID);
}
- User* customer = users.getValueAt(userIndex);
+ User* customer = trackedUsers.getValueAt(userIndex).data;
if (!customer)
{
throw std::runtime_error("User not found: " + customerID);
}
- auto& bookings = m_dataStore.getServiceBookings();
- auto& jobs = m_dataStore.getJobCards();
- for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
+ auto& trackedBookings = m_dataStore.getServiceBookings();
+ auto& trackedJobs = m_dataStore.getJobCards();
+ auto& trackedInventoryItems = m_dataStore.getInventoryItems();
+ for (int iteratorOne = 0; iteratorOne < trackedBookings.getSize(); iteratorOne++)
{
- ServiceBooking* booking = bookings.getValueAt(iteratorOne);
+ auto& trackedBooking = trackedBookings.getValueAt(iteratorOne);
+ ServiceBooking* booking = trackedBooking.data;
if (!booking)
{
continue;
@@ -645,8 +665,12 @@ void ServiceManagementService::cancelCustomerServiceBookings(const std::string&
{
continue;
}
- processBookingCancellation(booking, jobs, *this, util::UserType::CUSTOMER);
+ processBookingCancellation(trackedBooking, trackedJobs, *this, util::UserType::CUSTOMER, trackedInventoryItems);
}
+ m_dataStore.saveUsers();
+ m_dataStore.saveServiceBookings();
+ m_dataStore.saveJobCards();
+ m_dataStore.saveInventoryItems();
}
/*
@@ -658,22 +682,25 @@ Return type: void
*/
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
{
- auto& users = m_dataStore.getUsers();
- int userIndex = users.find(technicianID);
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedUsers = m_dataStore.getUsers();
+ int userIndex = trackedUsers.find(technicianID);
if (userIndex == -1)
{
throw std::runtime_error("User not found: " + technicianID);
}
- User* technician = users.getValueAt(userIndex);
+ User* technician = trackedUsers.getValueAt(userIndex).data;
if (!technician)
{
throw std::runtime_error("User not found: " + technicianID);
}
- auto& bookings = m_dataStore.getServiceBookings();
- auto& jobs = m_dataStore.getJobCards();
- for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
+ auto& trackedBookings = m_dataStore.getServiceBookings();
+ auto& trackedJobs = m_dataStore.getJobCards();
+ auto& trackedInventoryItems = m_dataStore.getInventoryItems();
+ for (int iteratorOne = 0; iteratorOne < trackedBookings.getSize(); iteratorOne++)
{
- ServiceBooking* booking = bookings.getValueAt(iteratorOne);
+ auto& trackedBooking = trackedBookings.getValueAt(iteratorOne);
+ ServiceBooking* booking = trackedBooking.data;
if (!booking)
{
continue;
@@ -694,8 +721,12 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia
{
continue;
}
- processBookingCancellation(booking, jobs, *this, util::UserType::TECHNICIAN);
+ processBookingCancellation(trackedBooking, trackedJobs, *this, util::UserType::TECHNICIAN, trackedInventoryItems);
}
+ m_dataStore.saveUsers();
+ m_dataStore.saveInventoryItems();
+ m_dataStore.saveServiceBookings();
+ m_dataStore.saveJobCards();
}
/*
@@ -709,6 +740,7 @@ Return type: void
*/
void ServiceManagementService::createComboPackage(const std::string& packageName, const util::Vector& serviceIDsInNewCombo, double discountPercentage)
{
+ DataStoreLockGuard lock(m_dataStore);
if (packageName.empty())
{
throw std::invalid_argument("The Combo Package Name cannot be empty.\n");
@@ -721,19 +753,19 @@ void ServiceManagementService::createComboPackage(const std::string& packageName
{
throw std::invalid_argument("Discount percentage must be between 0 and 100.");
}
- auto& servicesMap = m_dataStore.getServices();
+ auto& trackedServicesMap = m_dataStore.getServices();
for (int index = 0; index < serviceIDsInNewCombo.getSize(); index++)
{
- const std::string serviceid = serviceIDsInNewCombo[index];
- if (servicesMap.find(serviceid) == -1)
+ const std::string& serviceid = serviceIDsInNewCombo[index];
+ if (trackedServicesMap.find(serviceid) == -1)
{
throw std::runtime_error("Service ID not found: " + serviceid);
}
}
- auto& comboPackageMap = m_dataStore.getComboPackages();
- for (int iterator = 0; iterator < comboPackageMap.getSize(); iterator++)
+ auto& trackedComboPackageMap = m_dataStore.getComboPackages();
+ for (int iterator = 0; iterator < trackedComboPackageMap.getSize(); iterator++)
{
- ComboPackage* existingCombos = comboPackageMap.getValueAt(iterator);
+ ComboPackage* existingCombos = trackedComboPackageMap.getValueAt(iterator).data;
const util::Map& servicesInsideExistingCombos = existingCombos->getServices();
if (servicesInsideExistingCombos.getSize() == serviceIDsInNewCombo.getSize())
{
@@ -757,15 +789,16 @@ void ServiceManagementService::createComboPackage(const std::string& packageName
for (int iteratorOne = 0; iteratorOne < serviceIDsInNewCombo.getSize(); iteratorOne++)
{
const std::string& serviceId = serviceIDsInNewCombo[iteratorOne];
- int serviceIndex = servicesMap.find(serviceId);
+ int serviceIndex = trackedServicesMap.find(serviceId);
if (serviceIndex == -1)
{
throw std::runtime_error("Service ID not found: " + serviceId);
}
- selectedServices.insert(serviceId, servicesMap.getValueAt(serviceIndex));
+ selectedServices.insert(serviceId, trackedServicesMap.getValueAt(serviceIndex).data);
}
ComboPackage* newComboPackage = Factory::getObject(packageName, discountPercentage, selectedServices);
- comboPackageMap.insert(newComboPackage->getId(), newComboPackage);
+ trackedComboPackageMap.insert(newComboPackage->getId(), util::createNewRecord(newComboPackage));
+ m_dataStore.saveComboPackages();
}
/*
@@ -776,7 +809,10 @@ Return type: util::Map
*/
util::Map ServiceManagementService::getComboPackages()
{
- return m_dataStore.getComboPackages();
+ DataStoreLockGuard lock(m_dataStore);
+ util::Map comboPackages;
+ comboPackages = util::getObjects(m_dataStore.getComboPackages());
+ return comboPackages;
}
/*
@@ -787,14 +823,17 @@ Return type: void
*/
void ServiceManagementService::removeComboPackage(const std::string& comboPackageID)
{
+ DataStoreLockGuard lock(m_dataStore);
bool removed = false;
- util::Map& currentComboPackages = m_dataStore.getComboPackages();
- for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
+ auto& trackedComboPackages = m_dataStore.getComboPackages();
+ for (int iterator = 0; iterator < trackedComboPackages.getSize(); iterator++)
{
- ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
+ auto& comboPackage = trackedComboPackages.getValueAt(iterator);
+ ComboPackage* currentComboPackage = comboPackage.data;
if (currentComboPackage && currentComboPackage->getId() == comboPackageID)
{
currentComboPackage->setState(util::State::INACTIVE);
+ comboPackage.state = RecordState::MODIFIED;
removed = true;
break;
}
@@ -803,6 +842,7 @@ void ServiceManagementService::removeComboPackage(const std::string& comboPackag
{
throw std::runtime_error("Combo package with ID '" + comboPackageID + "' not found.");
}
+ m_dataStore.saveComboPackages();
}
/*
@@ -815,7 +855,9 @@ Returns:
*/
util::Map ServiceManagementService::getServiceBookings()
{
- return m_dataStore.getServiceBookings();
+ DataStoreLockGuard lock(m_dataStore);
+ util::Map serviceBookings;
+ serviceBookings = util::getObjects(m_dataStore.getServiceBookings());
}
/*
@@ -856,7 +898,8 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
{
UserManagementService m_userManagementService;
ServiceBooking* currentBooking = getServiceBooking(bookingID);
- auto& currentJobCards = m_dataStore.getJobCards();
+ DataStoreLockGuard lock(m_dataStore);
+ auto& currentTrackedJobCards = m_dataStore.getJobCards();
if (currentBooking == nullptr)
{
throw std::runtime_error("Service Booking not available");
@@ -902,7 +945,7 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
JobCard* jobCard = Factory::getObject(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
if (jobCard)
{
- currentJobCards.insert(jobCard->getId(), jobCard);
+ currentTrackedJobCards.insert(jobCard->getId(), util::createNewRecord(jobCard));
sendNotification(selectedTechnician, title, message);
}
else
@@ -930,14 +973,15 @@ Throws:
void ServiceManagementService::createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost)
{
util::Map currentServiceInventoryItems;
- auto inventoryItems = m_dataStore.getInventoryItems();
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedInventoryItems = m_dataStore.getInventoryItems();
for (int iteratorOne =0; iteratorOne < inventoryItemIDs.getSize(); iteratorOne++)
{
std::string currentItemID = inventoryItemIDs[iteratorOne];
bool itemFound = false;
- for (int iteratorTwo = 0; iteratorTwo < inventoryItems.getSize(); iteratorTwo++)
+ for (int iteratorTwo = 0; iteratorTwo < trackedInventoryItems.getSize(); iteratorTwo++)
{
- InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iteratorTwo);
+ InventoryItem* currentInventoryItem = trackedInventoryItems.getValueAt(iteratorTwo).data;
if (currentInventoryItem && currentInventoryItem->getId() == currentItemID)
{
itemFound = true;
@@ -955,12 +999,12 @@ void ServiceManagementService::createService(const std::string& name, const util
{
throw std::runtime_error("Unable to create new service.");
}
- util::Map& currentServices = m_dataStore.getServices();
+ auto& currentServices = m_dataStore.getServices();
if (currentServices.find(newService->getId()) != -1)
{
throw std::runtime_error("Service with this ID Already exists.");
}
- currentServices.insert(newService->getId(), newService);
+ currentServices.insert(newService->getId(), util::createNewRecord(newService));
}
/*
@@ -973,7 +1017,10 @@ Returns:
*/
util::Map ServiceManagementService::getServices()
{
- return m_dataStore.getServices();
+ DataStoreLockGuard lock(m_dataStore);
+ util::Map services;
+ services = util::getObjects(m_dataStore.getServices());
+ return services;
}
/*
@@ -988,14 +1035,19 @@ Throws:
*/
void ServiceManagementService::removeService(const std::string& serviceID)
{
- util::Map& currentServices = m_dataStore.getServices();
- util::Map& currentComboPackages = m_dataStore.getComboPackages();
- if (currentServices.find(serviceID) != -1)
+ DataStoreLockGuard lock(m_dataStore);
+ auto& currentTrackedServices = m_dataStore.getServices();
+ auto& currentTrackedComboPackages = m_dataStore.getComboPackages();
+ if (currentTrackedServices.find(serviceID) != -1)
{
- currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE);
- for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
+ int serviceIndex, comboPackageIndex;
+ serviceIndex = currentTrackedServices.find(serviceID);
+ currentTrackedServices.getValueAt(serviceIndex).data->setState(util::State::INACTIVE);
+ currentTrackedServices.getValueAt(serviceIndex).state = RecordState::MODIFIED;
+ for (int iterator = 0; iterator < currentTrackedComboPackages.getSize(); iterator++)
{
- ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
+ comboPackageIndex = iterator;
+ ComboPackage* currentComboPackage = currentTrackedComboPackages.getValueAt(iterator).data;
if (currentComboPackage && currentComboPackage->getState() == util::State::ACTIVE)
{
util::Map currentServices = currentComboPackage->getServices();
@@ -1005,6 +1057,7 @@ void ServiceManagementService::removeService(const std::string& serviceID)
if (currentService->getId() == serviceID)
{
currentComboPackage->setState(util::State::INACTIVE);
+ currentTrackedComboPackages.getValueAt(comboPackageIndex).state = RecordState::MODIFIED;
break;
}
}
@@ -1015,6 +1068,8 @@ void ServiceManagementService::removeService(const std::string& serviceID)
{
throw std::runtime_error("Service not found.");
}
+ m_dataStore.saveServices();
+ m_dataStore.saveComboPackages();
}
/*
@@ -1053,11 +1108,12 @@ Returns:
*/
util::Map ServiceManagementService::getJobCards(const std::string& technicianID)
{
- util::Map jobCards = m_dataStore.getJobCards();
+ DataStoreLockGuard lock(m_dataStore);
+ auto& trackedJobCards = m_dataStore.getJobCards();
util::Map technicianJobCards;
- for (int iterator = 0; iterator < jobCards.getSize(); iterator++)
+ for (int iterator = 0; iterator < trackedJobCards.getSize(); iterator++)
{
- JobCard* currentJobCard = jobCards.getValueAt(iterator);
+ JobCard* currentJobCard = trackedJobCards.getValueAt(iterator).data;
if (currentJobCard->getTechnicianId() == technicianID)
{
technicianJobCards.insert(currentJobCard->getId(), currentJobCard);
@@ -1106,6 +1162,7 @@ Returns:
*/
void ServiceManagementService::updateJobStatus(const std::string& jobID)
{
+ DataStoreLockGuard lock(m_dataStore);
AuthenticationManagementService authenticationManagementService;
PaymentManagementService paymentManagementService;
bool jobStatusUpdated = false, serviceBookingCompleted;
@@ -1120,8 +1177,15 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
{
throw std::runtime_error("No job cards assigned to the technician.");
}
+ auto& trackedJobCards = m_dataStore.getJobCards();
+ auto& trackedServiceBookings = m_dataStore.getServiceBookings();
if (currentAssignedJobs.find(jobID) != -1)
{
+ int jobIndex = trackedJobCards.find(jobID);
+ if (jobIndex == -1)
+ {
+ throw std::runtime_error("Unable to fetch current job.");
+ }
currentJob = currentAssignedJobs.getValueAt(currentAssignedJobs.find(jobID));
if (currentJob == nullptr)
{
@@ -1130,16 +1194,20 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
{
currentJob->setStatus(util::ServiceJobStatus::IN_PROGRESS);
+ trackedJobCards.getValueAt(jobIndex).state = RecordState::MODIFIED;
jobStatusUpdated = true;
}
else if (currentJob->getStatus() == util::ServiceJobStatus::IN_PROGRESS)
{
currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
+ trackedJobCards.getValueAt(jobIndex).state = RecordState::MODIFIED;
jobStatusUpdated = true;
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
if (serviceBookingCompleted)
{
+ const std::string& bookingId = currentJob->getBookingId();
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
+ trackedServiceBookings.getValueAt(trackedServiceBookings.find(bookingId)).state = RecordState::MODIFIED;
paymentManagementService.generateInvoice(currentJob->getBooking());
std::string title = "Service Booking completed. Invoice Generated.";
std::string message = "Services completed for the booking and invoice generated.";
@@ -1155,4 +1223,6 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
{
throw std::runtime_error("Failed to update job status. Job may already be completed.");
}
+ m_dataStore.saveJobCards();
+ m_dataStore.saveServiceBookings();
}
\ No newline at end of file