Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 95d1c9a04e | |||
| 2963d05ea1 | |||
| 69cda81a50 | |||
| 9fb9be1b45 | |||
| 0b8fc01dbd | |||
| 8c2a67a42c | |||
| e1676568cd | |||
| d44cc86af0 | |||
| f3220ee191 | |||
| f0c7d27e6c | |||
| b98062d45c | |||
| 74dbbd9e82 | |||
| 6dea303b92 | |||
| 4b76cae358 |
@@ -12,6 +12,8 @@ Date: 19-May-2026
|
||||
#include "Config.h"
|
||||
#include "SerializedRecords.h"
|
||||
#include "FileHelper.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "JobCard.h"
|
||||
|
||||
/*
|
||||
Function: DataStore
|
||||
@@ -252,6 +254,28 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, TrackedRecord<Service>>& DataStore::getServices()
|
||||
{
|
||||
util::Map<std::string, TrackedRecord<Service>> services = loadRecords<Service, SerializedService>(m_services);
|
||||
refreshCache(m_serviceCache, services);
|
||||
util::Map<std::string, TrackedRecord<InventoryItem>>& inventoryItems = getInventoryItems();
|
||||
size_t numberOfServices = m_serviceCache.getSize();
|
||||
for (int iteratorOne =0; iteratorOne < numberOfServices; iteratorOne++)
|
||||
{
|
||||
Service* currentService = m_serviceCache.getValueAt(iteratorOne).data;
|
||||
util::Map<std::string, InventoryItem*> inventoryItemMap;
|
||||
util::Vector<std::string> currentServiceInventoryItem = currentService->getRequiredInventoryItemIDs();
|
||||
for (int iteratorTwo = 0; iteratorTwo < currentServiceInventoryItem.getSize(); iteratorTwo++)
|
||||
{
|
||||
const std::string& currentInventoryItemId = currentServiceInventoryItem[iteratorTwo];
|
||||
int currentInventoryItemIndex = inventoryItems.find(currentInventoryItemId);
|
||||
if (currentInventoryItemIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid inventory item ID");
|
||||
}
|
||||
InventoryItem* currentItem = inventoryItems.getValueAt(currentInventoryItemIndex).data;
|
||||
inventoryItemMap[currentInventoryItemId] = currentItem;
|
||||
}
|
||||
currentService->setRequiredInventoryItems(inventoryItemMap);
|
||||
}
|
||||
return m_serviceCache;
|
||||
}
|
||||
|
||||
@@ -265,6 +289,28 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, TrackedRecord<ComboPackage>>& DataStore::getComboPackages()
|
||||
{
|
||||
util::Map<std::string, TrackedRecord<ComboPackage>> comboPackages = loadRecords<ComboPackage, SerializedComboPackage>(m_comboPackages);
|
||||
refreshCache(m_comboPackageCache, comboPackages);
|
||||
util::Map<std::string, TrackedRecord<Service>>& services = getServices();
|
||||
size_t numberOfComboPackages = m_comboPackageCache.getSize();
|
||||
for (int iteratorOne = 0; iteratorOne < numberOfComboPackages; iteratorOne++)
|
||||
{
|
||||
ComboPackage* currentComboPackage = m_comboPackageCache.getValueAt(iteratorOne).data;
|
||||
util::Vector<std::string> currentServiceIds = currentComboPackage->getServiceIDs();
|
||||
util::Map<std::string, Service*> currentComboPackageServices;
|
||||
for (int iteratorTwo = 0; iteratorTwo < currentServiceIds.getSize(); iteratorTwo++)
|
||||
{
|
||||
const std::string& currentServiceId = currentServiceIds[iteratorTwo];
|
||||
int serviceIndex = services.find(currentServiceId);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid service ID");
|
||||
}
|
||||
Service* currentService = services.getValueAt(serviceIndex).data;
|
||||
currentComboPackageServices[currentServiceId] = currentService;
|
||||
}
|
||||
currentComboPackage->setServices(currentComboPackageServices);
|
||||
}
|
||||
return m_comboPackageCache;
|
||||
}
|
||||
|
||||
@@ -278,6 +324,8 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, TrackedRecord<InventoryItem>>& DataStore::getInventoryItems()
|
||||
{
|
||||
auto inventoryItems = loadRecords<InventoryItem, SerializedInventoryItem>(m_inventoryItems);
|
||||
refreshCache(m_inventoryItemCache, inventoryItems);
|
||||
return m_inventoryItemCache;
|
||||
}
|
||||
|
||||
@@ -291,6 +339,49 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, TrackedRecord<ServiceBooking>>& DataStore::getServiceBookings()
|
||||
{
|
||||
util::Map<std::string, TrackedRecord<ServiceBooking>> serviceBookings = loadRecords<ServiceBooking, SerializedServiceBooking>(m_serviceBookings);
|
||||
refreshCache(m_serviceBookingCache, serviceBookings);
|
||||
auto& users = getUsers();
|
||||
auto& services = getServices();
|
||||
size_t numberOfServiceBookings = m_serviceBookingCache.getSize();
|
||||
for (int iteratorOne = 0; iteratorOne < numberOfServiceBookings; iteratorOne++)
|
||||
{
|
||||
ServiceBooking* serviceBooking = m_serviceBookingCache.getValueAt(iteratorOne).data;
|
||||
auto& serviceIds = serviceBooking->getServiceIDs();
|
||||
util::Map<std::string, Service*> servicesInBooking;
|
||||
for (int iteratorTwo = 0; iteratorTwo < serviceIds.getSize(); iteratorTwo++)
|
||||
{
|
||||
const std::string& currentServiceId = serviceIds[iteratorTwo];
|
||||
int serviceIndex = services.find(currentServiceId);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid service index.");
|
||||
}
|
||||
auto currentService = services.getValueAt(serviceIndex);
|
||||
servicesInBooking[currentServiceId] = currentService.data;
|
||||
}
|
||||
serviceBooking->setServices(servicesInBooking);
|
||||
if (!serviceBooking->getCustomerId().empty())
|
||||
{
|
||||
int userIndex = users.find(serviceBooking->getCustomerId());
|
||||
if (userIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid user index.");
|
||||
}
|
||||
auto customer = users.getValueAt(userIndex);
|
||||
serviceBooking->setCustomer(customer.data);
|
||||
}
|
||||
if (!serviceBooking->getAssignedTechnicianId().empty())
|
||||
{
|
||||
int technicianIndex = users.find(serviceBooking->getAssignedTechnicianId());
|
||||
if (technicianIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid technician index.");
|
||||
}
|
||||
auto technician = users.getValueAt(technicianIndex);
|
||||
serviceBooking->setAssignedTechnician(technician.data);
|
||||
}
|
||||
}
|
||||
return m_serviceBookingCache;
|
||||
}
|
||||
|
||||
@@ -304,9 +395,51 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, TrackedRecord<JobCard>>& DataStore::getJobCards()
|
||||
{
|
||||
util::Map<std::string, TrackedRecord<JobCard>> jobCards = loadRecords<JobCard, SerializedJobCard>(m_jobCards);
|
||||
refreshCache(m_jobCardCache, jobCards);
|
||||
auto& serviceBookings = getServiceBookings();
|
||||
auto& services = getServices();
|
||||
auto& users = getUsers();
|
||||
int numberOfJobCards = m_jobCardCache.getSize();
|
||||
for (int iterator = 0; iterator < numberOfJobCards; iterator++)
|
||||
{
|
||||
JobCard* jobCard = m_jobCardCache.getValueAt(iterator).data;
|
||||
if (!jobCard)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const std::string& bookingId = jobCard->getBookingId();
|
||||
int bookingIndex = serviceBookings.find(bookingId);
|
||||
if (bookingIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid booking ID: " + bookingId);
|
||||
}
|
||||
auto trackedBooking = serviceBookings.getValueAt(bookingIndex);
|
||||
jobCard->setBooking(trackedBooking.data);
|
||||
const std::string& serviceId = jobCard->getServiceId();
|
||||
int serviceIndex = services.find(serviceId);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid service ID: " + serviceId);
|
||||
}
|
||||
auto trackedService = services.getValueAt(serviceIndex);
|
||||
jobCard->setService(trackedService.data);
|
||||
const std::string& technicianId = jobCard->getTechnicianId();
|
||||
if (!technicianId.empty())
|
||||
{
|
||||
int technicianIndex = users.find(technicianId);
|
||||
if (technicianIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Invalid technician ID: " + technicianId);
|
||||
}
|
||||
auto trackedTechnician = users.getValueAt(technicianIndex);
|
||||
jobCard->setTechnician(trackedTechnician.data);
|
||||
}
|
||||
}
|
||||
return m_jobCardCache;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Function: getInvoices
|
||||
Description: Retrieves all invoice records from the datastore.
|
||||
@@ -426,6 +559,7 @@ Returns:
|
||||
*/
|
||||
void DataStore::saveServices()
|
||||
{
|
||||
saveRecords<Service, SerializedService>(m_services, m_serviceCache);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -438,6 +572,7 @@ Returns:
|
||||
*/
|
||||
void DataStore::saveComboPackages()
|
||||
{
|
||||
saveRecords<ComboPackage, SerializedComboPackage>(m_comboPackages, m_comboPackageCache);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -450,6 +585,7 @@ Returns:
|
||||
*/
|
||||
void DataStore::saveInventoryItems()
|
||||
{
|
||||
saveRecords<InventoryItem, SerializedInventoryItem>(m_inventoryItems, m_inventoryItemCache);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -462,6 +598,7 @@ Returns:
|
||||
*/
|
||||
void DataStore::saveServiceBookings()
|
||||
{
|
||||
saveRecords<ServiceBooking, SerializedServiceBooking>(m_serviceBookings, m_serviceBookingCache);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -474,6 +611,7 @@ Returns:
|
||||
*/
|
||||
void DataStore::saveJobCards()
|
||||
{
|
||||
saveRecords<JobCard, SerializedJobCard>(m_jobCards, m_jobCardCache);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -11,6 +11,7 @@ Date: 19-May-2026
|
||||
#include "Map.h"
|
||||
#include "MappingInfo.h"
|
||||
#include "TrackedRecord.h"
|
||||
#include "SerializedRecords.h"
|
||||
#include "SharedMemory.h"
|
||||
#include "User.h"
|
||||
#include "Notification.h"
|
||||
|
||||
@@ -9,6 +9,7 @@ Date: 19-May-2026
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "SerializedRecords.h"
|
||||
#include "ComboPackage.h"
|
||||
#include "Service.h"
|
||||
#include "Factory.h"
|
||||
@@ -28,7 +29,8 @@ Returns:
|
||||
ComboPackage::ComboPackage()
|
||||
: m_id("CMP" + std::to_string(++m_uid)),
|
||||
m_status(util::State::ACTIVE),
|
||||
m_discountPercentage(0.0) {}
|
||||
m_discountPercentage(0.0) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: ComboPackage
|
||||
@@ -270,72 +272,38 @@ static util::Vector<std::string> getServiceIDsAsVector(const std::string& servic
|
||||
|
||||
/*
|
||||
Function: serialize
|
||||
Description: Serializes the combo package into a CSV-formatted string.
|
||||
Description: Serializes the ComboPackage object into a SerializedComboPackage record.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- std::string: Serialized combo package record
|
||||
- SerializedComboPackage: Serialized representation of the combo package
|
||||
*/
|
||||
std::string ComboPackage::serialize() const
|
||||
SerializedComboPackage ComboPackage::serialize() const
|
||||
{
|
||||
std::ostringstream serializedComboPackage;
|
||||
serializedComboPackage << m_id << ','
|
||||
<< m_packageName << ','
|
||||
<< m_discountPercentage << ','
|
||||
<< getServiceIDsAsString(m_serviceIDs) << ','
|
||||
<< util::getStateString(m_status);
|
||||
return serializedComboPackage.str();
|
||||
SerializedComboPackage serialized = {};
|
||||
strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
|
||||
strcpy_s(serialized.packageName, sizeof(serialized.packageName), m_packageName.c_str());
|
||||
strcpy_s(serialized.serviceIDs, sizeof(serialized.serviceIDs), getServiceIDsAsString(m_serviceIDs).c_str());
|
||||
serialized.discountPercentage = m_discountPercentage;
|
||||
serialized.status = m_status;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: deserialize
|
||||
Description: Deserializes a CSV-formatted string into a ComboPackage object.
|
||||
Description: Deserializes a SerializedComboPackage record into a ComboPackage object.
|
||||
Parameters:
|
||||
- record: const std::string&, serialized combo package record
|
||||
- serializedComboPackage: const SerializedComboPackage&, 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)
|
||||
ComboPackage* ComboPackage::deserialize(const SerializedComboPackage& serializedComboPackage)
|
||||
{
|
||||
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);
|
||||
util::Vector<std::string> serviceIDs = getServiceIDsAsVector(serializedComboPackage.serviceIDs);
|
||||
return Factory::getObject<ComboPackage>(
|
||||
id,
|
||||
packageName,
|
||||
discountPercentage,
|
||||
serializedComboPackage.id,
|
||||
serializedComboPackage.packageName,
|
||||
serializedComboPackage.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";
|
||||
}
|
||||
serializedComboPackage.status);
|
||||
}
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
void setDiscountPercentage(double discountPercentage);
|
||||
void setServices(const util::Map<std::string, Service*>& services);
|
||||
void setState(util::State status);
|
||||
std::string serialize() const;
|
||||
static ComboPackage* deserialize(const std::string&);
|
||||
static std::string getHeaders();
|
||||
SerializedComboPackage serialize() const;
|
||||
static ComboPackage* deserialize(const SerializedComboPackage&);
|
||||
};
|
||||
+23
-56
@@ -8,6 +8,7 @@ Date: 19-May-2026
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "SerializedRecords.h"
|
||||
#include "Factory.h"
|
||||
#include "StringHelper.h"
|
||||
#include "InventoryItem.h"
|
||||
@@ -27,7 +28,8 @@ InventoryItem::InventoryItem()
|
||||
: m_id("IIM" + std::to_string(++m_uid)),
|
||||
m_quantity(0),
|
||||
m_status(util::State::ACTIVE),
|
||||
m_price(0.0) {}
|
||||
m_price(0.0) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: InventoryItem
|
||||
@@ -45,7 +47,8 @@ InventoryItem::InventoryItem(const std::string& partName, int quantity, double p
|
||||
m_partName(partName),
|
||||
m_quantity(quantity),
|
||||
m_status(util::State::ACTIVE),
|
||||
m_price(price) {}
|
||||
m_price(price) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: InventoryItem (parameterized constructor with ID)
|
||||
@@ -206,73 +209,37 @@ void InventoryItem::setState(util::State status)
|
||||
|
||||
/*
|
||||
Function: serialize
|
||||
Description: Serializes the inventory item into a CSV-formatted string.
|
||||
Description: Serializes the InventoryItem object into a SerializedInventoryItem record.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- std::string: Serialized inventory item record
|
||||
- SerializedInventoryItem: Serialized representation of the inventory item
|
||||
*/
|
||||
std::string InventoryItem::serialize() const
|
||||
SerializedInventoryItem InventoryItem::serialize() const
|
||||
{
|
||||
std::ostringstream serializedInventoryItem;
|
||||
serializedInventoryItem << m_id << ','
|
||||
<< m_partName << ','
|
||||
<< m_quantity << ','
|
||||
<< m_price << ','
|
||||
<< util::getStateString(m_status);
|
||||
return serializedInventoryItem.str();
|
||||
SerializedInventoryItem serialized = {};
|
||||
strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
|
||||
strcpy_s(serialized.partName, sizeof(serialized.partName), m_partName.c_str());
|
||||
serialized.quantity = m_quantity;
|
||||
serialized.price = m_price;
|
||||
serialized.status = m_status;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: deserialize
|
||||
Description: Deserializes a CSV-formatted string into an InventoryItem object.
|
||||
Description: Deserializes a SerializedInventoryItem record into an InventoryItem object.
|
||||
Parameters:
|
||||
- record: const std::string&, serialized inventory item record
|
||||
- serializedInventoryItem: const SerializedInventoryItem&, 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)
|
||||
InventoryItem* InventoryItem::deserialize(const SerializedInventoryItem& serializedInventoryItem)
|
||||
{
|
||||
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<InventoryItem>(
|
||||
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";
|
||||
serializedInventoryItem.id,
|
||||
serializedInventoryItem.partName,
|
||||
serializedInventoryItem.quantity,
|
||||
serializedInventoryItem.price,
|
||||
serializedInventoryItem.status);
|
||||
}
|
||||
@@ -6,11 +6,12 @@ Author: Trenser
|
||||
Date: 19-May-2026
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Enums.h"
|
||||
|
||||
struct SerializedInventoryItem;
|
||||
|
||||
class InventoryItem
|
||||
{
|
||||
private:
|
||||
@@ -34,7 +35,6 @@ 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();
|
||||
SerializedInventoryItem serialize() const;
|
||||
static InventoryItem* deserialize(const SerializedInventoryItem&);
|
||||
};
|
||||
@@ -9,6 +9,7 @@ Date:19-May-2026
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "SerializedRecords.h"
|
||||
#include "JobCard.h"
|
||||
#include "Factory.h"
|
||||
#include "StringHelper.h"
|
||||
@@ -28,7 +29,8 @@ JobCard::JobCard()
|
||||
m_booking(nullptr),
|
||||
m_service(nullptr),
|
||||
m_technician(nullptr),
|
||||
m_status(util::ServiceJobStatus()) {}
|
||||
m_status(util::ServiceJobStatus()) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: JobCard
|
||||
@@ -65,7 +67,8 @@ JobCard::JobCard(const std::string& bookingId,
|
||||
m_technician(technician),
|
||||
m_assignedDate(assignedDate),
|
||||
m_status(status),
|
||||
m_completionDate(completionDate) {}
|
||||
m_completionDate(completionDate) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: JobCard (parameterized constructor with ID)
|
||||
@@ -351,79 +354,41 @@ void JobCard::setCompletionDate(const util::Timestamp& completionDate)
|
||||
|
||||
/*
|
||||
Function: serialize
|
||||
Description: Serializes the job card into a CSV-formatted string.
|
||||
Description: Serializes the JobCard object into a SerializedJobCard record.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- std::string: Serialized job card record
|
||||
- SerializedJobCard: Serialized representation of the job card
|
||||
*/
|
||||
std::string JobCard::serialize() const
|
||||
SerializedJobCard 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();
|
||||
SerializedJobCard serialized = {};
|
||||
strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
|
||||
strcpy_s(serialized.bookingId, sizeof(serialized.bookingId), m_bookingId.c_str());
|
||||
strcpy_s(serialized.serviceId, sizeof(serialized.serviceId), m_serviceId.c_str());
|
||||
strcpy_s(serialized.technicianId, sizeof(serialized.technicianId), m_technicianId.c_str());
|
||||
serialized.assignedDate = m_assignedDate;
|
||||
serialized.status = m_status;
|
||||
serialized.completionDate = m_completionDate;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: deserialize
|
||||
Description: Deserializes a CSV-formatted string into a JobCard object.
|
||||
Description: Deserializes a SerializedJobCard record into a JobCard object.
|
||||
Parameters:
|
||||
- record: const std::string&, serialized job card record
|
||||
- serializedJobCard: const SerializedJobCard&, 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)
|
||||
JobCard* JobCard::deserialize(const SerializedJobCard& serializedJobCard)
|
||||
{
|
||||
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<JobCard>(
|
||||
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";
|
||||
serializedJobCard.id,
|
||||
serializedJobCard.bookingId,
|
||||
serializedJobCard.serviceId,
|
||||
serializedJobCard.technicianId,
|
||||
serializedJobCard.assignedDate,
|
||||
serializedJobCard.status,
|
||||
serializedJobCard.completionDate);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ Date:19-May-2026
|
||||
class ServiceBooking;
|
||||
class Service;
|
||||
class User;
|
||||
struct SerializedJobCard;
|
||||
|
||||
class JobCard
|
||||
{
|
||||
@@ -34,11 +35,11 @@ public:
|
||||
JobCard();
|
||||
JobCard(const std::string& bookingId,
|
||||
ServiceBooking* booking,
|
||||
Service* service,
|
||||
const std::string& serviceId,
|
||||
const std::string& technicianId,
|
||||
User* technician,
|
||||
const util::Timestamp& assignedDate,
|
||||
Service* service,
|
||||
const std::string& serviceId,
|
||||
const std::string& technicianId,
|
||||
User* technician,
|
||||
const util::Timestamp& assignedDate,
|
||||
util::ServiceJobStatus status,
|
||||
const util::Timestamp& completionDate
|
||||
);
|
||||
@@ -70,7 +71,6 @@ public:
|
||||
void setAssignedDate(const util::Timestamp& assignedDate);
|
||||
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();
|
||||
SerializedJobCard serialize() const;
|
||||
static JobCard* deserialize(const SerializedJobCard&);
|
||||
};
|
||||
@@ -8,6 +8,7 @@ Date: 19-May-2026
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include "SerializedRecords.h"
|
||||
#include "Service.h"
|
||||
#include "InventoryItem.h"
|
||||
#include "StringHelper.h"
|
||||
@@ -27,7 +28,8 @@ Returns:
|
||||
Service::Service()
|
||||
: m_id("SRV" + std::to_string(++m_uid)),
|
||||
m_status(util::State::ACTIVE),
|
||||
m_laborCost(0.0) {}
|
||||
m_laborCost(0.0) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: Service
|
||||
@@ -44,7 +46,7 @@ Service::Service(const std::string& name, const util::Map<std::string, Inventory
|
||||
m_name(name),
|
||||
m_requiredInventoryItems(requiredInventoryItems),
|
||||
m_status(util::State::ACTIVE),
|
||||
m_laborCost(laborCost)
|
||||
m_laborCost(laborCost)
|
||||
{
|
||||
int numberOfInventoryItems = m_requiredInventoryItems.getSize();
|
||||
auto inventoryItemPointers = m_requiredInventoryItems.getValues();
|
||||
@@ -266,72 +268,38 @@ static util::Vector<std::string> getInventoryItemIDsAsVector(const std::string&
|
||||
|
||||
/*
|
||||
Function: serialize
|
||||
Description: Serializes the service into a CSV-formatted string.
|
||||
Description: Serializes the Service object into a SerializedService record.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- std::string: Serialized service record
|
||||
- SerializedService: Serialized representation of the service
|
||||
*/
|
||||
std::string Service::serialize() const
|
||||
SerializedService Service::serialize() const
|
||||
{
|
||||
std::ostringstream serializedService;
|
||||
serializedService << m_id << ','
|
||||
<< m_name << ','
|
||||
<< getInventoryItemIDsAsString(m_requiredInventoryItemIDs) << ','
|
||||
<< m_laborCost << ','
|
||||
<< util::getStateString(m_status);
|
||||
return serializedService.str();
|
||||
SerializedService serialized = {};
|
||||
strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
|
||||
strcpy_s(serialized.name, sizeof(serialized.name), m_name.c_str());
|
||||
strcpy_s(serialized.inventoryItemIDs, sizeof(serialized.inventoryItemIDs), getInventoryItemIDsAsString(m_requiredInventoryItemIDs).c_str());
|
||||
serialized.laborCost = m_laborCost;
|
||||
serialized.status = m_status;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: deserialize
|
||||
Description: Deserializes a CSV-formatted string into a Service object.
|
||||
Description: Deserializes a SerializedService record into a Service object.
|
||||
Parameters:
|
||||
- record: const std::string&, serialized service record
|
||||
- serializedService: const SerializedService&, 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)
|
||||
Service* Service::deserialize(const SerializedService& serializedService)
|
||||
{
|
||||
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<std::string> inventoryItemIDs = getInventoryItemIDsAsVector(inventoryItemIDsString);
|
||||
try
|
||||
{
|
||||
laborCost = std::stod(laborCostString);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw std::runtime_error("Invalid labor cost");
|
||||
}
|
||||
util::State status = util::getState(statusString);
|
||||
util::Vector<std::string> inventoryItemIDs = getInventoryItemIDsAsVector(serializedService.inventoryItemIDs);
|
||||
return Factory::getObject<Service>(
|
||||
id,
|
||||
name,
|
||||
serializedService.id,
|
||||
serializedService.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";
|
||||
serializedService.laborCost,
|
||||
serializedService.status);
|
||||
}
|
||||
@@ -6,7 +6,6 @@ Author: Trenser
|
||||
Date: 19-May-2026
|
||||
*/
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
@@ -14,6 +13,7 @@ Date: 19-May-2026
|
||||
#include "Enums.h"
|
||||
|
||||
class InventoryItem;
|
||||
struct SerializedService;
|
||||
|
||||
class Service
|
||||
{
|
||||
@@ -40,7 +40,6 @@ public:
|
||||
void setRequiredInventoryItems(const util::Map<std::string, InventoryItem*>& requiredInventoryItems);
|
||||
void setLaborCost(double laborCost);
|
||||
void setState(util::State status);
|
||||
std::string serialize() const;
|
||||
static Service* deserialize(const std::string&);
|
||||
static std::string getHeaders();
|
||||
SerializedService serialize() const;
|
||||
static Service* deserialize(const SerializedService&);
|
||||
};
|
||||
+30
-65
@@ -6,8 +6,10 @@ Description: Implementation file containing the method definitions of the
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include "SerializedRecords.h"
|
||||
#include "ServiceBooking.h"
|
||||
#include "Service.h"
|
||||
#include "Enums.h"
|
||||
@@ -28,7 +30,8 @@ ServiceBooking::ServiceBooking()
|
||||
m_customer(nullptr),
|
||||
m_assignedTechnician(nullptr),
|
||||
m_status(util::ServiceJobStatus::PENDING),
|
||||
m_discountPercentage(0.0) {}
|
||||
m_discountPercentage(0.0) {
|
||||
}
|
||||
|
||||
/*
|
||||
Function: ServiceBooking
|
||||
@@ -437,84 +440,46 @@ static util::Vector<std::string> getServiceIDsAsVector(const std::string& servic
|
||||
|
||||
/*
|
||||
Function: serialize
|
||||
Description: Serializes the service booking into a CSV-formatted string.
|
||||
Description: Serializes the ServiceBooking object into a SerializedServiceBooking record.
|
||||
Parameters:
|
||||
- None
|
||||
Returns:
|
||||
- std::string: Serialized booking record
|
||||
- SerializedServiceBooking: Serialized representation of the service booking
|
||||
*/
|
||||
std::string ServiceBooking::serialize() const
|
||||
SerializedServiceBooking 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();
|
||||
SerializedServiceBooking serialized = {};
|
||||
strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str());
|
||||
strcpy_s(serialized.serviceIDs, sizeof(serialized.serviceIDs), getServiceIDsAsString(m_serviceIDs).c_str());
|
||||
strcpy_s(serialized.customerId, sizeof(serialized.customerId), m_customerId.c_str());
|
||||
strcpy_s(serialized.vehicleNumber, sizeof(serialized.vehicleNumber), m_vehicleNumber.c_str());
|
||||
strcpy_s(serialized.vehicleBrand, sizeof(serialized.vehicleBrand), m_vehicleBrand.c_str());
|
||||
strcpy_s(serialized.vehicleModel, sizeof(serialized.vehicleModel), m_vehicleModel.c_str());
|
||||
strcpy_s(serialized.assignedTechnicianId, sizeof(serialized.assignedTechnicianId), m_assignedTechnicianId.c_str());
|
||||
serialized.status = m_status;
|
||||
serialized.discountPercentage = m_discountPercentage;
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: deserialize
|
||||
Description: Deserializes a CSV-formatted string into a ServiceBooking object.
|
||||
Description: Deserializes a SerializedServiceBooking record into a ServiceBooking object.
|
||||
Parameters:
|
||||
- record: const std::string&, serialized booking record
|
||||
- serializedServiceBooking: const SerializedServiceBooking&, serialized service 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)
|
||||
ServiceBooking* ServiceBooking::deserialize(const SerializedServiceBooking& serializedServiceBooking)
|
||||
{
|
||||
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<std::string> serviceIDs = getServiceIDsAsVector(serviceIDsString);
|
||||
try
|
||||
{
|
||||
discountPercentage = std::stod(discountPercentageString);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
throw std::runtime_error("Invalid discount percentage");
|
||||
}
|
||||
util::ServiceJobStatus status = util::getServiceJobStatus(serviceJobStatusString);
|
||||
util::Vector<std::string> serviceIDs = getServiceIDsAsVector(serializedServiceBooking.serviceIDs);
|
||||
return Factory::getObject<ServiceBooking>(
|
||||
id,
|
||||
status,
|
||||
serializedServiceBooking.id,
|
||||
serializedServiceBooking.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";
|
||||
serializedServiceBooking.customerId,
|
||||
serializedServiceBooking.vehicleNumber,
|
||||
serializedServiceBooking.vehicleBrand,
|
||||
serializedServiceBooking.vehicleModel,
|
||||
serializedServiceBooking.assignedTechnicianId,
|
||||
serializedServiceBooking.discountPercentage);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ Description: Header file declaring the ServiceBooking class, which represents
|
||||
Author: Trenser
|
||||
Date:19-May-2026
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Map.h"
|
||||
@@ -14,6 +15,7 @@ Date:19-May-2026
|
||||
|
||||
class Service;
|
||||
class User;
|
||||
struct SerializedServiceBooking;
|
||||
|
||||
class ServiceBooking
|
||||
{
|
||||
@@ -78,7 +80,6 @@ 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();
|
||||
SerializedServiceBooking serialize() const;
|
||||
static ServiceBooking* deserialize(const SerializedServiceBooking&);
|
||||
};
|
||||
+16
-4
@@ -10,6 +10,8 @@ Date:19-May-2026
|
||||
#include <stdexcept>
|
||||
#include "AuthenticationManagementService.h"
|
||||
#include "User.h"
|
||||
#include "Utility.h"
|
||||
#include "DataStoreLockGuard.h"
|
||||
|
||||
User* AuthenticationManagementService::m_authenticatedUser = nullptr;
|
||||
|
||||
@@ -24,11 +26,12 @@ Return type: bool - true if login successful, false otherwise
|
||||
*/
|
||||
bool AuthenticationManagementService::login(const std::string& username, const std::string& password)
|
||||
{
|
||||
util::Map<std::string, User*> users = m_dataStore.getUsers();
|
||||
int usersMapSize = users.getSize();
|
||||
for (int index = 0; index < usersMapSize; index++)
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedUserMap = m_dataStore.getUsers();
|
||||
int trackedUserMapSize = trackedUserMap.getSize();
|
||||
for (int index = 0; index < trackedUserMapSize; index++)
|
||||
{
|
||||
User* user = users.getValueAt(index);
|
||||
User* user = trackedUserMap.getValueAt(index).data;
|
||||
if (username == user->getUserName())
|
||||
{
|
||||
if (password == user->getPassword())
|
||||
@@ -74,9 +77,18 @@ Return type: void
|
||||
*/
|
||||
void AuthenticationManagementService::changePassword(const std::string& newPassword)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedUsersMap = m_dataStore.getUsers();
|
||||
if (m_authenticatedUser == nullptr)
|
||||
{
|
||||
throw std::runtime_error("There is no user currently logged in!");
|
||||
}
|
||||
int index = trackedUsersMap.find(m_authenticatedUser->getId());
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::runtime_error("User does not exist!\n");
|
||||
}
|
||||
m_authenticatedUser->setPassword(newPassword);
|
||||
trackedUsersMap.getValueAt(index).state = RecordState::MODIFIED;
|
||||
m_dataStore.saveUsers();
|
||||
}
|
||||
|
||||
+58
-32
@@ -57,18 +57,19 @@ Returns:
|
||||
*/
|
||||
void InventoryManagementService::sendLowStockAlerts()
|
||||
{
|
||||
auto& inventoryItems = m_dataStore.getInventoryItems();
|
||||
if (inventoryItems.isEmpty())
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemsMap = m_dataStore.getInventoryItems();
|
||||
auto& trackedUserMap = m_dataStore.getUsers();
|
||||
if (trackedInventoryItemsMap.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
int inventoryItemsSize = inventoryItems.getSize();
|
||||
auto& usersMap = m_dataStore.getUsers();
|
||||
int usersMapSize = usersMap.getSize();
|
||||
int inventoryItemsSize = trackedInventoryItemsMap.getSize();
|
||||
int usersMapSize = trackedUserMap.getSize();
|
||||
util::Vector<User*> adminUsers;
|
||||
for (int index = 0; index < usersMapSize; index++)
|
||||
{
|
||||
User* user = usersMap.getValueAt(index);
|
||||
User* user = trackedUserMap.getValueAt(index).data;
|
||||
if (user->getUserType() == util::UserType::ADMIN)
|
||||
{
|
||||
adminUsers.push_back(user);
|
||||
@@ -81,7 +82,7 @@ void InventoryManagementService::sendLowStockAlerts()
|
||||
}
|
||||
for (int index = 0; index < inventoryItemsSize; index++)
|
||||
{
|
||||
InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
|
||||
InventoryItem* inventoryItem = trackedInventoryItemsMap.getValueAt(index).data;
|
||||
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
|
||||
{
|
||||
sendLowStockAlertsToAdmins(*this, inventoryItem, adminUsers);
|
||||
@@ -100,8 +101,11 @@ Return type: void
|
||||
*/
|
||||
void InventoryManagementService::addInventoryItem(const std::string& partName, int quantity, double price)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
|
||||
InventoryItem* newItem = Factory::getObject<InventoryItem>(partName, quantity, price);
|
||||
m_dataStore.getInventoryItems().insert(newItem->getId(), newItem);
|
||||
trackedInventoryItemMap.insert(newItem->getId(), util::createNewRecord(newItem));
|
||||
m_dataStore.saveInventoryItems();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -113,16 +117,22 @@ Return type: void
|
||||
*/
|
||||
void InventoryManagementService::addInventoryItemStock(const std::string& selectedItemId, int quantity)
|
||||
{
|
||||
int index = m_dataStore.getInventoryItems().find(selectedItemId);
|
||||
if (index != -1)
|
||||
{
|
||||
InventoryItem* item = m_dataStore.getInventoryItems().getValueAt(index);
|
||||
if (item != nullptr)
|
||||
{
|
||||
int totalQuantity = item->getQuantity() + quantity;
|
||||
item->setQuantity(totalQuantity);
|
||||
}
|
||||
}
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
|
||||
int index = trackedInventoryItemMap.find(selectedItemId);
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::runtime_error("Inventory update failed: Item ID '" + selectedItemId + "' not found.");
|
||||
}
|
||||
InventoryItem* item = trackedInventoryItemMap.getValueAt(index).data;
|
||||
if (item == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Inventory update failed. Item does not exist.\n");
|
||||
}
|
||||
int totalQuantity = item->getQuantity() + quantity;
|
||||
item->setQuantity(totalQuantity);
|
||||
trackedInventoryItemMap.getValueAt(index).state = RecordState::MODIFIED;
|
||||
m_dataStore.saveInventoryItems();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -133,7 +143,10 @@ Return type: util::Map<std::string, InventoryItem*>
|
||||
*/
|
||||
util::Map<std::string, InventoryItem*> InventoryManagementService::getInventoryItems()
|
||||
{
|
||||
return m_dataStore.getInventoryItems();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
|
||||
auto inventoryMap = util::getObjects(trackedInventoryItemMap);
|
||||
return inventoryMap;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -144,15 +157,21 @@ Return type: void
|
||||
*/
|
||||
void InventoryManagementService::removeInventoryItem(const std::string& inventoryItemID)
|
||||
{
|
||||
int index = m_dataStore.getInventoryItems().find(inventoryItemID);
|
||||
if (index != -1)
|
||||
{
|
||||
InventoryItem* item = m_dataStore.getInventoryItems().getValueAt(index);
|
||||
if (item != nullptr)
|
||||
{
|
||||
item->setState(util::State::INACTIVE);
|
||||
}
|
||||
}
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
|
||||
int index = trackedInventoryItemMap.find(inventoryItemID);
|
||||
if (index == -1)
|
||||
{
|
||||
throw std::runtime_error("Inventory removal failed: Item ID '" + inventoryItemID + "' not found.");
|
||||
}
|
||||
InventoryItem* item = trackedInventoryItemMap.getValueAt(index).data;
|
||||
if (item == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Inventory removal failed: Item ID does not exist.");
|
||||
}
|
||||
item->setState(util::State::INACTIVE);
|
||||
trackedInventoryItemMap.getValueAt(index).state = RecordState::MODIFIED;
|
||||
m_dataStore.saveInventoryItems();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -163,12 +182,19 @@ Return type: InventoryItem*
|
||||
*/
|
||||
InventoryItem* InventoryManagementService::getInventoryItem(const std::string& inventoryItemID)
|
||||
{
|
||||
int index = m_dataStore.getInventoryItems().find(inventoryItemID);
|
||||
if (index != -1)
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedInventoryItemMap = m_dataStore.getInventoryItems();
|
||||
int index = trackedInventoryItemMap.find(inventoryItemID);
|
||||
if (index == -1)
|
||||
{
|
||||
return m_dataStore.getInventoryItems().getValueAt(index);
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
InventoryItem* inventoryItem = trackedInventoryItemMap.getValueAt(index).data;
|
||||
if (inventoryItem == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Item ID does not exist.");
|
||||
}
|
||||
return inventoryItem;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+136
-63
@@ -24,6 +24,7 @@ Date:19-May-2026
|
||||
#include "Timestamp.h"
|
||||
#include "User.h"
|
||||
#include "UserManagementService.h"
|
||||
#include "DataStoreLockGuard.h"
|
||||
#include "Utility.h"
|
||||
#include "DataStoreLockGuard.h"
|
||||
|
||||
@@ -46,18 +47,19 @@ void ServiceManagementService::purchaseService(const util::Vector<std::string>&
|
||||
{
|
||||
throw std::runtime_error("No user is currently logged in!");
|
||||
}
|
||||
auto& servicesMap = m_dataStore.getServices();
|
||||
auto& serviceBookingMap = m_dataStore.getServiceBookings();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedServicesMap = m_dataStore.getServices();
|
||||
auto& trackedServiceBookingMap = m_dataStore.getServiceBookings();
|
||||
util::Map<std::string, Service*> selectedServices;
|
||||
int selectedServicesCount = serviceIDs.getSize();
|
||||
for (int index = 0; index < selectedServicesCount; index++)
|
||||
{
|
||||
int serviceIndex = servicesMap.find(serviceIDs[index]);
|
||||
int serviceIndex = trackedServicesMap.find(serviceIDs[index]);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Service not found!");
|
||||
}
|
||||
Service* service = servicesMap.getValueAt(serviceIndex);
|
||||
Service* service = trackedServicesMap.getValueAt(serviceIndex).data;
|
||||
selectedServices[service->getId()] = service;
|
||||
}
|
||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, 0);
|
||||
@@ -65,7 +67,7 @@ void ServiceManagementService::purchaseService(const util::Vector<std::string>&
|
||||
{
|
||||
throw std::runtime_error("Failed to create service booking");
|
||||
}
|
||||
serviceBookingMap[serviceBooking->getId()] = serviceBooking;
|
||||
trackedServiceBookingMap[serviceBooking->getId()] = util::createNewRecord(serviceBooking);
|
||||
std::string title = "Service Booking succeeded";
|
||||
std::string message = "Your service booking has been successfully placed with ID " + serviceBooking->getId();
|
||||
sendNotification(authenticatedUser, title, message);
|
||||
@@ -90,21 +92,22 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack
|
||||
{
|
||||
throw std::runtime_error("No user is currently logged in!");
|
||||
}
|
||||
auto& comboPackagesMap = m_dataStore.getComboPackages();
|
||||
auto& serviceBookingMap = m_dataStore.getServiceBookings();
|
||||
int comboPackageIndex = comboPackagesMap.find(comboPackageID);
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedComboPackagesMap = m_dataStore.getComboPackages();
|
||||
auto& trackedServiceBookingMap = m_dataStore.getServiceBookings();
|
||||
int comboPackageIndex = trackedComboPackagesMap.find(comboPackageID);
|
||||
if (comboPackageIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Combo Package not found!");
|
||||
}
|
||||
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
||||
const ComboPackage* comboPackage = trackedComboPackagesMap[comboPackageID].data;
|
||||
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
||||
if (serviceBooking == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Failed to create combo package service booking");
|
||||
}
|
||||
serviceBookingMap[serviceBooking->getId()] = serviceBooking;
|
||||
trackedServiceBookingMap[serviceBooking->getId()] = util::createNewRecord(serviceBooking);
|
||||
std::string title = "Combo Package Service Booking succeeded";
|
||||
std::string message = "Your service booking for the combo package has been successfully placed with ID " + serviceBooking->getId();
|
||||
sendNotification(authenticatedUser, title, message);
|
||||
@@ -205,7 +208,7 @@ Description: Restores inventory quantities for all required items in the service
|
||||
Parameter: ServiceBooking* booking - Pointer to the booking whose inventory items need to be restored
|
||||
Return type: void
|
||||
*/
|
||||
static void restoreInventory(ServiceBooking* booking)
|
||||
static void restoreInventory(ServiceBooking* booking, util::Map<std::string, TrackedRecord<InventoryItem>>& trackedInventoryItems)
|
||||
{
|
||||
const int INCREMENT_VALUE = 1;
|
||||
if (!booking)
|
||||
@@ -224,9 +227,17 @@ static void restoreInventory(ServiceBooking* booking)
|
||||
for (int InventoryIterator = 0; InventoryIterator < items.getSize(); ++InventoryIterator)
|
||||
{
|
||||
InventoryItem* item = items.getValueAt(InventoryIterator);
|
||||
const std::string& currentItemId = item->getId();
|
||||
int itemIndex = trackedInventoryItems.find(currentItemId);
|
||||
if (itemIndex == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto& currentTrackedInventoryItem = trackedInventoryItems.getValueAt(itemIndex);
|
||||
if (item)
|
||||
{
|
||||
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
|
||||
currentTrackedInventoryItem.state = RecordState::MODIFIED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -244,23 +255,28 @@ Parameters:
|
||||
util::UserType userType - Type of user initiating cancellation (CUSTOMER or TECHNICIAN)
|
||||
Return type: void
|
||||
*/
|
||||
static void processBookingCancellation(ServiceBooking* booking,
|
||||
util::Map<std::string, JobCard*>& jobs,
|
||||
static void processBookingCancellation(TrackedRecord<ServiceBooking>& trackedBooking,
|
||||
util::Map<std::string, TrackedRecord<JobCard>>& jobs,
|
||||
ServiceManagementService& currentService,
|
||||
util::UserType userType)
|
||||
util::UserType userType,
|
||||
util::Map<std::string, TrackedRecord<InventoryItem>>& trackedInventoryItems)
|
||||
{
|
||||
ServiceBooking* booking = trackedBooking.data;
|
||||
if (!booking)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const std::string& bookingId = booking->getId();
|
||||
for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator)
|
||||
{
|
||||
JobCard* jobCard = jobs.getValueAt(jobIterator);
|
||||
auto& trackedJobCard = jobs.getValueAt(jobIterator);
|
||||
JobCard* jobCard = trackedJobCard.data;
|
||||
if (!jobCard || jobCard->getBookingId() != booking->getId() || jobCard->getStatus() == util::ServiceJobStatus::CANCELLED)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
jobCard->setStatus(util::ServiceJobStatus::CANCELLED);
|
||||
trackedJobCard.state = RecordState::MODIFIED;
|
||||
if (userType == util::UserType::CUSTOMER)
|
||||
{
|
||||
if (User* technician = booking->getAssignedTechnician())
|
||||
@@ -293,7 +309,8 @@ static void processBookingCancellation(ServiceBooking* booking,
|
||||
}
|
||||
booking->setAssignedTechnician(nullptr);
|
||||
booking->setAssignedTechnicianId("");
|
||||
restoreInventory(booking);
|
||||
trackedBooking.state = RecordState::MODIFIED;
|
||||
restoreInventory(booking, trackedInventoryItems);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -306,22 +323,25 @@ Return type: void
|
||||
*/
|
||||
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& customerID)
|
||||
{
|
||||
auto& users = m_dataStore.getUsers();
|
||||
int userIndex = users.find(customerID);
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedUsers = m_dataStore.getUsers();
|
||||
int userIndex = trackedUsers.find(customerID);
|
||||
if (userIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("User not found: " + customerID);
|
||||
}
|
||||
User* customer = users.getValueAt(userIndex);
|
||||
User* customer = trackedUsers.getValueAt(userIndex).data;
|
||||
if (!customer)
|
||||
{
|
||||
throw std::runtime_error("User not found: " + customerID);
|
||||
}
|
||||
auto& bookings = m_dataStore.getServiceBookings();
|
||||
auto& jobs = m_dataStore.getJobCards();
|
||||
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||
auto& trackedBookings = m_dataStore.getServiceBookings();
|
||||
auto& trackedJobs = m_dataStore.getJobCards();
|
||||
auto& trackedInventoryItems = m_dataStore.getInventoryItems();
|
||||
for (int iteratorOne = 0; iteratorOne < trackedBookings.getSize(); iteratorOne++)
|
||||
{
|
||||
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||
auto& trackedBooking = trackedBookings.getValueAt(iteratorOne);
|
||||
ServiceBooking* booking = trackedBooking.data;
|
||||
if (!booking)
|
||||
{
|
||||
continue;
|
||||
@@ -336,8 +356,12 @@ void ServiceManagementService::cancelCustomerServiceBookings(const std::string&
|
||||
{
|
||||
continue;
|
||||
}
|
||||
processBookingCancellation(booking, jobs, *this, util::UserType::CUSTOMER);
|
||||
processBookingCancellation(trackedBooking, trackedJobs, *this, util::UserType::CUSTOMER, trackedInventoryItems);
|
||||
}
|
||||
m_dataStore.saveUsers();
|
||||
m_dataStore.saveServiceBookings();
|
||||
m_dataStore.saveJobCards();
|
||||
m_dataStore.saveInventoryItems();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -349,22 +373,25 @@ Return type: void
|
||||
*/
|
||||
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
|
||||
{
|
||||
auto& users = m_dataStore.getUsers();
|
||||
int userIndex = users.find(technicianID);
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedUsers = m_dataStore.getUsers();
|
||||
int userIndex = trackedUsers.find(technicianID);
|
||||
if (userIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("User not found: " + technicianID);
|
||||
}
|
||||
User* technician = users.getValueAt(userIndex);
|
||||
User* technician = trackedUsers.getValueAt(userIndex).data;
|
||||
if (!technician)
|
||||
{
|
||||
throw std::runtime_error("User not found: " + technicianID);
|
||||
}
|
||||
auto& bookings = m_dataStore.getServiceBookings();
|
||||
auto& jobs = m_dataStore.getJobCards();
|
||||
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||
auto& trackedBookings = m_dataStore.getServiceBookings();
|
||||
auto& trackedJobs = m_dataStore.getJobCards();
|
||||
auto& trackedInventoryItems = m_dataStore.getInventoryItems();
|
||||
for (int iteratorOne = 0; iteratorOne < trackedBookings.getSize(); iteratorOne++)
|
||||
{
|
||||
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||
auto& trackedBooking = trackedBookings.getValueAt(iteratorOne);
|
||||
ServiceBooking* booking = trackedBooking.data;
|
||||
if (!booking)
|
||||
{
|
||||
continue;
|
||||
@@ -385,8 +412,12 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia
|
||||
{
|
||||
continue;
|
||||
}
|
||||
processBookingCancellation(booking, jobs, *this, util::UserType::TECHNICIAN);
|
||||
processBookingCancellation(trackedBooking, trackedJobs, *this, util::UserType::TECHNICIAN, trackedInventoryItems);
|
||||
}
|
||||
m_dataStore.saveUsers();
|
||||
m_dataStore.saveInventoryItems();
|
||||
m_dataStore.saveServiceBookings();
|
||||
m_dataStore.saveJobCards();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -400,6 +431,7 @@ Return type: void
|
||||
*/
|
||||
void ServiceManagementService::createComboPackage(const std::string& packageName, const util::Vector<std::string>& serviceIDsInNewCombo, double discountPercentage)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
if (packageName.empty())
|
||||
{
|
||||
throw std::invalid_argument("The Combo Package Name cannot be empty.\n");
|
||||
@@ -412,19 +444,19 @@ void ServiceManagementService::createComboPackage(const std::string& packageName
|
||||
{
|
||||
throw std::invalid_argument("Discount percentage must be between 0 and 100.");
|
||||
}
|
||||
auto& servicesMap = m_dataStore.getServices();
|
||||
auto& trackedServicesMap = m_dataStore.getServices();
|
||||
for (int index = 0; index < serviceIDsInNewCombo.getSize(); index++)
|
||||
{
|
||||
const std::string serviceid = serviceIDsInNewCombo[index];
|
||||
if (servicesMap.find(serviceid) == -1)
|
||||
const std::string& serviceid = serviceIDsInNewCombo[index];
|
||||
if (trackedServicesMap.find(serviceid) == -1)
|
||||
{
|
||||
throw std::runtime_error("Service ID not found: " + serviceid);
|
||||
}
|
||||
}
|
||||
auto& comboPackageMap = m_dataStore.getComboPackages();
|
||||
for (int iterator = 0; iterator < comboPackageMap.getSize(); iterator++)
|
||||
auto& trackedComboPackageMap = m_dataStore.getComboPackages();
|
||||
for (int iterator = 0; iterator < trackedComboPackageMap.getSize(); iterator++)
|
||||
{
|
||||
ComboPackage* existingCombos = comboPackageMap.getValueAt(iterator);
|
||||
ComboPackage* existingCombos = trackedComboPackageMap.getValueAt(iterator).data;
|
||||
const util::Map<std::string, Service*>& servicesInsideExistingCombos = existingCombos->getServices();
|
||||
if (servicesInsideExistingCombos.getSize() == serviceIDsInNewCombo.getSize())
|
||||
{
|
||||
@@ -448,15 +480,16 @@ void ServiceManagementService::createComboPackage(const std::string& packageName
|
||||
for (int iteratorOne = 0; iteratorOne < serviceIDsInNewCombo.getSize(); iteratorOne++)
|
||||
{
|
||||
const std::string& serviceId = serviceIDsInNewCombo[iteratorOne];
|
||||
int serviceIndex = servicesMap.find(serviceId);
|
||||
int serviceIndex = trackedServicesMap.find(serviceId);
|
||||
if (serviceIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Service ID not found: " + serviceId);
|
||||
}
|
||||
selectedServices.insert(serviceId, servicesMap.getValueAt(serviceIndex));
|
||||
selectedServices.insert(serviceId, trackedServicesMap.getValueAt(serviceIndex).data);
|
||||
}
|
||||
ComboPackage* newComboPackage = Factory::getObject<ComboPackage>(packageName, discountPercentage, selectedServices);
|
||||
comboPackageMap.insert(newComboPackage->getId(), newComboPackage);
|
||||
trackedComboPackageMap.insert(newComboPackage->getId(), util::createNewRecord(newComboPackage));
|
||||
m_dataStore.saveComboPackages();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -467,7 +500,10 @@ Return type: util::Map<std::string, ComboPackage*>
|
||||
*/
|
||||
util::Map<std::string, ComboPackage*> ServiceManagementService::getComboPackages()
|
||||
{
|
||||
return m_dataStore.getComboPackages();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
util::Map<std::string, ComboPackage*> comboPackages;
|
||||
comboPackages = util::getObjects(m_dataStore.getComboPackages());
|
||||
return comboPackages;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -478,14 +514,17 @@ Return type: void
|
||||
*/
|
||||
void ServiceManagementService::removeComboPackage(const std::string& comboPackageID)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
bool removed = false;
|
||||
util::Map<std::string, ComboPackage*>& currentComboPackages = m_dataStore.getComboPackages();
|
||||
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||
auto& trackedComboPackages = m_dataStore.getComboPackages();
|
||||
for (int iterator = 0; iterator < trackedComboPackages.getSize(); iterator++)
|
||||
{
|
||||
ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
|
||||
auto& comboPackage = trackedComboPackages.getValueAt(iterator);
|
||||
ComboPackage* currentComboPackage = comboPackage.data;
|
||||
if (currentComboPackage && currentComboPackage->getId() == comboPackageID)
|
||||
{
|
||||
currentComboPackage->setState(util::State::INACTIVE);
|
||||
comboPackage.state = RecordState::MODIFIED;
|
||||
removed = true;
|
||||
break;
|
||||
}
|
||||
@@ -494,6 +533,7 @@ void ServiceManagementService::removeComboPackage(const std::string& comboPackag
|
||||
{
|
||||
throw std::runtime_error("Combo package with ID '" + comboPackageID + "' not found.");
|
||||
}
|
||||
m_dataStore.saveComboPackages();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -506,7 +546,10 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, ServiceBooking*> ServiceManagementService::getServiceBookings()
|
||||
{
|
||||
return m_dataStore.getServiceBookings();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
util::Map<std::string, ServiceBooking*> serviceBookings;
|
||||
serviceBookings = util::getObjects(m_dataStore.getServiceBookings());
|
||||
return serviceBookings;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -545,9 +588,10 @@ Throws:
|
||||
*/
|
||||
void ServiceManagementService::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
UserManagementService m_userManagementService;
|
||||
ServiceBooking* currentBooking = getServiceBooking(bookingID);
|
||||
auto& currentJobCards = m_dataStore.getJobCards();
|
||||
auto& currentTrackedJobCards = m_dataStore.getJobCards();
|
||||
if (currentBooking == nullptr)
|
||||
{
|
||||
throw std::runtime_error("Service Booking not available");
|
||||
@@ -593,7 +637,7 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
||||
JobCard* jobCard = Factory::getObject<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
|
||||
if (jobCard)
|
||||
{
|
||||
currentJobCards.insert(jobCard->getId(), jobCard);
|
||||
currentTrackedJobCards.insert(jobCard->getId(), util::createNewRecord(jobCard));
|
||||
sendNotification(selectedTechnician, title, message);
|
||||
}
|
||||
else
|
||||
@@ -603,6 +647,7 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
||||
title = "Technician assigned";
|
||||
message = "A technician has been assigned to your Service Booking with ID " + bookingID;
|
||||
sendNotification(currentBooking->getCustomer(), title, message);
|
||||
m_dataStore.saveJobCards();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -620,15 +665,17 @@ Throws:
|
||||
*/
|
||||
void ServiceManagementService::createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
util::Map<std::string, InventoryItem*> currentServiceInventoryItems;
|
||||
auto inventoryItems = m_dataStore.getInventoryItems();
|
||||
auto& trackedInventoryItems = m_dataStore.getInventoryItems();
|
||||
auto& currentServices = m_dataStore.getServices();
|
||||
for (int iteratorOne =0; iteratorOne < inventoryItemIDs.getSize(); iteratorOne++)
|
||||
{
|
||||
std::string currentItemID = inventoryItemIDs[iteratorOne];
|
||||
bool itemFound = false;
|
||||
for (int iteratorTwo = 0; iteratorTwo < inventoryItems.getSize(); iteratorTwo++)
|
||||
for (int iteratorTwo = 0; iteratorTwo < trackedInventoryItems.getSize(); iteratorTwo++)
|
||||
{
|
||||
InventoryItem* currentInventoryItem = inventoryItems.getValueAt(iteratorTwo);
|
||||
InventoryItem* currentInventoryItem = trackedInventoryItems.getValueAt(iteratorTwo).data;
|
||||
if (currentInventoryItem && currentInventoryItem->getId() == currentItemID)
|
||||
{
|
||||
itemFound = true;
|
||||
@@ -646,12 +693,12 @@ void ServiceManagementService::createService(const std::string& name, const util
|
||||
{
|
||||
throw std::runtime_error("Unable to create new service.");
|
||||
}
|
||||
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
||||
if (currentServices.find(newService->getId()) != -1)
|
||||
{
|
||||
throw std::runtime_error("Service with this ID Already exists.");
|
||||
}
|
||||
currentServices.insert(newService->getId(), newService);
|
||||
currentServices.insert(newService->getId(), util::createNewRecord(newService));
|
||||
m_dataStore.saveServices();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -664,7 +711,10 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, Service*> ServiceManagementService::getServices()
|
||||
{
|
||||
return m_dataStore.getServices();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
util::Map<std::string, Service*> services;
|
||||
services = util::getObjects(m_dataStore.getServices());
|
||||
return services;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -679,14 +729,19 @@ Throws:
|
||||
*/
|
||||
void ServiceManagementService::removeService(const std::string& serviceID)
|
||||
{
|
||||
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
||||
util::Map<std::string, ComboPackage*>& currentComboPackages = m_dataStore.getComboPackages();
|
||||
if (currentServices.find(serviceID) != -1)
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& currentTrackedServices = m_dataStore.getServices();
|
||||
auto& currentTrackedComboPackages = m_dataStore.getComboPackages();
|
||||
if (currentTrackedServices.find(serviceID) != -1)
|
||||
{
|
||||
currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE);
|
||||
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||
int serviceIndex, comboPackageIndex;
|
||||
serviceIndex = currentTrackedServices.find(serviceID);
|
||||
currentTrackedServices.getValueAt(serviceIndex).data->setState(util::State::INACTIVE);
|
||||
currentTrackedServices.getValueAt(serviceIndex).state = RecordState::MODIFIED;
|
||||
for (int iterator = 0; iterator < currentTrackedComboPackages.getSize(); iterator++)
|
||||
{
|
||||
ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
|
||||
comboPackageIndex = iterator;
|
||||
ComboPackage* currentComboPackage = currentTrackedComboPackages.getValueAt(iterator).data;
|
||||
if (currentComboPackage && currentComboPackage->getState() == util::State::ACTIVE)
|
||||
{
|
||||
util::Map<std::string, Service*> currentServices = currentComboPackage->getServices();
|
||||
@@ -696,6 +751,7 @@ void ServiceManagementService::removeService(const std::string& serviceID)
|
||||
if (currentService->getId() == serviceID)
|
||||
{
|
||||
currentComboPackage->setState(util::State::INACTIVE);
|
||||
currentTrackedComboPackages.getValueAt(comboPackageIndex).state = RecordState::MODIFIED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -706,6 +762,8 @@ void ServiceManagementService::removeService(const std::string& serviceID)
|
||||
{
|
||||
throw std::runtime_error("Service not found.");
|
||||
}
|
||||
m_dataStore.saveServices();
|
||||
m_dataStore.saveComboPackages();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -744,11 +802,12 @@ Returns:
|
||||
*/
|
||||
util::Map<std::string, JobCard*> ServiceManagementService::getJobCards(const std::string& technicianID)
|
||||
{
|
||||
util::Map<std::string, JobCard*> jobCards = m_dataStore.getJobCards();
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
auto& trackedJobCards = m_dataStore.getJobCards();
|
||||
util::Map<std::string, JobCard*> technicianJobCards;
|
||||
for (int iterator = 0; iterator < jobCards.getSize(); iterator++)
|
||||
for (int iterator = 0; iterator < trackedJobCards.getSize(); iterator++)
|
||||
{
|
||||
JobCard* currentJobCard = jobCards.getValueAt(iterator);
|
||||
JobCard* currentJobCard = trackedJobCards.getValueAt(iterator).data;
|
||||
if (currentJobCard->getTechnicianId() == technicianID)
|
||||
{
|
||||
technicianJobCards.insert(currentJobCard->getId(), currentJobCard);
|
||||
@@ -797,6 +856,7 @@ Returns:
|
||||
*/
|
||||
void ServiceManagementService::updateJobStatus(const std::string& jobID)
|
||||
{
|
||||
DataStoreLockGuard lock(m_dataStore);
|
||||
AuthenticationManagementService authenticationManagementService;
|
||||
PaymentManagementService paymentManagementService;
|
||||
bool jobStatusUpdated = false, serviceBookingCompleted;
|
||||
@@ -811,8 +871,15 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
|
||||
{
|
||||
throw std::runtime_error("No job cards assigned to the technician.");
|
||||
}
|
||||
auto& trackedJobCards = m_dataStore.getJobCards();
|
||||
auto& trackedServiceBookings = m_dataStore.getServiceBookings();
|
||||
if (currentAssignedJobs.find(jobID) != -1)
|
||||
{
|
||||
int jobIndex = trackedJobCards.find(jobID);
|
||||
if (jobIndex == -1)
|
||||
{
|
||||
throw std::runtime_error("Unable to fetch current job.");
|
||||
}
|
||||
currentJob = currentAssignedJobs.getValueAt(currentAssignedJobs.find(jobID));
|
||||
if (currentJob == nullptr)
|
||||
{
|
||||
@@ -821,16 +888,20 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
|
||||
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
||||
{
|
||||
currentJob->setStatus(util::ServiceJobStatus::IN_PROGRESS);
|
||||
trackedJobCards.getValueAt(jobIndex).state = RecordState::MODIFIED;
|
||||
jobStatusUpdated = true;
|
||||
}
|
||||
else if (currentJob->getStatus() == util::ServiceJobStatus::IN_PROGRESS)
|
||||
{
|
||||
currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||
trackedJobCards.getValueAt(jobIndex).state = RecordState::MODIFIED;
|
||||
jobStatusUpdated = true;
|
||||
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
||||
if (serviceBookingCompleted)
|
||||
{
|
||||
const std::string& bookingId = currentJob->getBookingId();
|
||||
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||
trackedServiceBookings.getValueAt(trackedServiceBookings.find(bookingId)).state = RecordState::MODIFIED;
|
||||
paymentManagementService.generateInvoice(currentJob->getBooking());
|
||||
std::string title = "Service Booking completed. Invoice Generated.";
|
||||
std::string message = "Services completed for the booking and invoice generated.";
|
||||
@@ -846,4 +917,6 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
|
||||
{
|
||||
throw std::runtime_error("Failed to update job status. Job may already be completed.");
|
||||
}
|
||||
m_dataStore.saveJobCards();
|
||||
m_dataStore.saveServiceBookings();
|
||||
}
|
||||
Reference in New Issue
Block a user