diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
index 063f776..8627061 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
@@ -173,9 +173,12 @@
+
+
+
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
index c72bd44..73b9291 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
@@ -233,6 +233,21 @@
Header Files\Models
+
+ Header Files\Utilities
+
+
+ Header Files\Utilities
+
+
+ Header Files\Utilities
+
+
+ Header Files\Utilities
+
+
+ Header Files\Utilities
+
Header Files\Views
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
index e6ead9e..b0c4802 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
@@ -288,6 +288,54 @@ void Controller::configureNotifications(bool paymentNotifications, bool serviceN
}
}
+/*
+Function: loadSystemData
+Description: Loads all system data from persistent storage into memory.
+ Invokes the respective management services to load users, inventory items, services,
+ combo packages, service bookings, job cards, invoices, and observers.
+Parameters:
+ - None
+Returns:
+ - void
+*/
+void Controller::loadSystemData()
+{
+ m_userManagementService.loadUsers();
+ m_inventoryManagementService.loadInventoryItems();
+ m_serviceManagementService.loadServices();
+ m_serviceManagementService.loadComboPackages();
+ m_serviceManagementService.loadServiceBookings();
+ m_serviceManagementService.loadJobCards();
+ m_paymentManagementService.loadInvoices();
+ m_serviceManagementService.loadObservers();
+ m_paymentManagementService.loadObservers();
+ m_inventoryManagementService.loadObservers();
+}
+
+/*
+Function: saveSystemData
+Description: Saves all system data from memory back to persistent storage.
+ Invokes the respective management services to save users, inventory items, services,
+ combo packages, service bookings, job cards, invoices, and observers.
+Parameters:
+ - None
+Returns:
+ - void
+*/
+void Controller::saveSystemData()
+{
+ m_userManagementService.saveUsers();
+ m_inventoryManagementService.saveInventoryItems();
+ m_serviceManagementService.saveServices();
+ m_serviceManagementService.saveComboPackages();
+ m_serviceManagementService.saveServiceBookings();
+ m_serviceManagementService.saveJobCards();
+ m_paymentManagementService.saveInvoices();
+ m_serviceManagementService.saveObservers();
+ m_paymentManagementService.saveObservers();
+ m_inventoryManagementService.saveObservers();
+}
+
/*
Function: runSystemChecks
Description: Runs system checks to ensure critical configurations, such as verifying admin existence.
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h
index 9139d5d..1b534ea 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h
@@ -15,6 +15,10 @@ Date:19-May-2026
#include "PaymentManagementService.h"
#include "ServiceManagementService.h"
#include "UserManagementService.h"
+#include "InventoryManagementService.h"
+#include "UserManagementService.h"
+#include "ServiceManagementService.h"
+#include "PaymentManagementService.h"
class Service;
class ComboPackage;
@@ -66,5 +70,7 @@ public:
util::Vector getNotifications();
void deleteNotification(const std::string& notificationID);
void configureNotifications(bool paymentNotifications, bool serviceNotifications);
+ void loadSystemData();
+ void saveSystemData();
void runSystemChecks();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Subject.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Subject.h
index 4cfe5ce..09b8ac3 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Subject.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Subject.h
@@ -8,6 +8,7 @@ Date: 19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
class User;
class Notification;
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/files/README.md b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/files/README.md
new file mode 100644
index 0000000..6e6b93e
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/files/README.md
@@ -0,0 +1 @@
+Place files here.
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.cpp
index 41e75d0..4e69d9f 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.cpp
@@ -7,7 +7,12 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
+#include
#include "ComboPackage.h"
+#include "Service.h"
+#include "Factory.h"
+#include "StringHelper.h"
int ComboPackage::m_uid = 0;
@@ -41,7 +46,42 @@ ComboPackage::ComboPackage(const std::string& packageName, double discountPercen
m_packageName(packageName),
m_discountPercentage(discountPercentage),
m_status(util::State::ACTIVE),
- m_services(services) {}
+ m_services(services)
+{
+ int numberOfServices = m_services.getSize();
+ auto servicePointers = m_services.getValues();
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ m_serviceIDs.push_back(servicePointers[index]->getId());
+ }
+}
+
+/*
+Function: ComboPackage (parameterized constructor with ID)
+Description: Initializes a combo package with an existing ID, name, discount percentage,
+ service IDs, and state. Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique ID of the package
+ - packageName: const std::string&, name of the package
+ - discountPercentage: double, discount percentage applied
+ - serviceIDs: const util::Vector&, IDs of services included
+ - status: util::State, state of the package (ACTIVE/INACTIVE)
+Returns:
+ - A new ComboPackage object
+*/
+ComboPackage::ComboPackage(const std::string& id, const std::string& packageName, double discountPercentage, const util::Vector& serviceIDs, util::State status)
+ : m_id(id),
+ m_packageName(packageName),
+ m_discountPercentage(discountPercentage),
+ m_serviceIDs(serviceIDs),
+ m_status(status)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
/*
Function: getId
@@ -95,6 +135,11 @@ util::State ComboPackage::getState() const
return m_status;
}
+const util::Vector& ComboPackage::getServiceIDs() const
+{
+ return m_serviceIDs;
+}
+
/*
Function: getServices
Description: Retrieves the map of services included in the combo package.
@@ -158,6 +203,13 @@ Returns:
void ComboPackage::setServices(const util::Map& services)
{
m_services = services;
+ m_serviceIDs.clear();
+ int numberOfServices = m_services.getSize();
+ auto servicePointers = m_services.getValues();
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ m_serviceIDs.push_back(servicePointers[index]->getId());
+ }
}
/*
@@ -172,3 +224,118 @@ void ComboPackage::setState(util::State status)
{
m_status = status;
}
+
+/*
+Function: getServiceIDsAsString (static helper)
+Description: Converts a vector of service IDs into a single string separated by '|'.
+Parameters:
+ - serviceIDs: const util::Vector&, vector of service IDs
+Returns:
+ - std::string: Concatenated service IDs string
+*/
+static std::string getServiceIDsAsString(const util::Vector& serviceIDs)
+{
+ int numberOfServices = serviceIDs.getSize();
+ std::string serviceIDsString;
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ serviceIDsString += serviceIDs[index];
+ if (index < numberOfServices - 1)
+ {
+ serviceIDsString += '|';
+ }
+ }
+ return serviceIDsString;
+}
+
+/*
+Function: getServiceIDsAsVector (static helper)
+Description: Converts a string of service IDs separated by '|' into a vector.
+Parameters:
+ - serviceIDsString: const std::string&, concatenated service IDs string
+Returns:
+ - util::Vector: Vector of service IDs
+*/
+static util::Vector getServiceIDsAsVector(const std::string& serviceIDsString)
+{
+ util::Vector serviceIDs;
+ std::string serviceID;
+ std::istringstream serializedServiceIDs(serviceIDsString);
+ while (getline(serializedServiceIDs, serviceID, '|'))
+ {
+ serviceIDs.push_back(serviceID);
+ }
+ return serviceIDs;
+}
+
+/*
+Function: serialize
+Description: Serializes the combo package into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized combo package record
+*/
+std::string ComboPackage::serialize() const
+{
+ std::ostringstream serializedComboPackage;
+ serializedComboPackage << m_id << ','
+ << m_packageName << ','
+ << m_discountPercentage << ','
+ << getServiceIDsAsString(m_serviceIDs) << ','
+ << util::getStateString(m_status);
+ return serializedComboPackage.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a ComboPackage object.
+Parameters:
+ - record: const std::string&, serialized combo package record
+Returns:
+ - ComboPackage*: Pointer to the deserialized ComboPackage object
+Throws:
+ - std::runtime_error if data is invalid
+*/
+ComboPackage* ComboPackage::deserialize(const std::string& record)
+{
+ std::string id, packageName;
+ std::string discountPercentageString, serviceIDsString, statusString;
+ double discountPercentage;
+ std::istringstream serializedComboPackage(record);
+ getline(serializedComboPackage, id, ',');
+ getline(serializedComboPackage, packageName, ',');
+ getline(serializedComboPackage, discountPercentageString, ',');
+ getline(serializedComboPackage, serviceIDsString, ',');
+ getline(serializedComboPackage, statusString, ',');
+ try
+ {
+ discountPercentage = std::stod(discountPercentageString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid combo package data");
+ }
+ util::Vector serviceIDs = getServiceIDsAsVector(serviceIDsString);
+ util::State status = util::getState(statusString);
+ return Factory::getObject(
+ id,
+ packageName,
+ discountPercentage,
+ serviceIDs,
+ status
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for combo package serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,PackageName,DiscountPercentage,ServiceIDs,Status")
+*/
+std::string ComboPackage::getHeaders()
+{
+ return "ID,PackageName,DiscountPercentage,ServiceIDs,Status";
+}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
index a620ee4..941c2b3 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ComboPackage.h
@@ -8,6 +8,7 @@ Date: 19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
#include "Enums.h"
class Service;
@@ -19,14 +20,17 @@ private:
std::string m_id;
std::string m_packageName;
double m_discountPercentage;
+ util::Vector m_serviceIDs;
util::Map m_services;
util::State m_status;
public:
ComboPackage();
ComboPackage(const std::string& packageName, double discountPercentage, const util::Map& services);
+ ComboPackage(const std::string& id, const std::string& packageName, double discountPercentage, const util::Vector& serviceIDs, util::State status);
const std::string& getId() const;
const std::string& getPackageName() const;
double getDiscountPercentage() const;
+ const util::Vector& getServiceIDs() const;
const util::Map& getServices() const;
util::State getState() const;
void setId(const std::string& id);
@@ -34,4 +38,7 @@ public:
void setDiscountPercentage(double discountPercentage);
void setServices(const util::Map& services);
void setState(util::State status);
+ std::string serialize() const;
+ static ComboPackage* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.cpp
index edc8654..f34b8a5 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.cpp
@@ -6,6 +6,10 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
+#include
+#include "Factory.h"
+#include "StringHelper.h"
#include "InventoryItem.h"
int InventoryItem::m_uid = 0;
@@ -43,6 +47,33 @@ InventoryItem::InventoryItem(const std::string& partName, int quantity, double p
m_status(util::State::ACTIVE),
m_price(price) {}
+/*
+Function: InventoryItem (parameterized constructor with ID)
+Description: Initializes an inventory item with an existing ID, part name, quantity,
+ price, and state. Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique ID of the item
+ - partName: const std::string&, name of the part
+ - quantity: int, quantity of the part
+ - price: double, price of the part
+ - status: util::State, state of the item (ACTIVE/INACTIVE)
+Returns:
+ - A new InventoryItem object
+*/
+InventoryItem::InventoryItem(const std::string& id, const std::string& partName, int quantity, double price, util::State status)
+ : m_id(id),
+ m_partName(partName),
+ m_quantity(quantity),
+ m_status(status),
+ m_price(price)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
+
/*
Function: getId
Description: Retrieves the unique ID of the inventory item.
@@ -171,4 +202,77 @@ Returns:
void InventoryItem::setState(util::State status)
{
m_status = status;
+}
+
+/*
+Function: serialize
+Description: Serializes the inventory item into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized inventory item record
+*/
+std::string InventoryItem::serialize() const
+{
+ std::ostringstream serializedInventoryItem;
+ serializedInventoryItem << m_id << ','
+ << m_partName << ','
+ << m_quantity << ','
+ << m_price << ','
+ << util::getStateString(m_status);
+ return serializedInventoryItem.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into an InventoryItem object.
+Parameters:
+ - record: const std::string&, serialized inventory item record
+Returns:
+ - InventoryItem*: Pointer to the deserialized InventoryItem object
+Throws:
+ - std::runtime_error if data is invalid
+*/
+InventoryItem* InventoryItem::deserialize(const std::string& record)
+{
+ std::string id, partName;
+ std::string quantityString, priceString, statusString;
+ int quantity;
+ double price;
+ std::istringstream serializedInventoryItem(record);
+ getline(serializedInventoryItem, id, ',');
+ getline(serializedInventoryItem, partName, ',');
+ getline(serializedInventoryItem, quantityString, ',');
+ getline(serializedInventoryItem, priceString, ',');
+ getline(serializedInventoryItem, statusString, ',');
+ try
+ {
+ quantity = std::stoi(quantityString);
+ price = std::stod(priceString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid inventory item data");
+ }
+ util::State status = util::getState(statusString);
+ return Factory::getObject(
+ id,
+ partName,
+ quantity,
+ price,
+ status
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for inventory item serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,PartName,Quantity,Price,Status")
+*/
+std::string InventoryItem::getHeaders()
+{
+ return "ID,PartName,Quantity,Price,Status";
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.h
index 0cb36ac..5808e8f 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/InventoryItem.h
@@ -23,6 +23,7 @@ private:
public:
InventoryItem();
InventoryItem(const std::string& partName, int quantity, double price);
+ InventoryItem(const std::string& id, const std::string& partName, int quantity, double price, util::State status);
const std::string& getId() const;
const std::string& getPartName() const;
int getQuantity() const;
@@ -33,4 +34,7 @@ public:
void setQuantity(int quantity);
void setPrice(double price);
void setState(util::State status);
+ std::string serialize() const;
+ static InventoryItem* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.cpp
index 7c06e5b..d1dc0c4 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.cpp
@@ -7,7 +7,12 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
+#include
#include "Invoice.h"
+#include "Factory.h"
+#include "InventoryItem.h"
+#include "StringHelper.h"
int Invoice::m_uid = 0;
@@ -53,7 +58,7 @@ Invoice::Invoice(
const std::string& bookingId,
ServiceBooking* booking,
const util::Timestamp& invoiceDate,
- double laborCost, const util::Map& parts,
double partsCost,
double discountPercentage,
@@ -73,7 +78,48 @@ Invoice::Invoice(
m_totalAmount(totalAmount),
m_paymentDate(paymentDate),
m_paymentMethod(paymentMethod),
- m_status(status) {}
+ m_status(status)
+{
+ int numberOfParts = m_parts.getSize();
+ auto partPointers = m_parts.getValues();
+ for (int index = 0; index < numberOfParts; index++)
+ {
+ m_partIDs.push_back(partPointers[index]->getId());
+ }
+}
+
+Invoice::Invoice(
+ const std::string& id,
+ const std::string& bookingId,
+ const util::Timestamp& invoiceDate,
+ const util::Vector& partIDs,
+ double laborCost,
+ double partsCost,
+ double discountPercentage,
+ double totalAmount,
+ const util::Timestamp& paymentDate,
+ util::PaymentMode paymentMethod,
+ util::PaymentStatus status
+)
+ : m_id(id),
+ m_bookingId(bookingId),
+ m_booking(nullptr),
+ m_invoiceDate(invoiceDate),
+ m_partIDs(partIDs),
+ m_laborCost(laborCost),
+ m_partsCost(partsCost),
+ m_discountPercentage(discountPercentage),
+ m_totalAmount(totalAmount),
+ m_paymentDate(paymentDate),
+ m_paymentMethod(paymentMethod),
+ m_status(status)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
/*
Function: getId
@@ -130,13 +176,26 @@ double Invoice::getLaborCost() const
return m_laborCost;
}
+/*
+Function: getPartIDs
+Description: Retrieves the IDs of parts used in the invoice.
+Parameters:
+ - None
+Returns:
+ - const util::Vector&: Part IDs
+*/
+const util::Vector& Invoice::getPartIDs() const
+{
+ return m_partIDs;
+}
+
/*
Function: getParts
Description: Retrieves the map of inventory items used in the service.
Returns:
- const util::Map& representing the parts.
*/
-const util::Map& Invoice::getParts() const
+const util::Map& Invoice::getParts() const
{
return m_parts;
}
@@ -280,9 +339,16 @@ Parameters:
Returns:
- void
*/
-void Invoice::setParts(const util::Map& parts)
+void Invoice::setParts(const util::Map& parts)
{
m_parts = parts;
+ m_partIDs.clear();
+ int numberOfParts = m_parts.getSize();
+ auto partPointers = m_parts.getValues();
+ for (int index = 0; index < numberOfParts; index++)
+ {
+ m_partIDs.push_back(partPointers[index]->getId());
+ }
}
/*
@@ -361,4 +427,147 @@ Returns:
void Invoice::setStatus(util::PaymentStatus status)
{
m_status = status;
+}
+
+/*
+Function: getPartIDsAsString (static helper)
+Description: Converts a vector of part IDs into a single string separated by '|'.
+Parameters:
+ - partIDs: const util::Vector&, vector of part IDs
+Returns:
+ - std::string: Concatenated part IDs string
+*/
+static std::string getPartIDsAsString(const util::Vector& partIDs)
+{
+ int numberOfParts = partIDs.getSize();
+ std::string partIDsString;
+ for (int index = 0; index < numberOfParts; index++)
+ {
+ partIDsString += partIDs[index];
+ if (index < numberOfParts - 1)
+ {
+ partIDsString += '|';
+ }
+ }
+ return partIDsString;
+}
+
+/*
+Function: getPartIDsAsVector (static helper)
+Description: Converts a string of part IDs separated by '|' into a vector.
+Parameters:
+ - partIDsString: const std::string&, concatenated part IDs string
+Returns:
+ - util::Vector: Vector of part IDs
+*/
+static util::Vector getPartIDsAsVector(const std::string& partIDsString)
+{
+ util::Vector partIDs;
+ std::string partID;
+ std::istringstream serializedPartIDs(partIDsString);
+ while (getline(serializedPartIDs, partID, '|'))
+ {
+ partIDs.push_back(partID);
+ }
+ return partIDs;
+}
+
+/*
+Function: serialize
+Description: Serializes the invoice into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized invoice record
+*/
+std::string Invoice::serialize() const
+{
+ std::ostringstream serializedInvoice;
+ serializedInvoice << m_id << ','
+ << m_bookingId << ','
+ << m_invoiceDate.toString() << ','
+ << m_laborCost << ','
+ << getPartIDsAsString(m_partIDs) << ','
+ << m_partsCost << ','
+ << m_discountPercentage << ','
+ << m_totalAmount << ','
+ << m_paymentDate.toString() << ','
+ << util::getPaymentModeString(m_paymentMethod) << ','
+ << util::getPaymentStatusString(m_status);
+ return serializedInvoice.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into an Invoice object.
+Parameters:
+ - record: const std::string&, serialized invoice record
+Returns:
+ - Invoice*: Pointer to the deserialized Invoice object
+Throws:
+ - std::runtime_error if data is invalid
+*/
+Invoice* Invoice::deserialize(const std::string& record)
+{
+ std::string id, bookingId;
+ std::string invoiceDateString, laborCostString, partIDsString;
+ std::string partsCostString, discountPercentageString, totalAmountString;
+ std::string paymentDateString, paymentMethodString, statusString;
+ double laborCost, partsCost, discountPercentage, totalAmount;
+ std::istringstream serializedInvoice(record);
+ getline(serializedInvoice, id, ',');
+ getline(serializedInvoice, bookingId, ',');
+ getline(serializedInvoice, invoiceDateString, ',');
+ getline(serializedInvoice, laborCostString, ',');
+ getline(serializedInvoice, partIDsString, ',');
+ getline(serializedInvoice, partsCostString, ',');
+ getline(serializedInvoice, discountPercentageString, ',');
+ getline(serializedInvoice, totalAmountString, ',');
+ getline(serializedInvoice, paymentDateString, ',');
+ getline(serializedInvoice, paymentMethodString, ',');
+ getline(serializedInvoice, statusString, ',');
+ util::Timestamp invoiceDate;
+ util::Timestamp paymentDate;
+ try
+ {
+ invoiceDate = util::Timestamp::fromString(invoiceDateString);
+ paymentDate = util::Timestamp::fromString(paymentDateString);
+ laborCost = std::stod(laborCostString);
+ partsCost = std::stod(partsCostString);
+ discountPercentage = std::stod(discountPercentageString);
+ totalAmount = std::stod(totalAmountString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid invoice data");
+ }
+ util::Vector partIDs = getPartIDsAsVector(partIDsString);
+ util::PaymentMode paymentMethod = util::getPaymentMode(paymentMethodString);
+ util::PaymentStatus status = util::getPaymentStatus(statusString);
+ return Factory::getObject(
+ id,
+ bookingId,
+ invoiceDate,
+ partIDs,
+ laborCost,
+ partsCost,
+ discountPercentage,
+ totalAmount,
+ paymentDate,
+ paymentMethod,
+ status
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for invoice serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,BookingID,InvoiceDate,LaborCost,PartIDs,PartsCost,DiscountPercentage,TotalAmount,PaymentDate,PaymentMethod,Status")
+*/
+std::string Invoice::getHeaders()
+{
+ return "ID,BookingID,InvoiceDate,LaborCost,PartIDs,PartsCost,DiscountPercentage,TotalAmount,PaymentDate,PaymentMethod,Status";
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.h
index b93cd77..a226038 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Invoice.h
@@ -10,6 +10,7 @@ Date: 19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
#include "Timestamp.h"
#include "Enums.h"
@@ -25,21 +26,21 @@ private:
ServiceBooking* m_booking;
util::Timestamp m_invoiceDate;
double m_laborCost;
- util::Map m_parts;
+ util::Vector m_partIDs;
+ util::Map m_parts;
double m_partsCost;
double m_discountPercentage;
double m_totalAmount;
util::Timestamp m_paymentDate;
util::PaymentMode m_paymentMethod;
util::PaymentStatus m_status;
-
public:
Invoice();
Invoice(
const std::string& bookingId,
ServiceBooking* booking,
const util::Timestamp& invoiceDate,
- double laborCost, const util::Map& parts,
double partsCost,
double discountPercentage,
@@ -48,12 +49,26 @@ public:
util::PaymentMode paymentMethod,
util::PaymentStatus status
);
+ Invoice(
+ const std::string& id,
+ const std::string& bookingId,
+ const util::Timestamp& invoiceDate,
+ const util::Vector& partIDs,
+ double laborCost,
+ double partsCost,
+ double discountPercentage,
+ double totalAmount,
+ const util::Timestamp& paymentDate,
+ util::PaymentMode paymentMethod,
+ util::PaymentStatus status
+ );
const std::string& getId() const;
const std::string& getBookingId() const;
ServiceBooking* getBooking() const;
const util::Timestamp& getInvoiceDate() const;
double getLaborCost() const;
- const util::Map& getParts() const;
+ const util::Vector& getPartIDs() const;
+ const util::Map& getParts() const;
double getPartsCost() const;
double getDiscountPercentage() const;
double getTotalAmount() const;
@@ -65,11 +80,14 @@ public:
void setBooking(ServiceBooking* booking);
void setInvoiceDate(const util::Timestamp& invoiceDate);
void setLaborCost(double laborCost);
- void setParts(const util::Map& parts);
+ void setParts(const util::Map& parts);
void setPartsCost(double partsCost);
void setDiscountPercentage(double discountPercentage);
void setTotalAmount(double totalAmount);
void setPaymentDate(const util::Timestamp& paymentDate);
void setPaymentMethod(util::PaymentMode paymentMethod);
void setStatus(util::PaymentStatus status);
+ std::string serialize() const;
+ static Invoice* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp
index 747da0f..132e82c 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.cpp
@@ -7,7 +7,12 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
+#include
#include "JobCard.h"
+#include "Factory.h"
+#include "StringHelper.h"
+#include "Enums.h"
int JobCard::m_uid = 0;
@@ -25,7 +30,7 @@ JobCard::JobCard()
m_booking(nullptr),
m_service(nullptr),
m_technician(nullptr),
- m_status(ServiceJobStatus()) {}
+ m_status(util::ServiceJobStatus()) {}
/*
Function: JobCard
@@ -50,7 +55,7 @@ JobCard::JobCard(const std::string& bookingId,
const std::string& technicianId,
User* technician,
const util::Timestamp& assignedDate,
- ServiceJobStatus status,
+ util::ServiceJobStatus status,
const util::Timestamp& completionDate
)
: m_id("JC" + std::to_string(++m_uid)),
@@ -64,6 +69,48 @@ JobCard::JobCard(const std::string& bookingId,
m_status(status),
m_completionDate(completionDate) {}
+/*
+Function: JobCard (parameterized constructor with ID)
+Description: Initializes a job card with an existing ID, booking ID, service ID,
+ technician ID, assignment date, completion date, and status.
+ Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique job card ID
+ - bookingId: const std::string&, ID of the booking
+ - serviceId: const std::string&, ID of the service
+ - technicianId: const std::string&, ID of the technician
+ - assignedDate: const util::Timestamp&, date of assignment
+ - status: util::ServiceJobStatus, job status
+ - completionDate: const util::Timestamp&, date of completion
+Returns:
+ - A new JobCard object
+*/
+JobCard::JobCard(const std::string& id,
+ const std::string& bookingId,
+ const std::string& serviceId,
+ const std::string& technicianId,
+ const util::Timestamp& assignedDate,
+ util::ServiceJobStatus status,
+ const util::Timestamp& completionDate
+)
+ : m_id(id),
+ m_bookingId(bookingId),
+ m_booking(nullptr),
+ m_service(nullptr),
+ m_serviceId(serviceId),
+ m_technicianId(technicianId),
+ m_technician(nullptr),
+ m_assignedDate(assignedDate),
+ m_status(status),
+ m_completionDate(completionDate)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
+
/*
Function: getId
Description: Retrieves the unique ID of the job card.
@@ -158,7 +205,7 @@ Description: Retrieves the current status of the job.
Returns:
- ServiceJobStatus representing the job status.
*/
-ServiceJobStatus JobCard::getStatus() const
+util::ServiceJobStatus JobCard::getStatus() const
{
return m_status;
}
@@ -286,7 +333,7 @@ Parameters:
Returns:
- void
*/
-void JobCard::setStatus(ServiceJobStatus status)
+void JobCard::setStatus(util::ServiceJobStatus status)
{
m_status = status;
}
@@ -302,4 +349,83 @@ Returns:
void JobCard::setCompletionDate(const util::Timestamp& completionDate)
{
m_completionDate = completionDate;
+}
+
+/*
+Function: serialize
+Description: Serializes the job card into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized job card record
+*/
+std::string JobCard::serialize() const
+{
+ std::ostringstream serializedJobCard;
+ serializedJobCard << m_id << ','
+ << m_bookingId << ','
+ << m_serviceId << ','
+ << m_technicianId << ','
+ << m_assignedDate.toString() << ','
+ << util::getServiceJobStatusString(m_status) << ','
+ << m_completionDate.toString();
+ return serializedJobCard.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a JobCard object.
+Parameters:
+ - record: const std::string&, serialized job card record
+Returns:
+ - JobCard*: Pointer to the deserialized JobCard object
+Throws:
+ - std::runtime_error if timestamp parsing fails
+*/
+JobCard* JobCard::deserialize(const std::string& record)
+{
+ std::string id, bookingId, serviceId, technicianId;
+ std::string assignedDateString, statusString, completionDateString;
+ std::istringstream serializedJobCard(record);
+ getline(serializedJobCard, id, ',');
+ getline(serializedJobCard, bookingId, ',');
+ getline(serializedJobCard, serviceId, ',');
+ getline(serializedJobCard, technicianId, ',');
+ getline(serializedJobCard, assignedDateString, ',');
+ getline(serializedJobCard, statusString, ',');
+ getline(serializedJobCard, completionDateString, ',');
+ util::Timestamp assignedDate;
+ util::Timestamp completionDate;
+ try
+ {
+ assignedDate = util::Timestamp::fromString(assignedDateString);
+ completionDate = util::Timestamp::fromString(completionDateString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid timestamp");
+ }
+ util::ServiceJobStatus status = util::getServiceJobStatus(statusString);
+ return Factory::getObject(
+ id,
+ bookingId,
+ serviceId,
+ technicianId,
+ assignedDate,
+ status,
+ completionDate
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for job card serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,BookingID,ServiceID,TechnicianID,AssignedDate,Status,CompletionDate")
+*/
+std::string JobCard::getHeaders()
+{
+ return "ID,BookingID,ServiceID,TechnicianID,AssignedDate,Status,CompletionDate";
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h
index bdc736d..b8a1cdd 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/JobCard.h
@@ -9,13 +9,12 @@ Date: 19-May-2026
#pragma once
#include
#include "Timestamp.h"
+#include "Enums.h"
class ServiceBooking;
class Service;
class User;
-enum class ServiceJobStatus : int;
-
class JobCard
{
private:
@@ -28,7 +27,7 @@ private:
std::string m_technicianId;
User* m_technician;
util::Timestamp m_assignedDate;
- ServiceJobStatus m_status;
+ util::ServiceJobStatus m_status;
util::Timestamp m_completionDate;
public:
@@ -40,7 +39,15 @@ public:
const std::string& technicianId,
User* technician,
const util::Timestamp& assignedDate,
- ServiceJobStatus status,
+ util::ServiceJobStatus status,
+ const util::Timestamp& completionDate
+ );
+ JobCard(const std::string& id,
+ const std::string& bookingId,
+ const std::string& serviceId,
+ const std::string& technicianId,
+ const util::Timestamp& assignedDate,
+ util::ServiceJobStatus status,
const util::Timestamp& completionDate
);
const std::string& getId() const;
@@ -51,7 +58,7 @@ public:
const std::string& getTechnicianId() const;
User* getTechnician() const;
const util::Timestamp& getAssignedDate() const;
- ServiceJobStatus getStatus() const;
+ util::ServiceJobStatus getStatus() const;
const util::Timestamp& getCompletionDate() const;
void setId(const std::string& id);
void setBookingId(const std::string& bookingId);
@@ -61,6 +68,9 @@ public:
void setTechnicianId(const std::string& technicianId);
void setTechnician(User* technician);
void setAssignedDate(const util::Timestamp& assignedDate);
- void setStatus(ServiceJobStatus status);
+ void setStatus(util::ServiceJobStatus status);
void setCompletionDate(const util::Timestamp& completionDate);
+ std::string serialize() const;
+ static JobCard* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
index 353bcb2..0bae917 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp
@@ -6,7 +6,10 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
#include "Notification.h"
+#include "StringHelper.h"
+#include "Factory.h"
int Notification::m_uid = 0;
@@ -42,6 +45,34 @@ Notification::Notification(const std::string& recipientUserId, User* recipient,
m_message(message),
m_createdAt(createdAt) {}
+/*
+Function: Notification (parameterized constructor with ID)
+Description: Initializes a notification with an existing ID, recipient details,
+ title, message, and creation timestamp. Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique notification ID
+ - recipientUserId: const std::string&, ID of the recipient user
+ - title: const std::string&, notification title
+ - message: const std::string&, notification message
+ - createdAt: const util::Timestamp&, timestamp of creation
+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)
+ : m_id(id),
+ m_recipientUserId(recipientUserId),
+ m_recipient(nullptr),
+ m_title(title),
+ m_message(message),
+ m_createdAt(createdAt)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
+
/*
Function: getId
Description: Retrieves the unique ID of the notification.
@@ -184,4 +215,73 @@ Returns:
void Notification::setCreatedAt(const util::Timestamp& createdAt)
{
m_createdAt = createdAt;
+}
+
+/*
+Function: serialize
+Description: Serializes the notification into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized notification record
+*/
+std::string Notification::serialize() const
+{
+ std::ostringstream serializedNotification;
+ serializedNotification << m_id << ','
+ << m_recipientUserId << ','
+ << m_title << ','
+ << m_message << ','
+ << m_createdAt.toString();
+ return serializedNotification.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a Notification object.
+Parameters:
+ - record: const std::string&, 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)
+{
+ 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";
}
\ 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 0ba780b..57869fa 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h
@@ -25,6 +25,7 @@ private:
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);
const std::string& getId() const;
const std::string& getRecipientUserId() const;
User* getRecipient() const;
@@ -37,4 +38,7 @@ public:
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();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.cpp
index 02fe9ea..0717467 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.cpp
@@ -7,7 +7,11 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
#include "Service.h"
+#include "InventoryItem.h"
+#include "StringHelper.h"
+#include "Factory.h"
int Service::m_uid = 0;
@@ -40,7 +44,42 @@ Service::Service(const std::string& name, const util::MapgetId());
+ }
+}
+
+/*
+Function: Service (parameterized constructor with ID)
+Description: Initializes a service with an existing ID, name, inventory item IDs,
+ labor cost, and state. Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique service ID
+ - name: const std::string&, name of the service
+ - requiredInventoryItemIDs: const util::Vector&, IDs of required inventory items
+ - laborCost: double, labor cost of the service
+ - status: util::State, state of the service (ACTIVE/INACTIVE)
+Returns:
+ - A new Service object
+*/
+Service::Service(const std::string& id, const std::string& name, const util::Vector& requiredInventoryItemIDs, double laborCost, util::State status)
+ : m_id(id),
+ m_name(name),
+ m_requiredInventoryItemIDs(requiredInventoryItemIDs),
+ m_status(status),
+ m_laborCost(laborCost)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
/*
Function: getId
@@ -64,6 +103,19 @@ const std::string& Service::getName() const
return m_name;
}
+/*
+Function: getRequiredInventoryItemIDs
+Description: Retrieves the IDs of required inventory items for the service.
+Parameters:
+ - None
+Returns:
+ - const util::Vector&: Inventory item IDs
+*/
+const util::Vector& Service::getRequiredInventoryItemIDs() const
+{
+ return m_requiredInventoryItemIDs;
+}
+
/*
Function: getRequiredInventoryItems
Description: Retrieves the map of inventory items required for the service.
@@ -134,6 +186,13 @@ Returns:
void Service::setRequiredInventoryItems(const util::Map& requiredInventoryItems)
{
m_requiredInventoryItems = requiredInventoryItems;
+ m_requiredInventoryItemIDs.clear();
+ int numberOfRequiredInventoryItems = m_requiredInventoryItems.getSize();
+ auto inventoryItemPointers = m_requiredInventoryItems.getValues();
+ for (int index = 0; index < numberOfRequiredInventoryItems; index++)
+ {
+ m_requiredInventoryItemIDs.push_back(inventoryItemPointers[index]->getId());
+ }
}
/*
@@ -160,4 +219,119 @@ Returns:
void Service::setState(util::State status)
{
m_status = status;
+}
+
+/*
+Function: getInventoryItemIDsAsString (static helper)
+Description: Converts a vector of inventory item IDs into a single string separated by '|'.
+Parameters:
+ - inventoryItemIds: const util::Vector&, vector of inventory item IDs
+Returns:
+ - std::string: Concatenated inventory item IDs string
+*/
+static std::string getInventoryItemIDsAsString(const util::Vector& inventoryItemIds)
+{
+ int numberOfInventoryItems = inventoryItemIds.getSize();
+ std::string inventoryItemIDs;
+ for (int index = 0; index < numberOfInventoryItems; index++)
+ {
+ inventoryItemIDs += inventoryItemIds[index];
+ if (index < numberOfInventoryItems - 1)
+ {
+ inventoryItemIDs += '|';
+ }
+ }
+ return inventoryItemIDs;
+}
+
+/*
+Function: getInventoryItemIDsAsVector (static helper)
+Description: Converts a string of inventory item IDs separated by '|' into a vector.
+Parameters:
+ - inventoryItemIDsString: const std::string&, concatenated inventory item IDs string
+Returns:
+ - util::Vector: Vector of inventory item IDs
+*/
+static util::Vector getInventoryItemIDsAsVector(const std::string& inventoryItemIDsString)
+{
+ util::Vector inventoryItemIDs;
+ std::string inventoryItemID;
+ std::istringstream serializedInventoryItemIDs(inventoryItemIDsString);
+ while (getline(serializedInventoryItemIDs, inventoryItemID, '|'))
+ {
+ inventoryItemIDs.push_back(inventoryItemID);
+ }
+ return inventoryItemIDs;
+}
+
+/*
+Function: serialize
+Description: Serializes the service into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized service record
+*/
+std::string Service::serialize() const
+{
+ std::ostringstream serializedService;
+ serializedService << m_id << ','
+ << m_name << ','
+ << getInventoryItemIDsAsString(m_requiredInventoryItemIDs) << ','
+ << m_laborCost << ','
+ << util::getStateString(m_status);
+ return serializedService.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a Service object.
+Parameters:
+ - record: const std::string&, serialized service record
+Returns:
+ - Service*: Pointer to the deserialized Service object
+Throws:
+ - std::runtime_error if labor cost parsing fails
+*/
+Service* Service::deserialize(const std::string& record)
+{
+ std::string id, name;
+ std::string inventoryItemIDsString, laborCostString, statusString;
+ double laborCost;
+ std::istringstream serializedService(record);
+ getline(serializedService, id, ',');
+ getline(serializedService, name, ',');
+ getline(serializedService, inventoryItemIDsString, ',');
+ getline(serializedService, laborCostString, ',');
+ getline(serializedService, statusString, ',');
+ util::Vector inventoryItemIDs = getInventoryItemIDsAsVector(inventoryItemIDsString);
+ try
+ {
+ laborCost = std::stod(laborCostString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid labor cost");
+ }
+ util::State status = util::getState(statusString);
+ return Factory::getObject(
+ id,
+ name,
+ inventoryItemIDs,
+ laborCost,
+ status
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for service serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,Name,InventoryIDs,LaborCost,Status")
+*/
+std::string Service::getHeaders()
+{
+ return "ID,Name,InventoryIDs,LaborCost,Status";
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.h
index 7d15ebe..b80e674 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Service.h
@@ -10,6 +10,7 @@ Date: 19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
#include "Enums.h"
class InventoryItem;
@@ -20,14 +21,17 @@ private:
static int m_uid;
std::string m_id;
std::string m_name;
+ util::Vector m_requiredInventoryItemIDs;
util::Map m_requiredInventoryItems;
double m_laborCost;
util::State m_status;
public:
Service();
Service(const std::string& name, const util::Map& requiredInventoryItems, double laborCost);
+ Service(const std::string& id, const std::string& name, const util::Vector& requiredInventoryItemIDs, double laborCost, util::State state);
const std::string& getId() const;
const std::string& getName() const;
+ const util::Vector& getRequiredInventoryItemIDs() const;
const util::Map& getRequiredInventoryItems() const;
double getLaborCost() const;
util::State getState() const;
@@ -36,4 +40,7 @@ public:
void setRequiredInventoryItems(const util::Map& requiredInventoryItems);
void setLaborCost(double laborCost);
void setState(util::State status);
+ std::string serialize() const;
+ static Service* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp
index 18702ac..a049a86 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp
@@ -6,7 +6,13 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
+#include
+#include
#include "ServiceBooking.h"
+#include "Service.h"
+#include "Enums.h"
+#include "Factory.h"
+#include "StringHelper.h"
int ServiceBooking::m_uid = 0;
@@ -64,6 +70,60 @@ ServiceBooking::ServiceBooking(
m_assignedTechnician(nullptr),
m_discountPercentage(discountPercentage)
{
+ int numberOfServices = m_services.getSize();
+ auto servicePointers = m_services.getValues();
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ m_serviceIDs.push_back(servicePointers[index]->getId());
+ }
+}
+
+/*
+Function: ServiceBooking (parameterized constructor with ID)
+Description: Initializes a service booking with an existing ID, status, service IDs,
+ customer details, vehicle details, technician ID, and discount percentage.
+ Updates UID tracking based on ID.
+Parameters:
+ - id: const std::string&, unique booking ID
+ - status: util::ServiceJobStatus, job status of the booking
+ - serviceIDs: const util::Vector&, IDs of booked services
+ - customerId: const std::string&, ID of the customer
+ - vehicleNumber: const std::string&, vehicle number
+ - vehicleBrand: const std::string&, vehicle brand
+ - vehicleModel: const std::string&, vehicle model
+ - assignedTechnicianId: const std::string&, ID of the assigned technician
+ - discountPercentage: double, discount applied
+Returns:
+ - A new ServiceBooking object
+*/
+ServiceBooking::ServiceBooking(
+ const std::string& id,
+ util::ServiceJobStatus status,
+ const util::Vector& serviceIDs,
+ const std::string& customerId,
+ const std::string& vehicleNumber,
+ const std::string& vehicleBrand,
+ const std::string& vehicleModel,
+ const std::string& assignedTechnicianId,
+ double discountPercentage
+)
+ : m_id(id),
+ m_status(status),
+ m_serviceIDs(serviceIDs),
+ m_customerId(customerId),
+ m_customer(nullptr),
+ m_vehicleNumber(vehicleNumber),
+ m_vehicleBrand(vehicleBrand),
+ m_vehicleModel(vehicleModel),
+ m_assignedTechnicianId(assignedTechnicianId),
+ m_assignedTechnician(nullptr),
+ m_discountPercentage(discountPercentage)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
}
/*
@@ -88,6 +148,19 @@ util::ServiceJobStatus ServiceBooking::getStatus() const
return m_status;
}
+/*
+Function: getServiceIDs
+Description: Retrieves the IDs of services booked.
+Parameters:
+ - None
+Returns:
+ - const util::Vector&: Service IDs
+*/
+const util::Vector& ServiceBooking::getServiceIDs() const
+{
+ return m_serviceIDs;
+}
+
/*
Function: getServices
Description: Retrieves the services associated with the booking.
@@ -217,6 +290,13 @@ Return type: void
void ServiceBooking::setServices(const util::Map& services)
{
m_services = services;
+ m_serviceIDs.clear();
+ int numberOfServices = m_services.getSize();
+ auto servicePointers = m_services.getValues();
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ m_serviceIDs.push_back(servicePointers[index]->getId());
+ }
}
/*
@@ -305,4 +385,131 @@ Return type: void
void ServiceBooking::setDiscountPercentage(double discountPercentage)
{
m_discountPercentage = discountPercentage;
+}
+
+/*
+Function: getServiceIDsAsString (static helper)
+Description: Converts a vector of service IDs into a single string separated by '|'.
+Parameters:
+ - serviceIDs: const util::Vector&, vector of service IDs
+Returns:
+ - std::string: Concatenated service IDs string
+*/
+static std::string getServiceIDsAsString(const util::Vector& serviceIDs)
+{
+ int numberOfServices = serviceIDs.getSize();
+ std::string serviceIDsString;
+ for (int index = 0; index < numberOfServices; index++)
+ {
+ serviceIDsString += serviceIDs[index];
+ if (index < numberOfServices - 1)
+ {
+ serviceIDsString += '|';
+ }
+ }
+ return serviceIDsString;
+}
+
+/*
+Function: getServiceIDsAsVector (static helper)
+Description: Converts a string of service IDs separated by '|' into a vector.
+Parameters:
+ - serviceIDsString: const std::string&, concatenated service IDs string
+Returns:
+ - util::Vector: Vector of service IDs
+*/
+static util::Vector getServiceIDsAsVector(const std::string& serviceIDsString)
+{
+ util::Vector serviceIDs;
+ std::string serviceID;
+ std::istringstream serializedServiceIDs(serviceIDsString);
+ while (getline(serializedServiceIDs, serviceID, '|'))
+ {
+ serviceIDs.push_back(serviceID);
+ }
+ return serviceIDs;
+}
+
+/*
+Function: serialize
+Description: Serializes the service booking into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized booking record
+*/
+std::string ServiceBooking::serialize() const
+{
+ std::ostringstream serializedBooking;
+ serializedBooking << m_id << ','
+ << util::getServiceJobStatusString(m_status) << ','
+ << getServiceIDsAsString(m_serviceIDs) << ','
+ << m_customerId << ','
+ << m_vehicleNumber << ','
+ << m_vehicleBrand << ','
+ << m_vehicleModel << ','
+ << m_assignedTechnicianId << ','
+ << m_discountPercentage << ',';
+ return serializedBooking.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a ServiceBooking object.
+Parameters:
+ - record: const std::string&, serialized booking record
+Returns:
+ - ServiceBooking*: Pointer to the deserialized ServiceBooking object
+Throws:
+ - std::runtime_error if discount percentage parsing fails
+*/
+ServiceBooking* ServiceBooking::deserialize(const std::string& record)
+{
+ std::string id, customerId, vehicleNumber, vehicleBrand, vehicleModel, assignedTechnicianId;
+ std::string serviceJobStatusString, serviceIDsString, discountPercentageString;
+ double discountPercentage;
+ std::istringstream serializedBooking(record);
+ getline(serializedBooking, id, ',');
+ getline(serializedBooking, serviceJobStatusString, ',');
+ getline(serializedBooking, serviceIDsString, ',');
+ getline(serializedBooking, customerId, ',');
+ getline(serializedBooking, vehicleNumber, ',');
+ getline(serializedBooking, vehicleBrand, ',');
+ getline(serializedBooking, vehicleModel, ',');
+ getline(serializedBooking, assignedTechnicianId, ',');
+ getline(serializedBooking, discountPercentageString, ',');
+ util::Vector serviceIDs = getServiceIDsAsVector(serviceIDsString);
+ try
+ {
+ discountPercentage = std::stod(discountPercentageString);
+ }
+ catch (...)
+ {
+ throw std::runtime_error("Invalid discount percentage");
+ }
+ util::ServiceJobStatus status = util::getServiceJobStatus(serviceJobStatusString);
+ return Factory::getObject(
+ id,
+ status,
+ serviceIDs,
+ customerId,
+ vehicleNumber,
+ vehicleBrand,
+ vehicleModel,
+ assignedTechnicianId,
+ discountPercentage
+ );
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for service booking serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,Status,ServiceIDs,CustomerID,VehicleNumber,VehicleBrand,VehicleModel,AssignedTechnicianID,DiscountPercentage")
+*/
+std::string ServiceBooking::getHeaders()
+{
+ return "ID,Status,ServiceIDs,CustomerID,VehicleNumber,VehicleBrand,VehicleModel,AssignedTechnicianID,DiscountPercentage";
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h
index 48e3ba9..24acb32 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h
@@ -9,6 +9,7 @@ Date:19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
#include "Enums.h"
class Service;
@@ -20,6 +21,7 @@ private:
static int m_uid;
std::string m_id;
util::ServiceJobStatus m_status;
+ util::Vector m_serviceIDs;
util::Map m_services;
std::string m_customerId;
User* m_customer;
@@ -42,8 +44,20 @@ public:
const std::string& vehicleModel,
double discountPercentage
);
+ ServiceBooking(
+ const std::string& id,
+ util::ServiceJobStatus status,
+ const util::Vector& serviceIDs,
+ const std::string& customerId,
+ const std::string& vehicleNumber,
+ const std::string& vehicleBrand,
+ const std::string& vehicleModel,
+ const std::string& assignedTechnicianId,
+ double discountPercentage
+ );
const std::string& getId() const;
util::ServiceJobStatus getStatus() const;
+ const util::Vector& getServiceIDs() const;
const util::Map& getServices() const;
const std::string& getCustomerId() const;
User* getCustomer() const;
@@ -64,4 +78,7 @@ public:
void setAssignedTechnicianId(const std::string& assignedTechnicianId);
void setAssignedTechnician(User* assignedTechnician);
void setDiscountPercentage(double discountPercentage);
+ std::string serialize() const;
+ static ServiceBooking* deserialize(const std::string&);
+ static std::string getHeaders();
};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
index 0b0fa58..0b4e86e 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp
@@ -7,9 +7,12 @@ Author: Trenser
Date: 19-May-2026
*/
+#include
#include "User.h"
#include "Notification.h"
#include "Enums.h"
+#include "Factory.h"
+#include "StringHelper.h"
int User::m_uid = 0;
@@ -50,6 +53,39 @@ User::User(const std::string& userName, const std::string& password, const std::
m_type(role),
m_status(util::State::ACTIVE) {}
+/*
+Function: User (parameterized constructor with ID)
+Description: Initializes a user with an existing ID, credentials, personal details,
+ role, and state. Updates UID tracking based on ID.
+Parameters:
+ - userId: const std::string&, unique user ID
+ - userName: const std::string&, username
+ - password: const std::string&, password
+ - name: const std::string&, full name
+ - phone: const std::string&, phone number
+ - email: const std::string&, email address
+ - role: util::UserType, role of the user
+ - status: util::State, state of the user (ACTIVE/INACTIVE)
+Returns:
+ - A new User object
+*/
+User::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)
+ : m_id(userId),
+ m_userName(userName),
+ m_password(password),
+ m_name(name),
+ m_phone(phone),
+ m_email(email),
+ m_type(role),
+ m_status(status)
+{
+ int idNumber = util::extractNumber(m_id);
+ if (idNumber > m_uid)
+ {
+ m_uid = idNumber;
+ }
+}
+
/*
Function: ~User
Description: Destructor that cleans up dynamically allocated notifications associated with the user.
@@ -60,9 +96,10 @@ Returns:
*/
User::~User()
{
- for (int index = 0; index < m_notifications.getSize(); index++)
+ auto values = m_notifications.getValues();
+ for (int index = 0; index < values.getSize(); index++)
{
- delete m_notifications.getValues()[index];
+ delete values[index];
}
}
@@ -284,3 +321,71 @@ void User::setState(util::State status)
{
m_status = status;
}
+
+/*
+Function: serialize
+Description: Serializes the user into a CSV-formatted string.
+Parameters:
+ - None
+Returns:
+ - std::string: Serialized user record
+*/
+std::string User::serialize() const
+{
+ std::ostringstream serializedUser;
+ serializedUser << m_id << ','
+ << m_userName << ','
+ << m_password << ','
+ << m_name << ','
+ << m_phone << ','
+ << m_email << ','
+ << util::getUserTypeString(m_type) << ','
+ << util::getStateString(m_status);
+ return serializedUser.str();
+}
+
+/*
+Function: deserialize
+Description: Deserializes a CSV-formatted string into a User object.
+Parameters:
+ - record: const std::string&, serialized user record
+Returns:
+ - User*: Pointer to the deserialized User object
+*/
+User* User::deserialize(const std::string& record)
+{
+ std::string id, name, username, phone, password, email;
+ std::string userTypeString, stateString;
+ std::istringstream serializedUser(record);
+ getline(serializedUser, id, ',');
+ getline(serializedUser, username, ',');
+ getline(serializedUser, password, ',');
+ getline(serializedUser, name, ',');
+ getline(serializedUser, phone, ',');
+ getline(serializedUser, email, ',');
+ getline(serializedUser, userTypeString, ',');
+ getline(serializedUser, stateString);
+ util::UserType userType = util::getUserType(userTypeString);
+ util::State status = util::getState(stateString);
+ return Factory::getObject(id,
+ username,
+ password,
+ name,
+ phone,
+ email,
+ userType,
+ status);
+}
+
+/*
+Function: getHeaders
+Description: Retrieves the CSV headers for user serialization.
+Parameters:
+ - None
+Returns:
+ - std::string: Header string ("ID,Username,Password,Name,Phone,Email,UserType,UserStatus")
+*/
+std::string User::getHeaders()
+{
+ return "ID,Username,Password,Name,Phone,Email,UserType,UserStatus";
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
index 1c5c215..12923f6 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h
@@ -31,6 +31,7 @@ private:
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();
const std::string& getId() const;
const std::string& getUserName() const;
@@ -50,4 +51,7 @@ public:
void addNotification(Notification* notification) override;
void setRole(util::UserType role);
void setState(util::State status);
+ std::string serialize() const;
+ static User* deserialize(const std::string&);
+ static std::string getHeaders();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
index 4b2f003..6f675eb 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp
@@ -1,12 +1,24 @@
+/*
+File: InventoryManagementService.cpp
+Description: Implements the InventoryManagementService class, which manages inventory
+ items and observer relationships within the system. Provides methods
+ for loading and saving inventory items from persistent storage, as well
+ as attaching and persisting observers for notification handling.
+Author: Trenser
+Date: 22-May-2026
+*/
+
#include
-#include "InventoryManagementService.h"
-#include "Vector.h"
-#include "Enums.h"
-#include "InventoryItem.h"
#include "Config.h"
-#include "User.h"
+#include "Enums.h"
#include "Factory.h"
+#include "FileManager.h"
+#include "InventoryItem.h"
+#include "InventoryManagementService.h"
#include "Timestamp.h"
+#include "User.h"
+#include "Utility.h"
+#include "Vector.h"
util::Map InventoryManagementService::m_observers{};
@@ -103,3 +115,93 @@ 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);
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
index da63a84..a56cd37 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.h
@@ -9,6 +9,7 @@ Date: 19-May-2026
#pragma once
#include
#include "Map.h"
+#include "Vector.h"
#include "NotificationManagementService.h"
#include "DataStore.h"
@@ -19,6 +20,7 @@ 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();
@@ -29,4 +31,8 @@ public:
void sendNotification(User* user, const std::string& title, const std::string& message) override;
void attach(User* user) override;
void detach(User* user) override;
+ void loadInventoryItems();
+ void saveInventoryItems();
+ void loadObservers();
+ void saveObservers();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
index 18d0dda..33d214a 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.h
@@ -19,4 +19,5 @@ public:
virtual void sendNotification(User* recipient, const std::string& title, const std::string& message) = 0;
virtual void attach(User* user) = 0;
virtual void detach(User* user) = 0;
+ virtual util::Vector getObserverIDs() = 0;
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
index 12082cf..b7946bf 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp
@@ -8,14 +8,17 @@ Date: 20-May-2026
*/
#include
-#include "PaymentManagementService.h"
-#include "Invoice.h"
-#include "ServiceBooking.h"
-#include "Enums.h"
-#include "Timestamp.h"
#include "Config.h"
-#include "User.h"
+#include "Enums.h"
#include "Factory.h"
+#include "FileManager.h"
+#include "Invoice.h"
+#include "PaymentManagementService.h"
+#include "ServiceBooking.h"
+#include "Timestamp.h"
+#include "User.h"
+#include "Utility.h"
+
util::Map PaymentManagementService::m_observers{};
@@ -134,3 +137,120 @@ 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);
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
index c6e43a0..14b8c11 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h
@@ -22,6 +22,7 @@ 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);
@@ -31,4 +32,8 @@ public:
void sendNotification(User* user, const std::string& title, const std::string& message) override;
void attach(User* user) override;
void detach(User* user) override;
+ void loadInvoices();
+ void saveInvoices();
+ void loadObservers();
+ void saveObservers();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
index de777ec..e958839 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp
@@ -6,15 +6,20 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
+
#include
#include "AuthenticationManagementService.h"
#include "ComboPackage.h"
+#include "Config.h"
#include "Factory.h"
+#include "FileManager.h"
+#include "JobCard.h"
#include "Service.h"
#include "ServiceBooking.h"
#include "ServiceManagementService.h"
#include "Timestamp.h"
#include "User.h"
+#include "Utility.h"
/*
Function: purchaseService
@@ -178,3 +183,320 @@ void ServiceManagementService::sendNotification(User* user, const std::string& t
}
}
}
+
+/*
+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++)
+ {
+ 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);
+ }
+}
+
+/*
+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++)
+ {
+ 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;
+ }
+}
+
+/*
+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++)
+ {
+ 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;
+ }
+}
+
+/*
+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);
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
index e1dfb91..119af04 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h
@@ -22,6 +22,7 @@ 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();
@@ -42,4 +43,14 @@ public:
void sendNotification(User* user, const std::string& title, const std::string& message) override;
void attach(User* user) override;
void detach(User* user) override;
+ void loadServices();
+ void saveServices();
+ void loadComboPackages();
+ void saveComboPackages();
+ void loadServiceBookings();
+ void saveServiceBookings();
+ void loadJobCards();
+ void saveJobCards();
+ void loadObservers();
+ void saveObservers();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
index 63732a5..0503019 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp
@@ -10,7 +10,9 @@ 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"
#include "ServiceManagementService.h"
#include "User.h"
@@ -173,4 +175,72 @@ void UserManagementService::deleteNotification(const std::string& notificationID
throw std::runtime_error("No notification found with given NotificationID");
}
notifications.remove(notificationID);
+}
+
+/*
+Function: loadUsers
+Description: Loads users and notifications from persistent storage into the datastore.
+ Validates that each notification’s recipient exists and attaches the
+ notification to the corresponding user.
+Parameters:
+ - None
+Returns:
+ - void
+Throws:
+ - std::runtime_error if a notification recipient user ID is invalid
+*/
+void UserManagementService::loadUsers()
+{
+ util::FileManager userFileManager(config::file::USER_FILE);
+ util::FileManager notificationFileManager(config::file::NOTIFICATION_FILE);
+ auto& users = m_dataStore.getUsers();
+ auto usersMap = userFileManager.load();
+ auto notificationsMap = notificationFileManager.load();
+ int numberOfUsers = usersMap.getSize();
+ int numberOfNotifications = notificationsMap.getSize();
+ for (int index = 0; index < numberOfUsers; index++)
+ {
+ users[usersMap.getKeyAt(index)] = usersMap.getValueAt(index);
+ }
+ for (int index = 0; index < numberOfNotifications; index++)
+ {
+ Notification* notification = notificationsMap.getValueAt(index);
+ const std::string& recipientUserId = notification->getRecipientUserId();
+ int userIndex = users.find(recipientUserId);
+ if (userIndex == -1)
+ {
+ throw std::runtime_error("Invalid recipient user ID");
+ }
+ User* user = users.getValueAt(userIndex);
+ user->addNotification(notification);
+ }
+}
+
+/*
+Function: saveUsers
+Description: Saves users and their notifications from the datastore to persistent storage.
+ Collects notifications from all users into a single map before saving.
+Parameters:
+ - None
+Returns:
+ - void
+*/
+void UserManagementService::saveUsers()
+{
+ util::FileManager userFileManager(config::file::USER_FILE);
+ util::FileManager notificationFileManager(config::file::NOTIFICATION_FILE);
+ auto& users = m_dataStore.getUsers();
+ util::Map notifications;
+ for (int userIndex = 0; userIndex < users.getSize(); userIndex++)
+ {
+ User* user = users.getValueAt(userIndex);
+ auto& userNotifications = user->getNotifications();
+ for (int notificationIndex = 0; notificationIndex < userNotifications.getSize(); notificationIndex++)
+ {
+ notifications[userNotifications.getKeyAt(notificationIndex)] =
+ userNotifications.getValueAt(notificationIndex);
+ }
+ }
+ userFileManager.save(users);
+ notificationFileManager.save(notifications);
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
index 313b8d6..6b9f518 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
@@ -30,4 +30,6 @@ public:
util::Vector getUserNotifications(const std::string& userID);
void deleteNotification(const std::string& notificationID, const std::string& userID);
void ensureAdminExists();
+ void loadUsers();
+ void saveUsers();
};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
index f55529e..30bfad9 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
@@ -25,4 +25,19 @@ namespace config
constexpr int INVENTORY_LOW_STOCK_THRESHOLD = 5;
constexpr int PAYMENT_REMINDER_THRESHOLD_HOURS = 168;
}
+
+ namespace file
+ {
+ constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.csv";
+ constexpr const char* USER_FILE = "files/User.csv";
+ constexpr const char* NOTIFICATION_FILE = "files/Notification.csv";
+ constexpr const char* SERVICE_FILE = "files/Service.csv";
+ constexpr const char* COMBOPACKAGE_FILE = "files/ComboPackage.csv";
+ constexpr const char* SERVICEBOOKING_FILE = "files/ServiceBooking.csv";
+ constexpr const char* JOBCARD_FILE = "files/JobCard.csv";
+ constexpr const char* INVOICE_FILE = "files/Invoice.csv";
+ constexpr const char* SERVICEMANAGEMENTOBSERVERS = "files/ServiceManagementObservers.csv";
+ constexpr const char* PAYMENTMANAGEMENTOBSERVERS = "files/PaymentManagementObservers.csv";
+ constexpr const char* INVENTORYMANAGEMENTOBSERVERS = "files/InventoryManagementObservers.csv";
+ }
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
index 60f2d9b..9e8b1b9 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
@@ -236,9 +236,9 @@ namespace util
switch (status)
{
case State::ACTIVE:
- return "STARTED";
+ return "ACTIVE";
case State::INACTIVE:
- return "COMPLETED";
+ return "INACTIVE";
}
throw std::invalid_argument("Invalid State");
}
@@ -259,7 +259,7 @@ namespace util
{
return State::ACTIVE;
}
- if (value == "COMPLETED")
+ if (value == "INACTIVE")
{
return State::INACTIVE;
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
new file mode 100644
index 0000000..3a532b1
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
@@ -0,0 +1,79 @@
+/*
+File: FileHelper.h
+Description: Provides utility functions for loading and saving records
+ from and to CSV-like text files. Ensures files are created
+ if missing and supports simple record persistence.
+Author: Trenser
+Date: 22-May-2026
+*/
+
+#pragma once
+#include
+#include
+#include
+#include "Vector.h"
+
+namespace util
+{
+ /*
+ 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())
+ {
+ 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';
+ }
+ }
+}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h
new file mode 100644
index 0000000..35d2935
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileManager.h
@@ -0,0 +1,117 @@
+/*
+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"
+
+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())
+ {
+ 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 d8fee08..e789442 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
@@ -34,7 +34,7 @@ namespace util
/*
* Function: read
- * Description: Reads a line of text input from console into a string.
+ * Description: Reads a line of text input from console into a string and cleans it up.
* Parameters:
* value - reference to a string where the input will be stored
* Returns:
@@ -43,6 +43,15 @@ namespace util
inline void read(std::string& value)
{
std::getline(std::cin >> std::ws, value);
+ std::string cleanedValue;
+ for (int index = 0; index < value.length(); index++)
+ {
+ if (value[index] != ',')
+ {
+ cleanedValue += value[index];
+ }
+ }
+ value = cleanedValue;
}
/*
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/StringHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/StringHelper.h
new file mode 100644
index 0000000..0d7839a
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/StringHelper.h
@@ -0,0 +1,36 @@
+/*
+File: StringHelper.h
+Description: Provides utility functions for extracting numeric values from strings.
+ Useful for parsing IDs, codes, or mixed alphanumeric inputs where
+ digits need to be isolated and converted into integers.
+Author: Trenser
+Date: 22-May-2026
+*/
+
+#include
+#include
+
+namespace util
+{
+ /*
+ Function: extractNumber
+ Description: Extracts all digits from the given string and converts them into an integer.
+ Ignores non-digit characters. For example, "abc123xyz" returns 123.
+ Parameters:
+ - input: const std::string&, the input string containing digits and/or other characters
+ Returns:
+ - int: The integer value formed by concatenating all digits in the string
+ */
+ inline int extractNumber(const std::string& input)
+ {
+ int result = 0;
+ for (char character : input)
+ {
+ if (std::isdigit(static_cast(character)))
+ {
+ result = result * 10 + (character - '0');
+ }
+ }
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
index ca1fd37..396fd4b 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
@@ -5,45 +5,99 @@ Description: Header file declaring utility functions used across the system,
Author: Trenser
Date:19-May-2026
*/
+
#pragma once
-#include "Service.h"
+#include "DataStore.h"
+#include "FileHelper.h"
#include "InventoryItem.h"
+#include "NotificationManagementService.h"
+#include "Service.h"
+#include "ComboPackage.h"
-/*
-Function: calculatePartsCost
-Description: Calculates the total cost of parts required for a given service
- by summing the prices of all associated inventory items.
-Parameter: const Service* service - pointer to the service object
-Return type: double - total cost of required parts
-*/
-inline double calculatePartsCost(const Service* service)
+namespace util
{
- double cost = 0;
- auto& requiredInventoryItems = service->getRequiredInventoryItems();
- int requiredInventoryItemsSize = requiredInventoryItems.getSize();
- for (int index = 0; index < requiredInventoryItemsSize; index++)
+ /*
+ Function: calculatePartsCost
+ Description: Calculates the total cost of parts required for a given service
+ by summing the prices of all associated inventory items.
+ Parameter: const Service* service - pointer to the service object
+ Return type: double - total cost of required parts
+ */
+ inline double calculatePartsCost(const Service* service)
{
- cost += requiredInventoryItems.getValueAt(index)->getPrice();
+ double cost = 0;
+ auto& requiredInventoryItems = service->getRequiredInventoryItems();
+ int requiredInventoryItemsSize = requiredInventoryItems.getSize();
+ for (int index = 0; index < requiredInventoryItemsSize; index++)
+ {
+ cost += requiredInventoryItems.getValueAt(index)->getPrice();
+ }
+ return cost;
}
- return cost;
-}
-/*
-Function: calculateComboServiceEstimatedCost
-Description: Calculates the estimated total cost of a combo package by summing
- the labor and parts costs of all services included in the package.
-Parameter: const ComboPackage* comboPackage - pointer to the combo package object
-Return type: double - estimated total cost of the combo package
-*/
-inline double calculateComboServiceEstimatedCost(const ComboPackage* comboPackage)
-{
- double cost = 0;
- auto& services = comboPackage->getServices();
- int servicesSize = services.getSize();
- for (int index = 0; index < servicesSize; index++)
+ /*
+ Function: calculateComboServiceEstimatedCost
+ Description: Calculates the estimated total cost of a combo package by summing
+ the labor and parts costs of all services included in the package.
+ Parameter: const ComboPackage* comboPackage - pointer to the combo package object
+ Return type: double - estimated total cost of the combo package
+ */
+ inline double calculateComboServiceEstimatedCost(const ComboPackage* comboPackage)
{
- const Service* service = services.getValueAt(index);
- cost += calculatePartsCost(service) + service->getLaborCost();
+ double cost = 0;
+ auto& services = comboPackage->getServices();
+ int servicesSize = services.getSize();
+ for (int index = 0; index < servicesSize; index++)
+ {
+ const Service* service = services.getValueAt(index);
+ cost += calculatePartsCost(service) + service->getLaborCost();
+ }
+ 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);
}
- return cost;
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
index c812089..213fb0d 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
@@ -196,7 +196,7 @@ static const Service* selectServiceFromServices(const util::MapgetId()
@@ -282,7 +282,7 @@ static const ComboPackage* selectComboPackageFromPackages(const util::MapgetId()
<< std::setw(25) << currentComboPackage->getPackageName()
- << std::setw(15) << calculateComboServiceEstimatedCost(currentComboPackage)
+ << std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
currentIndex++;
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
index 571cd33..4f91641 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
@@ -22,6 +22,7 @@ Return type: void
*/
void UserInterface::run()
{
+ m_controller.loadSystemData();
m_controller.runSystemChecks();
bool isMenuActive = true;
while (isMenuActive)
@@ -43,6 +44,7 @@ void UserInterface::run()
util::pressEnter();
}
}
+ m_controller.saveSystemData();
}
/*