Implement serialization/deserialization and persistent storage across services

- Add serialize/deserialize support for core models
- Add file-based load/save functions in management services
- Introduce FileManager, Config, Utility and helper utilities
- Persist observer IDs for notification services
- Resolve object relationships during load (services, bookings, invoices, job cards)
- Add controller-level loadSystemData/saveSystemData
- Load data at app startup and save on shutdown
This commit is contained in:
2026-05-22 12:13:17 +05:30
parent 56c5c2dc70
commit 53713f444b
38 changed files with 1573 additions and 35 deletions
@@ -1,4 +1,9 @@
#include <sstream>
#include <stdexcept>
#include "ComboPackage.h"
#include "Service.h"
#include "Factory.h"
#include "StringHelper.h"
int ComboPackage::m_uid = 0;
@@ -12,7 +17,29 @@ 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());
}
}
ComboPackage::ComboPackage(const std::string& id, const std::string& packageName, double discountPercentage, const util::Vector<std::string>& 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;
}
}
const std::string& ComboPackage::getId() const
{
@@ -34,6 +61,11 @@ util::State ComboPackage::getState() const
return m_status;
}
const util::Vector<std::string>& ComboPackage::getServiceIDs() const
{
return m_serviceIDs;
}
const util::Map<std::string, Service*>& ComboPackage::getServices() const
{
return m_services;
@@ -57,9 +89,89 @@ void ComboPackage::setDiscountPercentage(double discountPercentage)
void ComboPackage::setServices(const util::Map<std::string, Service*>& 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());
}
}
void ComboPackage::setState(util::State status)
{
m_status = status;
}
static std::string getServiceIDsAsString(const util::Vector<std::string>& 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;
}
static util::Vector<std::string> getServiceIDsAsVector(const std::string& serviceIDsString)
{
util::Vector<std::string> serviceIDs;
std::string serviceID;
std::istringstream serializedServiceIDs(serviceIDsString);
while (getline(serializedServiceIDs, serviceID, '|'))
{
serviceIDs.push_back(serviceID);
}
return serviceIDs;
}
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();
}
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<std::string> serviceIDs = getServiceIDsAsVector(serviceIDsString);
util::State status = util::getState(statusString);
return Factory::getObject<ComboPackage>(
id,
packageName,
discountPercentage,
serviceIDs,
status
);
}
std::string ComboPackage::getHeaders()
{
return "ID,PackageName,DiscountPercentage,ServiceIDs,Status";
}