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:
+48
@@ -1 +1,49 @@
|
||||
#include "InventoryManagementService.h"
|
||||
#include "FileManager.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "Utility.h"
|
||||
#include "Config.h"
|
||||
|
||||
util::Vector<std::string> InventoryManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> 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;
|
||||
}
|
||||
|
||||
void InventoryManagementService::loadInventoryItems()
|
||||
{
|
||||
util::FileManager<InventoryItem> 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);
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryManagementService::saveInventoryItems()
|
||||
{
|
||||
util::FileManager<InventoryItem> inventoryItemFileManager(config::file::INVENTORYITEM_FILE);
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
inventoryItemFileManager.save(inventoryItems);
|
||||
}
|
||||
|
||||
void InventoryManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
void InventoryManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
|
||||
+6
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
#include "Vector.h"
|
||||
#include "NotificationManagementService.h"
|
||||
#include "DataStore.h"
|
||||
|
||||
@@ -11,6 +12,7 @@ class InventoryManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
InventoryManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
util::Map<std::string, InventoryItem*> getInventoryItems();
|
||||
@@ -21,4 +23,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();
|
||||
};
|
||||
|
||||
+1
@@ -10,4 +10,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<std::string> getObserverIDs() = 0;
|
||||
};
|
||||
|
||||
+70
@@ -1 +1,71 @@
|
||||
#include <stdexcept>
|
||||
#include "PaymentManagementService.h"
|
||||
#include "Invoice.h"
|
||||
#include "FileManager.h"
|
||||
#include "Utility.h"
|
||||
#include "Config.h"
|
||||
|
||||
util::Vector<std::string> PaymentManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> 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;
|
||||
}
|
||||
|
||||
void PaymentManagementService::loadInvoices()
|
||||
{
|
||||
util::FileManager<Invoice> 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<std::string, InventoryItem*> 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;
|
||||
}
|
||||
}
|
||||
void PaymentManagementService::saveInvoices()
|
||||
{
|
||||
util::FileManager<Invoice> invoiceFileManager(config::file::INVOICE_FILE);
|
||||
auto& invoices = m_dataStore.getInvoices();
|
||||
invoiceFileManager.save(invoices);
|
||||
}
|
||||
|
||||
void PaymentManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
void PaymentManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
|
||||
+5
@@ -13,6 +13,7 @@ class PaymentManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
PaymentManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
void generateInvoice(ServiceBooking* booking);
|
||||
@@ -22,4 +23,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();
|
||||
};
|
||||
|
||||
+210
@@ -1 +1,211 @@
|
||||
#include <stdexcept>
|
||||
#include "ServiceManagementService.h"
|
||||
#include "FileManager.h"
|
||||
#include "Service.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "JobCard.h"
|
||||
#include "Config.h"
|
||||
#include "Utility.h"
|
||||
|
||||
util::Vector<std::string> ServiceManagementService::getObserverIDs()
|
||||
{
|
||||
util::Vector<std::string> 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;
|
||||
}
|
||||
|
||||
void ServiceManagementService::loadServices()
|
||||
{
|
||||
util::FileManager<Service> 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<std::string, InventoryItem*> 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);
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceManagementService::saveServices()
|
||||
{
|
||||
util::FileManager<Service> serviceFileManager(config::file::SERVICE_FILE);
|
||||
auto& services = m_dataStore.getServices();
|
||||
serviceFileManager.save(services);
|
||||
}
|
||||
|
||||
void ServiceManagementService::loadComboPackages()
|
||||
{
|
||||
util::FileManager<ComboPackage> 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<std::string, Service*> 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;
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceManagementService::saveComboPackages()
|
||||
{
|
||||
util::FileManager<ComboPackage> comboPackageFileManager(config::file::COMBOPACKAGE_FILE);
|
||||
auto& comboPackages = m_dataStore.getComboPackages();
|
||||
comboPackageFileManager.save(comboPackages);
|
||||
}
|
||||
|
||||
void ServiceManagementService::loadServiceBookings()
|
||||
{
|
||||
util::FileManager<ServiceBooking> 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<std::string, Service*> 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;
|
||||
}
|
||||
}
|
||||
|
||||
void ServiceManagementService::saveServiceBookings()
|
||||
{
|
||||
util::FileManager<ServiceBooking> bookingFileManager(config::file::SERVICEBOOKING_FILE);
|
||||
auto& serviceBookings = m_dataStore.getServiceBookings();
|
||||
bookingFileManager.save(serviceBookings);
|
||||
}
|
||||
|
||||
void ServiceManagementService::loadJobCards()
|
||||
{
|
||||
util::FileManager<JobCard> 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;
|
||||
}
|
||||
}
|
||||
void ServiceManagementService::saveJobCards()
|
||||
{
|
||||
util::FileManager<JobCard> jobCardFileManager(config::file::JOBCARD_FILE);
|
||||
auto& jobCards = m_dataStore.getJobCards();
|
||||
jobCardFileManager.save(jobCards);
|
||||
}
|
||||
|
||||
void ServiceManagementService::loadObservers()
|
||||
{
|
||||
util::loadObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this, m_dataStore);
|
||||
}
|
||||
|
||||
void ServiceManagementService::saveObservers()
|
||||
{
|
||||
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
||||
}
|
||||
|
||||
+11
@@ -14,6 +14,7 @@ class ServiceManagementService : public NotificationManagementService
|
||||
private:
|
||||
DataStore& m_dataStore;
|
||||
static util::Map<std::string, User*> m_observers;
|
||||
util::Vector<std::string> getObserverIDs() override;
|
||||
public:
|
||||
ServiceManagementService() : m_dataStore(DataStore::getInstance()) {}
|
||||
util::Map<std::string, Service*> getServices();
|
||||
@@ -34,4 +35,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();
|
||||
};
|
||||
|
||||
+51
@@ -1 +1,52 @@
|
||||
#include "UserManagementService.h"
|
||||
#include "FileManager.h"
|
||||
#include "User.h"
|
||||
#include "Notification.h"
|
||||
#include "Config.h"
|
||||
|
||||
void UserManagementService::loadUsers()
|
||||
{
|
||||
util::FileManager<User> userFileManager(config::file::USER_FILE);
|
||||
util::FileManager<Notification> 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);
|
||||
}
|
||||
}
|
||||
|
||||
void UserManagementService::saveUsers()
|
||||
{
|
||||
util::FileManager<User> userFileManager(config::file::USER_FILE);
|
||||
util::FileManager<Notification> notificationFileManager(config::file::NOTIFICATION_FILE);
|
||||
auto& users = m_dataStore.getUsers();
|
||||
util::Map<std::string, Notification*> 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);
|
||||
}
|
||||
|
||||
+2
@@ -21,4 +21,6 @@ public:
|
||||
void removeUser(const std::string& userID);
|
||||
util::Vector<Notification*> getUserNotifications(const std::string& userID);
|
||||
void deleteNotification(const std::string& notificationID, const std::string& userID);
|
||||
void loadUsers();
|
||||
void saveUsers();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user