Compare commits

..

8 Commits

Author SHA1 Message Date
joelthomastrenser 70bce90865 Merge branch 'feature-file-management' into feature 2026-05-22 17:21:03 +05:30
joelthomastrenser a32e5b07ae Merge branch 'feature-notification-management' into feature 2026-05-22 15:47:57 +05:30
joelthomastrenser 1a77e85daa Merge branch 'feature-admin-management' into feature 2026-05-22 14:19:36 +05:30
Avinash Rajesh dd738be4de Add standardized documentation headers 2026-05-22 12:59:36 +05:30
joelthomastrenser 401a5d8369 Merge branch 'feature-payment-management' into feature 2026-05-22 12:47:18 +05:30
joelthomastrenser 80e860bd12 Merge branch 'feature-inventory-management' into feature 2026-05-22 12:37:34 +05:30
joelthomastrenser 9eaf81ca3d Merge branch 'feature-service-management' into feature 2026-05-22 12:28:53 +05:30
joelthomastrenser ba5f96c22d 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
2026-05-22 12:13:17 +05:30
41 changed files with 2038 additions and 4232 deletions
@@ -233,6 +233,12 @@
<ClInclude Include="models\ComboPackage.h">
<Filter>Header Files\Models</Filter>
</ClInclude>
<ClInclude Include="views\MenuHelper.h">
<Filter>Header Files\Views</Filter>
</ClInclude>
<ClInclude Include="utilities\Utility.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="utilities\Config.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
@@ -245,11 +251,5 @@
<ClInclude Include="utilities\FileHelper.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="utilities\Utility.h">
<Filter>Header Files\Utilities</Filter>
</ClInclude>
<ClInclude Include="views\MenuHelper.h">
<Filter>Header Files\Views</Filter>
</ClInclude>
</ItemGroup>
</Project>
@@ -1,13 +1,13 @@
/*
File: Controller.cpp
Description: Implementation file containing the method definitions of the
Controller class, including authentication, user creation,
service purchasing, and system checks.
Description: Implementation file containing the method definitions
of the Controller class, which manages user authentication,
inventory, services, bookings, and notifications.
Author: Trenser
Date:19-May-2026
*/
#include "ComboPackage.h"
#include "Controller.h"
#include "ComboPackage.h"
#include "Enums.h"
#include "InventoryItem.h"
#include "Invoice.h"
@@ -15,14 +15,15 @@ Date:19-May-2026
#include "Service.h"
#include "ServiceBooking.h"
#include "User.h"
#include "User.h"
#include <stdexcept>
/*
Function: login
Description: Authenticates a user by delegating to the authentication management service.
Parameter: const std::string& username - users username
const std::string& password - users password
Return type: bool - true if login successful, false otherwise
Description: Authenticates a user based on provided credentials.
Parameter: const std::string& username - the username of the user
const std::string& password - the password of the user
Return type: bool
*/
bool Controller::login(const std::string& username, const std::string& password)
{
@@ -31,7 +32,8 @@ bool Controller::login(const std::string& username, const std::string& password)
/*
Function: logout
Description: Logs out the currently authenticated user.
Description: Logs out the currently authenticated user by delegating
to the authentication management service.
Parameter: None
Return type: void
*/
@@ -42,8 +44,9 @@ void Controller::logout()
/*
Function: changePassword
Description: Changes the password of the currently authenticated user.
Parameter: const std::string& newPassword - new password to set
Description: Updates the password of the authenticated user by delegating
to the authentication management service.
Parameter: const std::string& newPassword - the new password to set
Return type: void
*/
void Controller::changePassword(const std::string& newPassword)
@@ -51,28 +54,11 @@ void Controller::changePassword(const std::string& newPassword)
m_authenticationManagementService.changePassword(newPassword);
}
/*
Function: createCustomer
Description: Creates a new customer account with the provided details.
Parameter: const std::string& username - customers username
const std::string& name - customers name
const std::string& password - customers password
const std::string& email - customers email
const std::string& phone - customers phone number
Return type: void
*/
void Controller::createCustomer(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone)
{
m_userManagementService.createUser(username, name, password, email, phone, util::UserType::CUSTOMER);
}
/*
Function: getAuthenticatedUser
Description: Retrieves the currently authenticated user.
Parameter: None
Return type: const User* - pointer to the authenticated user
*/
const User* Controller::getAuthenticatedUser()
{
return m_authenticationManagementService.getAuthenticatedUser();
@@ -93,13 +79,6 @@ void Controller::createTechnician(const std::string& username, const std::string
m_userManagementService.createUser(username, name, password, email, phoneNumber, util::UserType::TECHNICIAN);
}
/*
Function: updateUserDetails
Description: Updates the email and phone details of the currently authenticated user.
Parameter: const std::string& email - new email address
const std::string& phone - new phone number
Return type: void
*/
void Controller::updateUserDetails(const std::string& email, const std::string& phone)
{
User* authenticatedUser = m_authenticationManagementService.getAuthenticatedUser();
@@ -110,14 +89,6 @@ void Controller::updateUserDetails(const std::string& email, const std::string&
m_userManagementService.updateUserDetails(authenticatedUser->getId(), email, phone);
}
/*
Function: getServices
Description: Retrieves all available services in read-only form.
Parameters:
- None
Returns:
- util::Map<std::string, const Service*> containing all services
*/
util::Map<std::string, const Service*> Controller::getServices()
{
util::Map<std::string, Service*> currentServices = m_serviceManagementService.getServices();
@@ -151,29 +122,11 @@ util::Map<std::string, const ComboPackage*> Controller::getComboPackages()
return readOnlyComboPackages;
}
/*
Function: purchaseService
Description: Purchases one or more services for a vehicle by delegating to the service management service.
Parameter: const util::Vector<std::string>& serviceIDs - IDs of services to purchase
const std::string& vehicleNumber - vehicle registration number
const std::string& vehicleBrand - brand of the vehicle
const std::string& vehicleModel - model of the vehicle
Return type: void
*/
void Controller::purchaseService(const util::Vector<std::string>& serviceIDs, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel)
{
m_serviceManagementService.purchaseService(serviceIDs, vehicleNumber, vehicleBrand, vehicleModel);
}
/*
Function: purchaseComboPackage
Description: Purchases a combo package for a vehicle by delegating to the service management service.
Parameter: const std::string& comboPackageID - ID of the combo package
const std::string& vehicleNumber - vehicle registration number
const std::string& vehicleBrand - brand of the vehicle
const std::string& vehicleModel - model of the vehicle
Return type: void
*/
void Controller::purchaseComboPackage(const std::string& comboPackageID, const std::string& vehicleNumber, const std::string& vehicleBrand, const std::string& vehicleModel)
{
m_serviceManagementService.purchaseComboPackage(comboPackageID, vehicleNumber, vehicleBrand, vehicleModel);
@@ -188,12 +141,12 @@ Return type: util::Map<std::string, const InventoryItem*>
*/
util::Map<std::string, const InventoryItem*> Controller::getInventoryItems()
{
auto inventoryItems = m_inventoryManagementService.getInventoryItems();
auto inventoryIems = m_inventoryManagementService.getInventoryItems();
util::Map<std::string, const InventoryItem*> readOnlyInventoryItems;
int inventoryItemsMapSize = inventoryItems.getSize();
int inventoryItemsMapSize = inventoryIems.getSize();
for (int index = 0; index < inventoryItemsMapSize; index++)
{
readOnlyInventoryItems.insert(inventoryItems.getKeyAt(index), inventoryItems.getValueAt(index));
readOnlyInventoryItems.insert(inventoryIems.getKeyAt(index), inventoryIems.getValueAt(index));
}
return readOnlyInventoryItems;
}
@@ -245,14 +198,6 @@ void Controller::addInventoryItemStock(const std::string& selectedItemId, int qu
m_inventoryManagementService.addInventoryItemStock(selectedItemId, quantity);
}
/*
Function: getServiceBookings
Description: Retrieves all service bookings in read-only form.
Parameters:
- None
Returns:
- util::Map<std::string, const ServiceBooking*> containing service bookings
*/
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookings()
{
auto serviceBookings = m_serviceManagementService.getServiceBookings();
@@ -264,14 +209,6 @@ util::Map<std::string, const ServiceBooking*> Controller::getServiceBookings()
return readOnlyServiceBookings;
}
/*
Function: getServiceBookingsByUser
Description: Retrieves all service bookings for a specific user.
Parameters:
- userID: std::string, the user ID
Returns:
- util::Map<std::string, const ServiceBooking*> containing bookings for the user
*/
util::Map<std::string, const ServiceBooking*> Controller::getServiceBookingsByUser(const std::string userID)
{
util::Map<std::string, const ServiceBooking*> readOnlyServiceBookingsByUserMap;
@@ -301,14 +238,6 @@ util::Map<std::string, const User*> Controller::getUsers()
return readOnlyUserList;
}
/*
Function: getUsers
Description: Retrieves users filtered by user type.
Parameters:
- userType: util::UserType, type of user (CUSTOMER, TECHNICIAN, ADMIN)
Returns:
- util::Map<std::string, const User*> containing users of the specified type
*/
util::Map<std::string, const User*> Controller::getUsers(util::UserType userType)
{
auto userMap = m_userManagementService.getUsers(userType);
@@ -320,57 +249,21 @@ util::Map<std::string, const User*> Controller::getUsers(util::UserType userType
return readOnlyUserMap;
}
/*
Function: createJobCard
Description: Creates a job card for a service booking assigned to a technician.
Parameters:
- bookingID: std::string, ID of the service booking
- technicianID: std::string, ID of the technician
- serviceID: std::string, ID of the service
Returns:
- void
*/
void Controller::createJobCard(const std::string& bookingID, const std::string& technicianID, const std::string& serviceID)
{
m_serviceManagementService.createJobCard(bookingID, technicianID, serviceID);
}
/*
Function: createService
Description: Creates a new service with associated inventory items and labor cost.
Parameters:
- name: std::string, name of the service
- inventoryItemIDs: Vector of inventory item IDs
- laborCost: double, labor cost
Returns:
- void
*/
void Controller::createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost)
{
m_serviceManagementService.createService(name, inventoryItemIDs, laborCost);
}
/*
Function: removeService
Description: Removes a service from the system by ID.
Parameters:
- serviceID: std::string, ID of the service
Returns:
- void
*/
void Controller::removeService(const std::string& serviceID)
{
m_serviceManagementService.removeService(serviceID);
}
/*
Function: getJobCardsByUser
Description: Retrieves job cards assigned to the authenticated technician.
Parameters:
- None
Returns:
- util::Map<std::string, const JobCard*> containing job cards
*/
util::Map<std::string, const JobCard*> Controller::getJobCardsByUser()
{
const User* currentUser = getAuthenticatedUser();
@@ -384,14 +277,6 @@ util::Map<std::string, const JobCard*> Controller::getJobCardsByUser()
return readOnlyJobCardMap;
}
/*
Function: completeJob
Description: Marks a job card as completed.
Parameters:
- jobID: std::string, ID of the job card
Returns:
- void
*/
void Controller::completeJob(const std::string& jobID)
{
m_serviceManagementService.completeJob(jobID);
@@ -409,8 +294,10 @@ void Controller::removeUser(const std::string& userID)
User* user = m_userManagementService.getUser(userID);
if (!user)
{
throw std::runtime_error("Error: User not Found.\n");
throw std::runtime_error("Error User not Found.\n");
}
m_serviceManagementService.cancelCustomerServiceBookings(userID);
m_serviceManagementService.cancelTechnicianJobs(userID);
m_userManagementService.removeUser(userID);
}
@@ -440,15 +327,6 @@ void Controller::removeComboPackage(const std::string& comboPackageID)
m_serviceManagementService.removeComboPackage(comboPackageID);
}
/*
Function: getInvoicesByUser
Description: Retrieves all invoices associated with the currently authenticated user.
Converts them into a read-only map before returning.
Parameters:
- None
Returns:
- util::Map<std::string, const Invoice*> containing the users invoices
*/
util::Map<std::string, const Invoice*> Controller::getInvoicesByUser()
{
User* currentUser = m_authenticationManagementService.getAuthenticatedUser();
@@ -462,15 +340,6 @@ util::Map<std::string, const Invoice*> Controller::getInvoicesByUser()
return userInvoicesReadOnly;
}
/*
Function: completePayment
Description: Completes payment for a specific invoice using the given payment mode.
Parameters:
- invoiceID: std::string, ID of the invoice to be paid
- paymentMode: util::PaymentMode, mode of payment (e.g., ONLINE, OFFLINE)
Returns:
- void
*/
void Controller::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
{
m_paymentManagementService.completePayment(invoiceID, paymentMode);
@@ -554,16 +423,6 @@ void Controller::configureNotifications(bool paymentNotifications, bool serviceN
}
}
/*
Function: loadSystemData
Description: Loads all system data from persistent storage into memory.
Invokes the respective management services to load users, inventory items, services,
combo packages, service bookings, job cards, invoices, and observers.
Parameters:
- None
Returns:
- void
*/
void Controller::loadSystemData()
{
m_userManagementService.loadUsers();
@@ -578,16 +437,6 @@ void Controller::loadSystemData()
m_inventoryManagementService.loadObservers();
}
/*
Function: saveSystemData
Description: Saves all system data from memory back to persistent storage.
Invokes the respective management services to save users, inventory items, services,
combo packages, service bookings, job cards, invoices, and observers.
Parameters:
- None
Returns:
- void
*/
void Controller::saveSystemData()
{
m_userManagementService.saveUsers();
@@ -604,8 +453,9 @@ void Controller::saveSystemData()
/*
Function: runSystemChecks
Description: Runs system checks to ensure critical configurations, such as verifying admin existence.
Parameter: None
Description: Executes system checks including sending low stock alerts
and payment reminders.
Parameters: None
Return type: void
*/
void Controller::runSystemChecks()
@@ -6,7 +6,6 @@ Description: Header file declaring the Controller class, which manages
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include <string>
#include "AuthenticationManagementService.h"
@@ -29,7 +28,7 @@ class Notification;
class Controller
{
private:
AuthenticationManagementService m_authenticationManagementService;
AuthenticationManagementService m_authenticationManagementService;
UserManagementService m_userManagementService;
ServiceManagementService m_serviceManagementService;
InventoryManagementService m_inventoryManagementService;
@@ -40,7 +39,7 @@ public:
void changePassword(const std::string& newPassword);
void createCustomer(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone);
const User* getAuthenticatedUser();
void createTechnician(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone);
void createTechnician(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phoneNumber);
void updateUserDetails(const std::string& email, const std::string& phone);
util::Map<std::string, const Service*> getServices();
util::Map<std::string, const ComboPackage*> getComboPackages();
@@ -0,0 +1 @@
Place files here.
@@ -56,19 +56,6 @@ ComboPackage::ComboPackage(const std::string& packageName, double discountPercen
}
}
/*
Function: ComboPackage (parameterized constructor with ID)
Description: Initializes a combo package with an existing ID, name, discount percentage,
service IDs, and state. Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique ID of the package
- packageName: const std::string&, name of the package
- discountPercentage: double, discount percentage applied
- serviceIDs: const util::Vector<std::string>&, IDs of services included
- status: util::State, state of the package (ACTIVE/INACTIVE)
Returns:
- A new ComboPackage object
*/
ComboPackage::ComboPackage(const std::string& id, const std::string& packageName, double discountPercentage, const util::Vector<std::string>& serviceIDs, util::State status)
: m_id(id),
m_packageName(packageName),
@@ -225,14 +212,6 @@ void ComboPackage::setState(util::State status)
m_status = status;
}
/*
Function: getServiceIDsAsString (static helper)
Description: Converts a vector of service IDs into a single string separated by '|'.
Parameters:
- serviceIDs: const util::Vector<std::string>&, vector of service IDs
Returns:
- std::string: Concatenated service IDs string
*/
static std::string getServiceIDsAsString(const util::Vector<std::string>& serviceIDs)
{
int numberOfServices = serviceIDs.getSize();
@@ -248,14 +227,6 @@ static std::string getServiceIDsAsString(const util::Vector<std::string>& servic
return serviceIDsString;
}
/*
Function: getServiceIDsAsVector (static helper)
Description: Converts a string of service IDs separated by '|' into a vector.
Parameters:
- serviceIDsString: const std::string&, concatenated service IDs string
Returns:
- util::Vector<std::string>: Vector of service IDs
*/
static util::Vector<std::string> getServiceIDsAsVector(const std::string& serviceIDsString)
{
util::Vector<std::string> serviceIDs;
@@ -268,14 +239,6 @@ static util::Vector<std::string> getServiceIDsAsVector(const std::string& servic
return serviceIDs;
}
/*
Function: serialize
Description: Serializes the combo package into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized combo package record
*/
std::string ComboPackage::serialize() const
{
std::ostringstream serializedComboPackage;
@@ -287,16 +250,6 @@ std::string ComboPackage::serialize() const
return serializedComboPackage.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a ComboPackage object.
Parameters:
- record: const std::string&, serialized combo package record
Returns:
- ComboPackage*: Pointer to the deserialized ComboPackage object
Throws:
- std::runtime_error if data is invalid
*/
ComboPackage* ComboPackage::deserialize(const std::string& record)
{
std::string id, packageName;
@@ -327,14 +280,6 @@ ComboPackage* ComboPackage::deserialize(const std::string& record)
);
}
/*
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";
@@ -8,9 +8,9 @@ Date: 19-May-2026
#include <sstream>
#include <stdexcept>
#include "InventoryItem.h"
#include "Factory.h"
#include "StringHelper.h"
#include "InventoryItem.h"
int InventoryItem::m_uid = 0;
@@ -47,19 +47,6 @@ InventoryItem::InventoryItem(const std::string& partName, int quantity, double p
m_status(util::State::ACTIVE),
m_price(price) {}
/*
Function: InventoryItem (parameterized constructor with ID)
Description: Initializes an inventory item with an existing ID, part name, quantity,
price, and state. Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique ID of the item
- partName: const std::string&, name of the part
- quantity: int, quantity of the part
- price: double, price of the part
- status: util::State, state of the item (ACTIVE/INACTIVE)
Returns:
- A new InventoryItem object
*/
InventoryItem::InventoryItem(const std::string& id, const std::string& partName, int quantity, double price, util::State status)
: m_id(id),
m_partName(partName),
@@ -204,14 +191,6 @@ void InventoryItem::setState(util::State status)
m_status = status;
}
/*
Function: serialize
Description: Serializes the inventory item into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized inventory item record
*/
std::string InventoryItem::serialize() const
{
std::ostringstream serializedInventoryItem;
@@ -223,16 +202,6 @@ std::string InventoryItem::serialize() const
return serializedInventoryItem.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into an InventoryItem object.
Parameters:
- record: const std::string&, serialized inventory item record
Returns:
- InventoryItem*: Pointer to the deserialized InventoryItem object
Throws:
- std::runtime_error if data is invalid
*/
InventoryItem* InventoryItem::deserialize(const std::string& record)
{
std::string id, partName;
@@ -264,14 +233,6 @@ InventoryItem* InventoryItem::deserialize(const std::string& record)
);
}
/*
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";
@@ -59,7 +59,8 @@ Invoice::Invoice(
ServiceBooking* booking,
const util::Timestamp& invoiceDate,
double laborCost,
const util::Map<std::string, InventoryItem*>& parts,
const util::Map<std::string,
InventoryItem*>& parts,
double partsCost,
double discountPercentage,
double totalAmount,
@@ -87,6 +88,7 @@ Invoice::Invoice(
m_partIDs.push_back(partPointers[index]->getId());
}
}
Invoice::Invoice(
const std::string& id,
const std::string& bookingId,
@@ -120,12 +122,6 @@ Invoice::Invoice(
}
}
/*
Function: getId
Description: Retrieves the unique ID of the invoice.
Returns:
- const std::string& representing the invoice ID.
*/
const std::string& Invoice::getId() const
{
return m_id;
@@ -175,14 +171,6 @@ double Invoice::getLaborCost() const
return m_laborCost;
}
/*
Function: getPartIDs
Description: Retrieves the IDs of parts used in the invoice.
Parameters:
- None
Returns:
- const util::Vector<std::string>&: Part IDs
*/
const util::Vector<std::string>& Invoice::getPartIDs() const
{
return m_partIDs;
@@ -192,7 +180,7 @@ const util::Vector<std::string>& Invoice::getPartIDs() const
Function: getParts
Description: Retrieves the map of inventory items used in the service.
Returns:
- const util::Map<int, InventoryItem*>& representing the parts.
- const util::Map<std::string, InventoryItem*>& representing the parts.
*/
const util::Map<std::string, InventoryItem*>& Invoice::getParts() const
{
@@ -428,14 +416,6 @@ void Invoice::setStatus(util::PaymentStatus status)
m_status = status;
}
/*
Function: getPartIDsAsString (static helper)
Description: Converts a vector of part IDs into a single string separated by '|'.
Parameters:
- partIDs: const util::Vector<std::string>&, vector of part IDs
Returns:
- std::string: Concatenated part IDs string
*/
static std::string getPartIDsAsString(const util::Vector<std::string>& partIDs)
{
int numberOfParts = partIDs.getSize();
@@ -451,14 +431,6 @@ static std::string getPartIDsAsString(const util::Vector<std::string>& partIDs)
return partIDsString;
}
/*
Function: getPartIDsAsVector (static helper)
Description: Converts a string of part IDs separated by '|' into a vector.
Parameters:
- partIDsString: const std::string&, concatenated part IDs string
Returns:
- util::Vector<std::string>: Vector of part IDs
*/
static util::Vector<std::string> getPartIDsAsVector(const std::string& partIDsString)
{
util::Vector<std::string> partIDs;
@@ -471,14 +443,6 @@ static util::Vector<std::string> getPartIDsAsVector(const std::string& partIDsSt
return partIDs;
}
/*
Function: serialize
Description: Serializes the invoice into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized invoice record
*/
std::string Invoice::serialize() const
{
std::ostringstream serializedInvoice;
@@ -496,16 +460,6 @@ std::string Invoice::serialize() const
return serializedInvoice.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into an Invoice object.
Parameters:
- record: const std::string&, serialized invoice record
Returns:
- Invoice*: Pointer to the deserialized Invoice object
Throws:
- std::runtime_error if data is invalid
*/
Invoice* Invoice::deserialize(const std::string& record)
{
std::string id, bookingId;
@@ -558,14 +512,6 @@ Invoice* Invoice::deserialize(const std::string& record)
);
}
/*
Function: getHeaders
Description: Retrieves the CSV headers for invoice serialization.
Parameters:
- None
Returns:
- std::string: Header string ("ID,BookingID,InvoiceDate,LaborCost,PartIDs,PartsCost,DiscountPercentage,TotalAmount,PaymentDate,PaymentMethod,Status")
*/
std::string Invoice::getHeaders()
{
return "ID,BookingID,InvoiceDate,LaborCost,PartIDs,PartsCost,DiscountPercentage,TotalAmount,PaymentDate,PaymentMethod,Status";
@@ -6,7 +6,6 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
#include <sstream>
#include <stdexcept>
#include "JobCard.h"
@@ -18,10 +17,12 @@ int JobCard::m_uid = 0;
/*
Function: JobCard
Description: Default constructor that initializes a new job card with
a unique ID and default values.
Parameter: None
Return type: Constructor
Description: Default constructor that initializes a new job card with a unique ID,
null booking, null service, null technician, and default job status.
Parameters:
- None
Returns:
- A new JobCard object.
*/
JobCard::JobCard()
: m_id("JC" + std::to_string(++m_uid)),
@@ -32,19 +33,18 @@ JobCard::JobCard()
/*
Function: JobCard
Description: Parameterized constructor that initializes a new job card with a unique ID and specified details.
Parameters:
- bookingId: ID of the associated service booking.
- booking: Pointer to the ServiceBooking object.
- service: Pointer to the Service object.
- serviceId: ID of the associated service.
- technicianId: ID of the assigned technician.
- technician: Pointer to the User object representing the technician.
- assignedDate: Timestamp of when the job was assigned.
- status: Current status of the job (STARTED/COMPLETED).
- completionDate: Timestamp of when the job was completed.
Returns:
- A new JobCard object.
Description: Parameterized constructor that initializes a job card with
booking, service, technician, and status details.
Parameter: const std::string& bookingId - ID of the booking
ServiceBooking* booking - pointer to the booking object
Service* service - pointer to the service object
const std::string& serviceId - ID of the service
const std::string& technicianId - ID of the technician
User* technician - pointer to the technician object
const util::Timestamp& assignedDate - date when job was assigned
util::ServiceJobStatus status - current status of the job
const util::Timestamp& completionDate - date when job was completed
Return type: Constructor
*/
JobCard::JobCard(const std::string& bookingId,
ServiceBooking* booking,
@@ -67,22 +67,6 @@ JobCard::JobCard(const std::string& bookingId,
m_status(status),
m_completionDate(completionDate) {}
/*
Function: JobCard (parameterized constructor with ID)
Description: Initializes a job card with an existing ID, booking ID, service ID,
technician ID, assignment date, completion date, and status.
Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique job card ID
- bookingId: const std::string&, ID of the booking
- serviceId: const std::string&, ID of the service
- technicianId: const std::string&, ID of the technician
- assignedDate: const util::Timestamp&, date of assignment
- status: util::ServiceJobStatus, job status
- completionDate: const util::Timestamp&, date of completion
Returns:
- A new JobCard object
*/
JobCard::JobCard(const std::string& id,
const std::string& bookingId,
const std::string& serviceId,
@@ -199,9 +183,9 @@ const util::Timestamp& JobCard::getAssignedDate() const
/*
Function: getStatus
Description: Retrieves the current status of the job.
Returns:
- ServiceJobStatus representing the job status.
Description: Retrieves the current status of the job card.
Parameter: None
Return type: util::ServiceJobStatus
*/
util::ServiceJobStatus JobCard::getStatus() const
{
@@ -325,11 +309,9 @@ void JobCard::setAssignedDate(const util::Timestamp& assignedDate)
/*
Function: setStatus
Description: Sets the current status of the job.
Parameters:
- status: New job status value.
Returns:
- void
Description: Sets the status of the job card.
Parameter: util::ServiceJobStatus status - new job status
Return type: void
*/
void JobCard::setStatus(util::ServiceJobStatus status)
{
@@ -349,14 +331,6 @@ void JobCard::setCompletionDate(const util::Timestamp& completionDate)
m_completionDate = completionDate;
}
/*
Function: serialize
Description: Serializes the job card into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized job card record
*/
std::string JobCard::serialize() const
{
std::ostringstream serializedJobCard;
@@ -370,16 +344,6 @@ std::string JobCard::serialize() const
return serializedJobCard.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a JobCard object.
Parameters:
- record: const std::string&, serialized job card record
Returns:
- JobCard*: Pointer to the deserialized JobCard object
Throws:
- std::runtime_error if timestamp parsing fails
*/
JobCard* JobCard::deserialize(const std::string& record)
{
std::string id, bookingId, serviceId, technicianId;
@@ -415,14 +379,6 @@ JobCard* JobCard::deserialize(const std::string& record)
);
}
/*
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";
@@ -6,11 +6,11 @@ Description: Header file declaring the JobCard class, which represents
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include <string>
#include "Enums.h"
#include "Timestamp.h"
#include "Enums.h"
class ServiceBooking;
class Service;
@@ -45,19 +45,6 @@ Notification::Notification(const std::string& recipientUserId, User* recipient,
m_message(message),
m_createdAt(createdAt) {}
/*
Function: Notification (parameterized constructor with ID)
Description: Initializes a notification with an existing ID, recipient details,
title, message, and creation timestamp. Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique notification ID
- recipientUserId: const std::string&, ID of the recipient user
- title: const std::string&, notification title
- message: const std::string&, notification message
- createdAt: const util::Timestamp&, timestamp of creation
Returns:
- A new Notification object
*/
Notification::Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt)
: m_id(id),
m_recipientUserId(recipientUserId),
@@ -217,14 +204,6 @@ void Notification::setCreatedAt(const util::Timestamp& createdAt)
m_createdAt = createdAt;
}
/*
Function: serialize
Description: Serializes the notification into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized notification record
*/
std::string Notification::serialize() const
{
std::ostringstream serializedNotification;
@@ -236,16 +215,6 @@ std::string Notification::serialize() const
return serializedNotification.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a Notification object.
Parameters:
- record: const std::string&, serialized notification record
Returns:
- Notification*: Pointer to the deserialized Notification object
Throws:
- std::runtime_error if timestamp parsing fails
*/
Notification* Notification::deserialize(const std::string& record)
{
std::string id, recipientUserId, title, message, createdAtTimestampString;
@@ -273,14 +242,6 @@ Notification* Notification::deserialize(const std::string& record)
);
}
/*
Function: getHeaders
Description: Retrieves the CSV headers for notification serialization.
Parameters:
- None
Returns:
- std::string: Header string ("ID,RecipientID,Title,Message,Timestamp")
*/
std::string Notification::getHeaders()
{
return "ID,RecipientID,Title,Message,Timestamp";
@@ -54,19 +54,6 @@ Service::Service(const std::string& name, const util::Map<std::string, Inventory
}
}
/*
Function: Service (parameterized constructor with ID)
Description: Initializes a service with an existing ID, name, inventory item IDs,
labor cost, and state. Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique service ID
- name: const std::string&, name of the service
- requiredInventoryItemIDs: const util::Vector<std::string>&, IDs of required inventory items
- laborCost: double, labor cost of the service
- status: util::State, state of the service (ACTIVE/INACTIVE)
Returns:
- A new Service object
*/
Service::Service(const std::string& id, const std::string& name, const util::Vector<std::string>& requiredInventoryItemIDs, double laborCost, util::State status)
: m_id(id),
m_name(name),
@@ -103,14 +90,6 @@ const std::string& Service::getName() const
return m_name;
}
/*
Function: getRequiredInventoryItemIDs
Description: Retrieves the IDs of required inventory items for the service.
Parameters:
- None
Returns:
- const util::Vector<std::string>&: Inventory item IDs
*/
const util::Vector<std::string>& Service::getRequiredInventoryItemIDs() const
{
return m_requiredInventoryItemIDs;
@@ -221,14 +200,6 @@ void Service::setState(util::State status)
m_status = status;
}
/*
Function: getInventoryItemIDsAsString (static helper)
Description: Converts a vector of inventory item IDs into a single string separated by '|'.
Parameters:
- inventoryItemIds: const util::Vector<std::string>&, vector of inventory item IDs
Returns:
- std::string: Concatenated inventory item IDs string
*/
static std::string getInventoryItemIDsAsString(const util::Vector<std::string>& inventoryItemIds)
{
int numberOfInventoryItems = inventoryItemIds.getSize();
@@ -244,14 +215,6 @@ static std::string getInventoryItemIDsAsString(const util::Vector<std::string>&
return inventoryItemIDs;
}
/*
Function: getInventoryItemIDsAsVector (static helper)
Description: Converts a string of inventory item IDs separated by '|' into a vector.
Parameters:
- inventoryItemIDsString: const std::string&, concatenated inventory item IDs string
Returns:
- util::Vector<std::string>: Vector of inventory item IDs
*/
static util::Vector<std::string> getInventoryItemIDsAsVector(const std::string& inventoryItemIDsString)
{
util::Vector<std::string> inventoryItemIDs;
@@ -264,14 +227,6 @@ static util::Vector<std::string> getInventoryItemIDsAsVector(const std::string&
return inventoryItemIDs;
}
/*
Function: serialize
Description: Serializes the service into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized service record
*/
std::string Service::serialize() const
{
std::ostringstream serializedService;
@@ -283,16 +238,6 @@ std::string Service::serialize() const
return serializedService.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a Service object.
Parameters:
- record: const std::string&, serialized service record
Returns:
- Service*: Pointer to the deserialized Service object
Throws:
- std::runtime_error if labor cost parsing fails
*/
Service* Service::deserialize(const std::string& record)
{
std::string id, name;
@@ -323,14 +268,6 @@ Service* Service::deserialize(const std::string& record)
);
}
/*
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";
@@ -20,31 +20,31 @@ int ServiceBooking::m_uid = 0;
Function: ServiceBooking
Description: Default constructor that initializes a new service booking with a unique ID,
null customer, and zero discount percentage.
Parameters: None
Returns: A new ServiceBooking object.
Parameters:
- None
Returns:
- A new ServiceBooking object.
*/
ServiceBooking::ServiceBooking()
: m_id("SBK" + std::to_string(++m_uid)),
: m_id("SRV" + std::to_string(++m_uid)),
m_customer(nullptr),
m_assignedTechnician(nullptr),
m_status(util::ServiceJobStatus::PENDING),
m_discountPercentage(0.0) {}
/*
Function: ServiceBooking
Description: Parameterized constructor that initializes a new service booking with a unique ID and specified details.
Parameters:
- id: Booking ID string.
- status: Current status of the booking (e.g., PENDING, COMPLETED).
- services: Map of services included in the booking.
- customerId: ID of the customer.
- customer: Pointer to the User object representing the customer.
- vehicleNumber: Vehicle registration number.
- vehicleBrand: Brand of the vehicle.
- vehicleModel: Model of the vehicle.
- discountPercentage: Discount applied to the booking.
Returns:
- A new ServiceBooking object.
Description: Parameterized constructor that initializes a service booking
with customer, vehicle, technician, and discount details.
Parameter: const std::string& id - booking ID
util::ServiceJobStatus status - current booking status
const util::Map<std::string, Service*>& services - map of services
const std::string& customerId - ID of the customer
User* customer - pointer to the customer object
const std::string& vehicleNumber - vehicle registration number
const std::string& vehicleBrand - brand of the vehicle
const std::string& vehicleModel - model of the vehicle
double discountPercentage - discount applied to the booking
Return type: Constructor
*/
ServiceBooking::ServiceBooking(
util::ServiceJobStatus status,
@@ -57,7 +57,7 @@ ServiceBooking::ServiceBooking(
const std::string& vehicleModel,
double discountPercentage
)
: m_id("SBK" + std::to_string(++m_uid)),
: m_id("SRV" + std::to_string(++m_uid)),
m_status(status),
m_services(services),
m_customerId(customerId),
@@ -77,24 +77,6 @@ ServiceBooking::ServiceBooking(
}
}
/*
Function: ServiceBooking (parameterized constructor with ID)
Description: Initializes a service booking with an existing ID, status, service IDs,
customer details, vehicle details, technician ID, and discount percentage.
Updates UID tracking based on ID.
Parameters:
- id: const std::string&, unique booking ID
- status: util::ServiceJobStatus, job status of the booking
- serviceIDs: const util::Vector<std::string>&, IDs of booked services
- customerId: const std::string&, ID of the customer
- vehicleNumber: const std::string&, vehicle number
- vehicleBrand: const std::string&, vehicle brand
- vehicleModel: const std::string&, vehicle model
- assignedTechnicianId: const std::string&, ID of the assigned technician
- discountPercentage: double, discount applied
Returns:
- A new ServiceBooking object
*/
ServiceBooking::ServiceBooking(
const std::string& id,
util::ServiceJobStatus status,
@@ -125,12 +107,6 @@ ServiceBooking::ServiceBooking(
}
}
/*
Function: getId
Description: Retrieves the unique identifier of the service booking.
Parameter: None
Return type: const std::string&
*/
const std::string& ServiceBooking::getId() const
{
return m_id;
@@ -139,22 +115,14 @@ const std::string& ServiceBooking::getId() const
/*
Function: getStatus
Description: Retrieves the current status of the service booking.
Parameter: None
Return type: util::ServiceJobStatus
Returns:
- util::ServiceJobStatus representing the booking status.
*/
util::ServiceJobStatus ServiceBooking::getStatus() const
{
return m_status;
}
/*
Function: getServiceIDs
Description: Retrieves the IDs of services booked.
Parameters:
- None
Returns:
- const util::Vector<std::string>&: Service IDs
*/
const util::Vector<std::string>& ServiceBooking::getServiceIDs() const
{
return m_serviceIDs;
@@ -162,15 +130,9 @@ const util::Vector<std::string>& ServiceBooking::getServiceIDs() const
/*
Function: getServices
Description: Retrieves the services associated with the booking.
Parameter: None
Return type: const util::Map<std::string, Service*>&
*/
/*
Function: getServices
Description: Retrieves the services associated with the booking.
Parameter: None
Return type: const util::Map<std::string, Service*>&
Description: Retrieves the map of services included in the booking.
Returns:
- const util::Map<std::string, Service*>& representing the services.
*/
const util::Map<std::string, Service*>& ServiceBooking::getServices() const
{
@@ -180,8 +142,8 @@ const util::Map<std::string, Service*>& ServiceBooking::getServices() const
/*
Function: getCustomerId
Description: Retrieves the customer ID associated with the booking.
Parameter: None
Return type: const std::string&
Returns:
- const std::string& representing the customer ID.
*/
const std::string& ServiceBooking::getCustomerId() const
{
@@ -190,9 +152,9 @@ const std::string& ServiceBooking::getCustomerId() const
/*
Function: getCustomer
Description: Retrieves the customer object associated with the booking.
Parameter: None
Return type: User*
Description: Retrieves the pointer to the associated customer.
Returns:
- User* representing the customer.
*/
User* ServiceBooking::getCustomer() const
{
@@ -201,9 +163,9 @@ User* ServiceBooking::getCustomer() const
/*
Function: getVehicleNumber
Description: Retrieves the vehicle registration number for the booking.
Parameter: None
Return type: const std::string&
Description: Retrieves the vehicle registration number.
Returns:
- const std::string& representing the vehicle number.
*/
const std::string& ServiceBooking::getVehicleNumber() const
{
@@ -212,9 +174,9 @@ const std::string& ServiceBooking::getVehicleNumber() const
/*
Function: getVehicleBrand
Description: Retrieves the brand of the vehicle for the booking.
Parameter: None
Return type: const std::string&
Description: Retrieves the brand of the vehicle.
Returns:
- const std::string& representing the vehicle brand.
*/
const std::string& ServiceBooking::getVehicleBrand() const
{
@@ -223,9 +185,9 @@ const std::string& ServiceBooking::getVehicleBrand() const
/*
Function: getVehicleModel
Description: Retrieves the model of the vehicle for the booking.
Parameter: None
Return type: const std::string&
Description: Retrieves the model of the vehicle.
Returns:
- const std::string& representing the vehicle model.
*/
const std::string& ServiceBooking::getVehicleModel() const
{
@@ -234,9 +196,9 @@ const std::string& ServiceBooking::getVehicleModel() const
/*
Function: getAssignedTechnicianId
Description: Retrieves the ID of the technician assigned to the booking.
Parameter: None
Return type: const std::string&
Description: Retrieves the ID of the assigned technician.
Returns:
- const std::string& representing the technician ID.
*/
const std::string& ServiceBooking::getAssignedTechnicianId() const
{
@@ -253,11 +215,12 @@ User* ServiceBooking::getAssignedTechnician() const
{
return m_assignedTechnician;
}
/*
Function: getDiscountPercentage
Description: Retrieves the discount percentage applied to the booking.
Parameter: None
Return type: double
Returns:
- double representing the discount percentage.
*/
double ServiceBooking::getDiscountPercentage() const
{
@@ -266,9 +229,11 @@ double ServiceBooking::getDiscountPercentage() const
/*
Function: setId
Description: Sets the unique identifier of the service booking.
Parameter: const std::string& id - new booking ID
Return type: void
Description: Sets the unique ID of the service booking.
Parameters:
- id: New booking ID string.
Returns:
- void
*/
void ServiceBooking::setId(const std::string& id)
{
@@ -278,8 +243,10 @@ void ServiceBooking::setId(const std::string& id)
/*
Function: setStatus
Description: Sets the current status of the service booking.
Parameter: const util::ServiceJobStatus& status - new booking status
Return type: void
Parameters:
- status: New booking status value.
Returns:
- void
*/
void ServiceBooking::setStatus(const util::ServiceJobStatus& status)
{
@@ -288,9 +255,11 @@ void ServiceBooking::setStatus(const util::ServiceJobStatus& status)
/*
Function: setServices
Description: Sets the services associated with the booking.
Parameter: const util::Map<std::string, Service*>& services - new services map
Return type: void
Description: Sets the services included in the booking.
Parameters:
- services: Map of services.
Returns:
- void
*/
void ServiceBooking::setServices(const util::Map<std::string, Service*>& services)
{
@@ -306,9 +275,11 @@ void ServiceBooking::setServices(const util::Map<std::string, Service*>& service
/*
Function: setCustomerId
Description: Sets the customer ID for the booking.
Parameter: const std::string& customerId - new customer ID
Return type: void
Description: Sets the customer ID associated with the booking.
Parameters:
- customerId: New customer ID string.
Returns:
- void
*/
void ServiceBooking::setCustomerId(const std::string& customerId)
{
@@ -317,9 +288,11 @@ void ServiceBooking::setCustomerId(const std::string& customerId)
/*
Function: setCustomer
Description: Sets the customer object for the booking.
Parameter: User* customer - pointer to the customer object
Return type: void
Description: Sets the pointer to the associated customer.
Parameters:
- customer: Pointer to the User object.
Returns:
- void
*/
void ServiceBooking::setCustomer(User* customer)
{
@@ -328,9 +301,11 @@ void ServiceBooking::setCustomer(User* customer)
/*
Function: setVehicleNumber
Description: Sets the vehicle registration number for the booking.
Parameter: const std::string& vehicleNumber - new vehicle number
Return type: void
Description: Sets the vehicle registration number.
Parameters:
- vehicleNumber: New vehicle number string.
Returns:
- void
*/
void ServiceBooking::setVehicleNumber(const std::string& vehicleNumber)
{
@@ -339,9 +314,11 @@ void ServiceBooking::setVehicleNumber(const std::string& vehicleNumber)
/*
Function: setVehicleBrand
Description: Sets the brand of the vehicle for the booking.
Parameter: const std::string& vehicleBrand - new vehicle brand
Return type: void
Description: Sets the brand of the vehicle.
Parameters:
- vehicleBrand: New vehicle brand string.
Returns:
- void
*/
void ServiceBooking::setVehicleBrand(const std::string& vehicleBrand)
{
@@ -350,9 +327,11 @@ void ServiceBooking::setVehicleBrand(const std::string& vehicleBrand)
/*
Function: setVehicleModel
Description: Sets the model of the vehicle for the booking.
Parameter: const std::string& vehicleModel - new vehicle model
Return type: void
Description: Sets the model of the vehicle.
Parameters:
- vehicleModel: New vehicle model string.
Returns:
- void
*/
void ServiceBooking::setVehicleModel(const std::string& vehicleModel)
{
@@ -361,9 +340,11 @@ void ServiceBooking::setVehicleModel(const std::string& vehicleModel)
/*
Function: setAssignedTechnicianId
Description: Sets the ID of the technician assigned to the booking.
Parameter: const std::string& assignedTechnicianId - new technician ID
Return type: void
Description: Sets the ID of the assigned technician.
Parameters:
- assignedTechnicianId: New technician ID string.
Returns:
- void
*/
void ServiceBooking::setAssignedTechnicianId(const std::string& assignedTechnicianId)
{
@@ -383,23 +364,17 @@ void ServiceBooking::setAssignedTechnician(User* assignedTechnician)
/*
Function: setDiscountPercentage
Description: Sets the discount percentage for the booking.
Parameter: double discountPercentage - new discount percentage
Return type: void
Description: Sets the discount percentage applied to the booking.
Parameters:
- discountPercentage: New discount percentage value.
Returns:
- void
*/
void ServiceBooking::setDiscountPercentage(double discountPercentage)
{
m_discountPercentage = discountPercentage;
}
/*
Function: getServiceIDsAsString (static helper)
Description: Converts a vector of service IDs into a single string separated by '|'.
Parameters:
- serviceIDs: const util::Vector<std::string>&, vector of service IDs
Returns:
- std::string: Concatenated service IDs string
*/
static std::string getServiceIDsAsString(const util::Vector<std::string>& serviceIDs)
{
int numberOfServices = serviceIDs.getSize();
@@ -415,14 +390,6 @@ static std::string getServiceIDsAsString(const util::Vector<std::string>& servic
return serviceIDsString;
}
/*
Function: getServiceIDsAsVector (static helper)
Description: Converts a string of service IDs separated by '|' into a vector.
Parameters:
- serviceIDsString: const std::string&, concatenated service IDs string
Returns:
- util::Vector<std::string>: Vector of service IDs
*/
static util::Vector<std::string> getServiceIDsAsVector(const std::string& serviceIDsString)
{
util::Vector<std::string> serviceIDs;
@@ -435,14 +402,6 @@ static util::Vector<std::string> getServiceIDsAsVector(const std::string& servic
return serviceIDs;
}
/*
Function: serialize
Description: Serializes the service booking into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized booking record
*/
std::string ServiceBooking::serialize() const
{
std::ostringstream serializedBooking;
@@ -458,16 +417,6 @@ std::string ServiceBooking::serialize() const
return serializedBooking.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a ServiceBooking object.
Parameters:
- record: const std::string&, serialized booking record
Returns:
- ServiceBooking*: Pointer to the deserialized ServiceBooking object
Throws:
- std::runtime_error if discount percentage parsing fails
*/
ServiceBooking* ServiceBooking::deserialize(const std::string& record)
{
std::string id, customerId, vehicleNumber, vehicleBrand, vehicleModel, assignedTechnicianId;
@@ -506,14 +455,6 @@ ServiceBooking* ServiceBooking::deserialize(const std::string& record)
);
}
/*
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";
@@ -53,22 +53,6 @@ User::User(const std::string& userName, const std::string& password, const std::
m_type(role),
m_status(util::State::ACTIVE) {}
/*
Function: User (parameterized constructor with ID)
Description: Initializes a user with an existing ID, credentials, personal details,
role, and state. Updates UID tracking based on ID.
Parameters:
- userId: const std::string&, unique user ID
- userName: const std::string&, username
- password: const std::string&, password
- name: const std::string&, full name
- phone: const std::string&, phone number
- email: const std::string&, email address
- role: util::UserType, role of the user
- status: util::State, state of the user (ACTIVE/INACTIVE)
Returns:
- A new User object
*/
User::User(const std::string& userId, const std::string& userName, const std::string& password, const std::string& name, const std::string& phone, const std::string& email, util::UserType role, util::State status)
: m_id(userId),
m_userName(userName),
@@ -322,14 +306,6 @@ void User::setState(util::State status)
m_status = status;
}
/*
Function: serialize
Description: Serializes the user into a CSV-formatted string.
Parameters:
- None
Returns:
- std::string: Serialized user record
*/
std::string User::serialize() const
{
std::ostringstream serializedUser;
@@ -344,14 +320,6 @@ std::string User::serialize() const
return serializedUser.str();
}
/*
Function: deserialize
Description: Deserializes a CSV-formatted string into a User object.
Parameters:
- record: const std::string&, serialized user record
Returns:
- User*: Pointer to the deserialized User object
*/
User* User::deserialize(const std::string& record)
{
std::string id, name, username, phone, password, email;
@@ -377,15 +345,8 @@ User* User::deserialize(const std::string& record)
status);
}
/*
Function: getHeaders
Description: Retrieves the CSV headers for user serialization.
Parameters:
- None
Returns:
- std::string: Header string ("ID,Username,Password,Name,Phone,Email,UserType,UserStatus")
*/
std::string User::getHeaders()
{
return "ID,Username,Password,Name,Phone,Email,UserType,UserStatus";
}
@@ -6,22 +6,12 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
#include <stdexcept>
#include "AuthenticationManagementService.h"
#include "User.h"
User* AuthenticationManagementService::m_authenticatedUser = nullptr;
/*
Function: login
Description: Authenticates a user by checking the provided username and password
against the stored users in the DataStore. If successful, sets the
authenticated user.
Parameter: const std::string& username - users username
const std::string& password - users password
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();
@@ -42,12 +32,6 @@ bool AuthenticationManagementService::login(const std::string& username, const s
return false;
}
/*
Function: getAuthenticatedUser
Description: Retrieves the currently authenticated user.
Parameter: None
Return type: User* - pointer to the authenticated user
*/
User* AuthenticationManagementService::getAuthenticatedUser()
{
return m_authenticatedUser;
@@ -6,7 +6,6 @@ Description: Header file declaring the AuthenticationManagementService class, wh
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include <string>
#include "DataStore.h"
@@ -1,61 +1,171 @@
/*
File: InventoryManagementService.cpp
Description: Implements the InventoryManagementService class, which manages inventory
items and observer relationships within the system. Provides methods
for loading and saving inventory items from persistent storage, as well
as attaching and persisting observers for notification handling.
Description: Implementation file containing the method definitions of the
InventoryManagementService class, including inventory operations
and notification handling.
Author: Trenser
Date: 22-May-2026
Date:19-May-2026
*/
#include <stdexcept>
#include "Config.h"
#include "Enums.h"
#include "Factory.h"
#include "FileManager.h"
#include "InventoryItem.h"
#include "InventoryManagementService.h"
#include "Timestamp.h"
#include "User.h"
#include "Utility.h"
#include "Config.h"
#include "Vector.h"
#include "Enums.h"
#include "InventoryItem.h"
#include "Config.h"
#include "User.h"
#include "Factory.h"
#include "Timestamp.h"
#include "FileManager.h"
#include "Utility.h"
util::Map<std::string, User*> InventoryManagementService::m_observers{};
/*
Function: sendLowStockAlertsToAdmins (static helper)
Description: Sends low stock alert notifications to all admin users for a given inventory item.
Parameters:
- inventoryManagementService: InventoryManagementService&, service used to send notifications
- inventoryItem: const InventoryItem*, pointer to the low-stock inventory item
- adminUsers: const util::Vector<User*>&, list of admin users to notify
Returns:
- None
Function: addInventoryItem
Description: Creates a new inventory item using the Factory and inserts it
into the DataStore.
Parameter: const std::string& partName - name of the part
int quantity - initial quantity of the part
double price - price of the part
Return type: void
*/
void InventoryManagementService::addInventoryItem(const std::string& partName, int quantity, double price)
{
InventoryItem* newItem = Factory::getObject<InventoryItem>(partName, quantity, price);
m_dataStore.getInventoryItems().insert(newItem->getId(), newItem);
}
/*
Function: addInventoryItemStock
Description: Increases the stock quantity of an existing inventory item.
Parameter: const std::string& selectedItemId - ID of the inventory item
int quantity - quantity to add
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);
}
}
}
/*
Function: getInventoryItems
Description: Retrieves all inventory items stored in the DataStore.
Parameter: None
Return type: util::Map<std::string, InventoryItem*>
*/
util::Map<std::string, InventoryItem*> InventoryManagementService::getInventoryItems()
{
return m_dataStore.getInventoryItems();
}
/*
Function: removeInventoryItem
Description: Marks an inventory item as inactive instead of deleting it.
Parameter: const std::string& inventoryItemID - ID of the inventory item
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);
}
}
}
/*
Function: getInventoryItem
Description: Retrieves a specific inventory item by its ID from the DataStore.
Parameter: const std::string& inventoryItemID - ID of the inventory item
Return type: InventoryItem*
*/
InventoryItem* InventoryManagementService::getInventoryItem(const std::string& inventoryItemID)
{
int index = m_dataStore.getInventoryItems().find(inventoryItemID);
if (index != -1)
{
return m_dataStore.getInventoryItems().getValueAt(index);
}
return nullptr;
}
void InventoryManagementService::attach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) == -1)
{
m_observers[userID] = user;
}
}
}
void InventoryManagementService::detach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) != -1)
{
m_observers.remove(userID);
}
}
}
void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message)
{
if (user)
{
if (m_observers.find(user->getId()) != -1)
{
Notification* notification =
Factory::getObject<Notification>(
user->getId(),
user,
"InventoryManagementService: " + title,
message,
util::Timestamp()
);
if (notification)
{
user->addNotification(notification);
}
else
{
throw std::runtime_error("Failed to create notification");
}
}
}
}
static void sendLowStockAlertsToAdmins(InventoryManagementService& inventoryManagementService, const InventoryItem* inventoryItem, const util::Vector<User*>& adminUsers)
{
int adminUsersSize = adminUsers.getSize();
for (int index = 0; index < adminUsersSize; index++)
{
std::string title = "Low Stock Alert";
std::string message = "The inventory item with ID " + inventoryItem->getId() + " has very low quantity in the inventory";
inventoryManagementService.sendNotification(
adminUsers[index],
title,
message
);
"Low Stock Alert",
"The inventory item with ID " + inventoryItem->getId() +
" has very low quantity in the inventory"
);
}
}
/*
Function: sendLowStockAlerts
Description: Sends alerts to user for inventory items with low stock
Parameters:
- None
Returns:
- None
*/
void InventoryManagementService::sendLowStockAlerts()
{
auto& inventoryItems = m_dataStore.getInventoryItems();
@@ -80,7 +190,7 @@ void InventoryManagementService::sendLowStockAlerts()
{
throw std::runtime_error("The system has no admins present!");
}
for (int index = 0; index < inventoryItemsSize; index++)
for (int index = 0; index <= inventoryItemsSize; index++)
{
InventoryItem* inventoryItem = inventoryItems.getValueAt(index);
if (inventoryItem && inventoryItem->getQuantity() < config::threshold::INVENTORY_LOW_STOCK_THRESHOLD)
@@ -90,15 +200,6 @@ void InventoryManagementService::sendLowStockAlerts()
}
}
/*
Function: getObserverIDs
Description: Retrieves the IDs of all observers currently attached to the
InventoryManagementService.
Parameters:
- None
Returns:
- util::Vector<std::string>: Vector of observer user IDs
*/
util::Vector<std::string> InventoryManagementService::getObserverIDs()
{
util::Vector<std::string> observerIDs;
@@ -114,15 +215,6 @@ util::Vector<std::string> InventoryManagementService::getObserverIDs()
return observerIDs;
}
/*
Function: loadInventoryItems
Description: Loads inventory items from persistent storage into the datastore.
Uses FileManager to deserialize inventory items from the configured file.
Parameters:
- None
Returns:
- void
*/
void InventoryManagementService::loadInventoryItems()
{
util::FileManager<InventoryItem> inventoryItemFileManager(config::file::INVENTORYITEM_FILE);
@@ -135,15 +227,6 @@ void InventoryManagementService::loadInventoryItems()
}
}
/*
Function: saveInventoryItems
Description: Saves inventory items from the datastore to persistent storage.
Uses FileManager to serialize inventory items into the configured file.
Parameters:
- None
Returns:
- void
*/
void InventoryManagementService::saveInventoryItems()
{
util::FileManager<InventoryItem> inventoryItemFileManager(config::file::INVENTORYITEM_FILE);
@@ -151,191 +234,12 @@ void InventoryManagementService::saveInventoryItems()
inventoryItemFileManager.save(inventoryItems);
}
/*
Function: loadObservers
Description: Loads observer IDs from persistent storage and attaches corresponding
users as observers to the InventoryManagementService.
Parameters:
- None
Returns:
- void
*/
void InventoryManagementService::loadObservers()
{
util::loadObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this, m_dataStore);
}
/*
Function: saveObservers
Description: Saves the current observer IDs of the InventoryManagementService
to persistent storage for future retrieval.
Parameters:
- None
Returns:
- void
*/
void InventoryManagementService::saveObservers()
{
util::saveObservers(config::file::INVENTORYMANAGEMENTOBSERVERS, this);
}
/*
Function: addInventoryItem
Description: Creates a new inventory item using the Factory and inserts it
into the DataStore.
Parameter: const std::string& partName - name of the part
int quantity - initial quantity of the part
double price - price of the part
Return type: void
*/
void InventoryManagementService::addInventoryItem(const std::string& partName, int quantity, double price)
{
InventoryItem* newItem = Factory::getObject<InventoryItem>(partName, quantity, price);
m_dataStore.getInventoryItems().insert(newItem->getId(), newItem);
}
/*
Function: addInventoryItemStock
Description: Increases the stock quantity of an existing inventory item.
Parameter: const std::string& selectedItemId - ID of the inventory item
int quantity - quantity to add
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);
}
}
}
/*
Function: getInventoryItems
Description: Retrieves all inventory items stored in the DataStore.
Parameter: None
Return type: util::Map<std::string, InventoryItem*>
*/
util::Map<std::string, InventoryItem*> InventoryManagementService::getInventoryItems()
{
return m_dataStore.getInventoryItems();
}
/*
Function: removeInventoryItem
Description: Marks an inventory item as inactive instead of deleting it.
Parameter: const std::string& inventoryItemID - ID of the inventory item
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);
}
}
}
/*
Function: getInventoryItem
Description: Retrieves a specific inventory item by its ID from the DataStore.
Parameter: const std::string& inventoryItemID - ID of the inventory item
Return type: InventoryItem*
*/
InventoryItem* InventoryManagementService::getInventoryItem(const std::string& inventoryItemID)
{
int index = m_dataStore.getInventoryItems().find(inventoryItemID);
if (index != -1)
{
return m_dataStore.getInventoryItems().getValueAt(index);
}
return nullptr;
}
/*
Function: attach
Description: Adds a user to the observer list for receiving inventory notifications.
Parameters:
- user: User*, pointer to the user to be attached as an observer
Returns:
- None
*/
void InventoryManagementService::attach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) == -1)
{
m_observers[userID] = user;
}
}
}
/*
Function: detach
Description: Removes a user from the observer list so they no longer receive inventory notifications.
Parameters:
- user: User*, pointer to the user to be detached from the observer list
Returns:
- None
*/
void InventoryManagementService::detach(User* user)
{
if (user)
{
const std::string& userID = user->getId();
if (m_observers.find(userID) != -1)
{
m_observers.remove(userID);
}
}
}
/*
Function: sendNotification
Description: Sends a notification to a user if they are subscribed as an observer.
Parameters:
- user: User*, pointer to the user receiving the notification
- title: std::string, title of the notification
- message: std::string, body/content of the notification
Returns:
- None
Throws:
- std::runtime_error if notification creation fails
*/
void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message)
{
if (user)
{
if (m_observers.find(user->getId()) != -1)
{
Notification* notification =
Factory::getObject<Notification>(
user->getId(),
user,
title,
message,
util::Timestamp()
);
if (notification)
{
user->addNotification(notification);
}
else
{
throw std::runtime_error("Failed to create notification");
}
}
}
}
@@ -6,7 +6,6 @@ Description: Header file declaring the InventoryManagementService class,
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include <string>
#include "Map.h"
@@ -8,6 +8,7 @@ Date: 20-May-2026
*/
#include <stdexcept>
#include "PaymentManagementService.h"
#include "Config.h"
#include "Enums.h"
#include "Factory.h"
@@ -15,7 +16,6 @@ Date: 20-May-2026
#include "InventoryItem.h"
#include "Invoice.h"
#include "JobCard.h"
#include "PaymentManagementService.h"
#include "Service.h"
#include "ServiceBooking.h"
#include "Timestamp.h"
@@ -24,6 +24,90 @@ Date: 20-May-2026
util::Map<std::string, User*> PaymentManagementService::m_observers{};
static void createInventoryItemsMap(util::Map<std::string, InventoryItem*>& completeInventoryItemMapOfBooking, const Service* currentService)
{
auto& currentRequiredInventoryItems = currentService->getRequiredInventoryItems();
for (int iterator = 0; iterator < currentRequiredInventoryItems.getSize(); iterator++)
{
auto& currentRequiredInventoryItem = currentRequiredInventoryItems.getValueAt(iterator);
completeInventoryItemMapOfBooking.insert(currentRequiredInventoryItem->getId(), currentRequiredInventoryItem);
}
}
void PaymentManagementService::generateInvoice(ServiceBooking* booking)
{
if (!booking)
{
throw std::runtime_error("Invoice generation failed: booking is null.");
}
double totalLabourCost = 0, totalPartsCost = 0, totalServiceCost = 0;
double discountPercentage = booking->getDiscountPercentage();
std::string bookingID = booking->getId();
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
util::Map<std::string, InventoryItem*> completeInventoryItemMapOfBooking;
util::Map<std::string, JobCard*> currentJobCards = m_dataStore.getJobCards();
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
{
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
if (currentJobCard->getBookingId() == bookingID && currentJobCard->getStatus() != util::ServiceJobStatus::COMPLETED)
{
throw std::runtime_error("Invoice generation failed: not all job cards are completed for booking '" + bookingID + "'.");
}
}
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
{
Service* currentService = servicesInTheBookedService.getValueAt(iterator);
if (currentService)
{
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
totalLabourCost += currentService->getLaborCost();
totalPartsCost += util::calculatePartsCost(currentService);
}
}
totalServiceCost = totalLabourCost + totalPartsCost;
totalServiceCost -= (totalServiceCost * (discountPercentage / 100));
Invoice* invoice = Factory::getObject<Invoice>(bookingID, booking, util::Timestamp(), totalLabourCost, completeInventoryItemMapOfBooking, totalPartsCost, discountPercentage, totalServiceCost, util::Timestamp(), util::PaymentMode::NOTSET, util::PaymentStatus::PENDING);
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
currentInvoices.insert(invoice->getId(), invoice);
}
util::Map<std::string, Invoice*> PaymentManagementService::getInvoices(const std::string& customerID)
{
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
util::Map<std::string, Invoice*> currentUserInvoices;
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
{
Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
if (currentInvoice->getBooking()->getCustomerId() == customerID)
{
currentUserInvoices.insert(currentInvoice->getId(), currentInvoice);
}
}
return currentUserInvoices;
}
void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
{
auto& currentInvoices = m_dataStore.getInvoices();
int invoiceIndex = currentInvoices.find(invoiceID);
if (invoiceIndex != -1)
{
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
User* currentUser = invoice->getBooking()->getCustomer();
invoice->setPaymentMethod(paymentMode);
invoice->setPaymentDate(util::Timestamp());
invoice->setStatus(util::PaymentStatus::COMPLETED);
std::string title, message;
title = "Payment successful";
message = "Payment successful for invoice ID " + invoiceID;
sendNotification(currentUser, title, message);
}
else
{
throw std::runtime_error("Payment failed: invalid invoice ID.");
}
}
/*
Function: attach
Description: Attaches a user as an observer to the PaymentManagementService for receiving notifications.
@@ -86,7 +170,7 @@ void PaymentManagementService::sendNotification(User* user, const std::string& t
Factory::getObject<Notification>(
user->getId(),
user,
title,
"PaymentManagementService: " + title,
message,
util::Timestamp()
);
@@ -130,9 +214,9 @@ void PaymentManagementService::sendPaymentReminders()
User* customer = serviceBooking->getCustomer();
if (customer)
{
std::string title = "Payment Reminder";
std::string message = "Your payment for Invoice ID " + invoice->getId() + " is still pending. Please complete the payment.";
sendNotification(customer, title, message);
sendNotification(customer,
"Payment Reminder",
"Your payment for Invoice ID " + invoice->getId() + " is still pending.Please complete the payment." + invoice->getId());
}
}
}
@@ -140,15 +224,6 @@ void PaymentManagementService::sendPaymentReminders()
}
}
/*
Function: getObserverIDs
Description: Retrieves the IDs of all observers currently attached to the
PaymentManagementService.
Parameters:
- None
Returns:
- util::Vector<std::string>: Vector of observer user IDs
*/
util::Vector<std::string> PaymentManagementService::getObserverIDs()
{
util::Vector<std::string> observerIDs;
@@ -164,19 +239,6 @@ util::Vector<std::string> PaymentManagementService::getObserverIDs()
return observerIDs;
}
/*
Function: loadInvoices
Description: Loads invoices from persistent storage into the datastore.
Validates associated service bookings and inventory parts before
attaching them to each invoice. Throws exceptions if invalid IDs
are encountered.
Parameters:
- None
Returns:
- void
Throws:
- std::runtime_error if a booking ID or part ID is invalid
*/
void PaymentManagementService::loadInvoices()
{
util::FileManager<Invoice> invoiceFileManager(config::file::INVOICE_FILE);
@@ -210,16 +272,6 @@ void PaymentManagementService::loadInvoices()
invoices[invoice->getId()] = invoice;
}
}
/*
Function: saveInvoices
Description: Saves invoices from the datastore to persistent storage.
Uses FileManager to serialize invoices into the configured file.
Parameters:
- None
Returns:
- void
*/
void PaymentManagementService::saveInvoices()
{
util::FileManager<Invoice> invoiceFileManager(config::file::INVOICE_FILE);
@@ -227,161 +279,12 @@ void PaymentManagementService::saveInvoices()
invoiceFileManager.save(invoices);
}
/*
Function: loadObservers
Description: Loads observer IDs from persistent storage and attaches corresponding
users as observers to the PaymentManagementService.
Parameters:
- None
Returns:
- void
Throws:
- std::runtime_error if an observer ID is invalid (not found in datastore)
*/
void PaymentManagementService::loadObservers()
{
util::loadObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this, m_dataStore);
}
/*
Function: saveObservers
Description: Saves the current observer IDs of the PaymentManagementService
to persistent storage for future retrieval.
Parameters:
- None
Returns:
- void
*/
void PaymentManagementService::saveObservers()
{
util::saveObservers(config::file::PAYMENTMANAGEMENTOBSERVERS, this);
}
/*
Function: createInventoryItemsMap (static helper)
Description: Builds a map of inventory items required for a given service and adds them to the bookings inventory map.
Parameters:
- completeInventoryItemMapOfBooking: util::Map<std::string, InventoryItem*>&, map to store inventory items for the booking
- currentService: const Service*, pointer to the current service
Returns:
- void
*/
static void createInventoryItemsMap(util::Map<std::string, InventoryItem*>& completeInventoryItemMapOfBooking, const Service* currentService)
{
auto& currentRequiredInventoryItems = currentService->getRequiredInventoryItems();
for (int iterator = 0; iterator < currentRequiredInventoryItems.getSize(); iterator++)
{
auto& currentRequiredInventoryItem = currentRequiredInventoryItems.getValueAt(iterator);
completeInventoryItemMapOfBooking.insert(currentRequiredInventoryItem->getId(), currentRequiredInventoryItem);
}
}
/*
Function: generateInvoice
Description: Generates an invoice for a completed service booking.
Validates that all job cards are completed, calculates labor and parts cost, applies discount,
and stores the invoice in the datastore.
Parameters:
- booking: ServiceBooking*, pointer to the service booking
Returns:
- void
Throws:
- std::runtime_error if booking is null or job cards are incomplete
*/
void PaymentManagementService::generateInvoice(ServiceBooking* booking)
{
if (!booking)
{
throw std::runtime_error("Invoice generation failed: booking is null.");
}
double totalLaborCost = 0, totalPartsCost = 0, totalServiceCost = 0;
double discountPercentage = booking->getDiscountPercentage();
std::string bookingID = booking->getId();
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
util::Map<std::string, InventoryItem*> completeInventoryItemMapOfBooking;
util::Map<std::string, JobCard*> currentJobCards = m_dataStore.getJobCards();
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
{
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
util::ServiceJobStatus currentJobCardStatus = currentJobCard->getStatus();
if (currentJobCard->getBookingId() == bookingID && currentJobCardStatus != util::ServiceJobStatus::CANCELLED && currentJobCardStatus != util::ServiceJobStatus::COMPLETED)
{
throw std::runtime_error("Invoice generation failed: Not all job cards are completed for booking '" + bookingID + "'.");
}
}
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
{
Service* currentService = servicesInTheBookedService.getValueAt(iterator);
if (currentService)
{
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
totalLaborCost += currentService->getLaborCost();
totalPartsCost += util::calculatePartsCost(currentService);
}
}
totalServiceCost = totalLaborCost + totalPartsCost;
totalServiceCost -= (totalServiceCost * (discountPercentage / 100));
Invoice* invoice = Factory::getObject<Invoice>(bookingID, booking, util::Timestamp(), totalLaborCost, completeInventoryItemMapOfBooking, totalPartsCost, discountPercentage, totalServiceCost, util::Timestamp(), util::PaymentMode::NOTSET, util::PaymentStatus::PENDING);
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
currentInvoices.insert(invoice->getId(), invoice);
}
/*
Function: getInvoices
Description: Retrieves all invoices associated with a specific customer.
Parameters:
- customerID: std::string, ID of the customer
Returns:
- util::Map<std::string, Invoice*> containing the customers invoices
*/
util::Map<std::string, Invoice*> PaymentManagementService::getInvoices(const std::string& customerID)
{
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
util::Map<std::string, Invoice*> currentUserInvoices;
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
{
Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
if (currentInvoice->getBooking()->getCustomerId() == customerID)
{
currentUserInvoices.insert(currentInvoice->getId(), currentInvoice);
}
}
return currentUserInvoices;
}
/*
Function: completePayment
Description: Completes payment for a specific invoice. Updates payment method, date, and status,
then sends a notification to the customer.
Parameters:
- invoiceID: std::string, ID of the invoice
- paymentMode: util::PaymentMode, mode of payment (e.g., ONLINE, OFFLINE)
Returns:
- void
Throws:
- std::runtime_error if the invoice ID is invalid
*/
void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode)
{
auto& currentInvoices = m_dataStore.getInvoices();
int invoiceIndex = currentInvoices.find(invoiceID);
if (invoiceIndex != -1)
{
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED)
{
User* currentUser = invoice->getBooking()->getCustomer();
invoice->setPaymentMethod(paymentMode);
invoice->setPaymentDate(util::Timestamp());
invoice->setStatus(util::PaymentStatus::COMPLETED);
std::string title, message;
title = "Payment successful";
message = "Payment successful for Invoice ID " + invoiceID;
sendNotification(currentUser, title, message);
}
}
else
{
throw std::runtime_error("Payment failed: invalid invoice ID.");
}
}
@@ -6,7 +6,6 @@ Description: Header file declaring the ServiceManagementService class, which man
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include <string>
#include "Map.h"
@@ -1,8 +1,7 @@
/*
File: UserManagementService.cpp
Description: Implementation file containing the method definitions of the
UserManagementService class, including user creation, updates,
and ensuring an admin account exists.
UserManagementService class, including user retrieval and removal logic.
Author: Trenser
Date:19-May-2026
*/
@@ -13,22 +12,14 @@ Date:19-May-2026
#include "Factory.h"
#include "FileManager.h"
#include "InventoryManagementService.h"
#include "Notification.h"
#include "Invoice.h"
#include "PaymentManagementService.h"
#include "ServiceManagementService.h"
#include "User.h"
#include "UserManagementService.h"
#include "Utility.h"
#include "Vector.h"
#include "Validator.h"
/*
Function: ensureAdminExists
Description: Ensures that at least one admin user exists in the system.
If no admin is found, creates a default admin user using
configuration constants.
Parameter: None
Return type: void
*/
void UserManagementService::ensureAdminExists()
{
auto& usersMap = m_dataStore.getUsers();
@@ -55,37 +46,22 @@ void UserManagementService::ensureAdminExists()
}
}
/*
Function: createUser
Description: Creates a new user with the provided details. Validates that
the username is unique, then attaches the user to relevant
management services (payment, service, inventory).
Parameter: const std::string& username - users username
const std::string& name - users name
const std::string& password - users password
const std::string& email - users email address
const std::string& phone - users phone number
util::UserType type - type of user (ADMIN, CUSTOMER, TECHNICIAN)
Return type: void
*/
void UserManagementService::createUser(const std::string& username, const std::string& name, const std::string& password, const std::string& email, const std::string& phone, util::UserType type)
{
InventoryManagementService inventoryManagementService;
PaymentManagementService paymentManagementService;
ServiceManagementService serviceManagementService;
auto& usersMap = m_dataStore.getUsers();
if (util::isUsernameDuplicate(username, usersMap))
int index = usersMap.findIf(
[&](const std::string&, User* user)
{
return user->getUserName() == username;
}
);
if (index != -1)
{
throw std::runtime_error("Username already exists");
}
if (util::isEmailDuplicate(email, usersMap))
{
throw std::runtime_error("Email already exists");
}
if (util::isPhoneDuplicate(phone, usersMap))
{
throw std::runtime_error("Phone already exists");
}
User* newUser = Factory::getObject<User>(username, password, name, phone, email, type);
usersMap.insert(newUser->getId(), newUser);
paymentManagementService.attach(newUser);
@@ -96,42 +72,80 @@ void UserManagementService::createUser(const std::string& username, const std::s
}
}
/*
Function: updateUserDetails
Description: Updates the email and phone details of an existing user.
Throws an exception if the user does not exist.
Parameter: const std::string& userID - ID of the user to update
const std::string& email - new email address
const std::string& phone - new phone number
Return type: void
*/
void UserManagementService::updateUserDetails(const std::string& userID, const std::string& email, const std::string& phone)
{
auto& usersMap = m_dataStore.getUsers();
int index = usersMap.find(userID);
if (index == -1)
{
throw std::runtime_error("User does not exist!\n");
throw std::runtime_error("User does not exist!");
}
User* user = usersMap.getValueAt(index);
if (email != user->getEmail())
{
if (util::isEmailDuplicate(email, usersMap))
{
throw std::runtime_error("Email already exists!\n");
}
}
if (phone != user->getPhone())
{
if (util::isPhoneDuplicate(phone, usersMap))
{
throw std::runtime_error("Phone number already exists!\n");
}
}
user->setEmail(email);
user->setPhone(phone);
}
/*
Function: getUsers
Description: Retrieves all users stored in the DataStore.
Parameter: None
Return type: util::Map<std::string, User*>
*/
util::Map<std::string, User*> UserManagementService::getUsers()
{
return m_dataStore.getUsers();
}
util::Map<std::string, User*> UserManagementService::getUsers(util::UserType type)
{
util::Map<std::string, User*>& currentUsers = m_dataStore.getUsers();
util::Map<std::string, User*> filteredUsersMap;
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
{
User* currentUser = currentUsers.getValueAt(iterator);
if (currentUser->getUserType() == type)
{
filteredUsersMap.insert(currentUser->getId(), currentUser);
}
}
return filteredUsersMap;
}
/*
Function: getUser
Description: Retrieves a specific user by ID from the DataStore.
Parameter: const std::string& userID - ID of the user
Return type: User*
*/
User* UserManagementService::getUser(const std::string& userID)
{
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
return m_dataStore.getUsers().getValueAt(index);
}
return nullptr;
}
/*
Function: removeUser
Description: Marks a user as inactive in the DataStore instead of deleting them.
Parameter: const std::string& userID - ID of the user to remove
Return type: void
*/
void UserManagementService::removeUser(const std::string& userID)
{
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
User* user = m_dataStore.getUsers().getValueAt(index);
if (user != nullptr)
{
user->setState(util::State::INACTIVE);
}
}
}
/*
Function: getUserNotifications
Description: Retrieves all notifications associated with a given user ID.
@@ -157,7 +171,7 @@ util::Vector<Notification*> UserManagementService::getUserNotifications(const st
util::Vector<Notification*> notificationsVector;
for (int index = 0; index < numberOfNotifications; index++)
{
notificationsVector.push_back(notifications.getValueAt(index));
notificationsVector.push_back(notifications.getValueAt(index));
}
return notificationsVector;
}
@@ -194,18 +208,6 @@ void UserManagementService::deleteNotification(const std::string& notificationID
notifications.remove(notificationID);
}
/*
Function: loadUsers
Description: Loads users and notifications from persistent storage into the datastore.
Validates that each notifications recipient exists and attaches the
notification to the corresponding user.
Parameters:
- None
Returns:
- void
Throws:
- std::runtime_error if a notification recipient user ID is invalid
*/
void UserManagementService::loadUsers()
{
util::FileManager<User> userFileManager(config::file::USER_FILE);
@@ -233,15 +235,6 @@ void UserManagementService::loadUsers()
}
}
/*
Function: saveUsers
Description: Saves users and their notifications from the datastore to persistent storage.
Collects notifications from all users into a single map before saving.
Parameters:
- None
Returns:
- void
*/
void UserManagementService::saveUsers()
{
util::FileManager<User> userFileManager(config::file::USER_FILE);
@@ -261,78 +254,3 @@ void UserManagementService::saveUsers()
userFileManager.save(users);
notificationFileManager.save(notifications);
}
/*
Function: getUsers
Description: Retrieves all users stored in the DataStore.
Parameter: None
Return type: util::Map<std::string, User*>
*/
util::Map<std::string, User*> UserManagementService::getUsers()
{
return m_dataStore.getUsers();
}
/*
Function: getUser
Description: Retrieves a specific user by ID from the DataStore.
Parameter: const std::string& userID - ID of the user
Return type: User*
*/
User* UserManagementService::getUser(const std::string& userID)
{
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
return m_dataStore.getUsers().getValueAt(index);
}
return nullptr;
}
/*
Function: removeUser
Description: Marks a user as inactive in the DataStore instead of deleting them.
Parameter: const std::string& userID - ID of the user to remove
Return type: void
*/
void UserManagementService::removeUser(const std::string& userID)
{
InventoryManagementService inventoryManagementService;
PaymentManagementService paymentManagementService;
ServiceManagementService serviceManagementService;
int index = m_dataStore.getUsers().find(userID);
if (index != -1)
{
User* user = m_dataStore.getUsers().getValueAt(index);
if (user != nullptr)
{
if (user->getUserType() == util::UserType::CUSTOMER)
{
serviceManagementService.cancelCustomerServiceBookings(userID);
}
if (user->getUserType() == util::UserType::TECHNICIAN)
{
serviceManagementService.cancelTechnicianJobs(userID);
}
user->setState(util::State::INACTIVE);
inventoryManagementService.detach(user);
paymentManagementService.detach(user);
serviceManagementService.detach(user);
}
}
}
util::Map<std::string, User*> UserManagementService::getUsers(util::UserType type)
{
util::Map<std::string, User*>& currentUsers = m_dataStore.getUsers();
util::Map<std::string, User*> filteredUsersMap;
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
{
User* currentUser = currentUsers.getValueAt(iterator);
if (currentUser && currentUser->getState() == util::State::ACTIVE && currentUser->getUserType() == type)
{
filteredUsersMap.insert(currentUser->getId(), currentUser);
}
}
return filteredUsersMap;
}
@@ -1,8 +1,7 @@
/*
File: UserManagementService.h
Description: Header file declaring the UserManagementService class, which manages
user creation, updates, retrieval, removal, notifications, and ensures
the existence of an admin account.
user creation, updates, retrieval, removal, and notification handling.
Author: Trenser
Date:19-May-2026
*/
@@ -1,8 +1,7 @@
/*
File: Config.h
Description: Header file declaring configuration constants for the Vehicle Service System.
Includes default admin account details such as username, name, password,
email, and phone number.
Description: Defines configuration constants for system thresholds in the Vehicle Service Management System.
Includes limits for inventory stock alerts and payment reminder intervals.
Author: Trenser
Date: 21-May-2026
*/
@@ -137,10 +137,6 @@ namespace util
{
return PaymentMode::OFFLINE;
}
if (value == "NOTSET")
{
return PaymentMode::NOTSET;
}
throw std::invalid_argument("Invalid PaymentMode string");
}
@@ -1,67 +1,17 @@
/*
File: FileHelper.h
Description: Provides utility functions for loading and saving records
from and to CSV-like text files. Ensures files are created
if missing and supports simple record persistence.
Author: Trenser
Date: 22-May-2026
*/
#pragma once
#include <fstream>
#include <string>
#include <stdexcept>
#include <direct.h>
#include "Vector.h"
namespace util
{
/*
Function: ensureDirectoryExists
Description: Creates all missing directories present in the given file path.
Iteratively parses the path and creates each directory level
using _mkdir() before file operations are performed.
Parameters:
- filePath: const std::string&, relative or absolute file path
Returns:
- void
Throws:
- None (_mkdir failures are intentionally ignored if directory already exists)
*/
inline void ensureDirectoryExists(const std::string& filePath)
{
size_t position = 0;
while ((position = filePath.find('/', position)) != std::string::npos)
{
std::string directory = filePath.substr(0, position);
if (!directory.empty())
{
(void)_mkdir(directory.c_str());
}
position++;
}
}
/*
Function: loadRecords
Description: Loads records from a given file path into a vector of strings.
Skips the header line if present. Creates the file if it does not exist.
Parameters:
- filePath: const std::string&, path to the file
Returns:
- util::Vector<std::string>: Vector containing all records (excluding header)
Throws:
- None (creates file if missing)
*/
inline util::Vector<std::string> loadRecords(const std::string& filePath)
{
util::Vector<std::string> records;
std::ifstream file(filePath);
if (!file.is_open())
{
ensureDirectoryExists(filePath);
std::ofstream newFile(filePath);
newFile.close();
file.open(filePath);
@@ -80,18 +30,6 @@ namespace util
return records;
}
/*
Function: saveRecords
Description: Saves records to a given file path. Overwrites existing content
and writes a header line followed by all records.
Parameters:
- filePath: const std::string&, path to the file
- records: const util::Vector<std::string>&, vector of records to save
Returns:
- void
Throws:
- std::runtime_error if the file cannot be opened for writing
*/
inline void saveRecords(const std::string& filePath, const util::Vector<std::string>& records)
{
std::ofstream file(filePath, std::ios::trunc);
@@ -1,21 +1,9 @@
/*
File: FileManager.h
Description: Declares and implements a generic FileManager template class for
loading and saving objects to and from files. Uses serialization
and deserialization methods defined in the object type T.
Provides persistence support for system entities such as Users,
Services, InventoryItems, etc.
Author: Trenser
Date: 22-May-2026
*/
#pragma once
#include <stdexcept>
#include <string>
#include <stdexcept>
#include <fstream>
#include "Vector.h"
#include "Map.h"
#include "FileHelper.h"
namespace util
{
@@ -33,18 +21,6 @@ namespace util
void save(const objects<T>&);
};
/*
Function: load
Description: Loads records from the file into a map of objects.
Skips the header line, deserializes each record into an object of type T,
and stores them in a map keyed by object ID.
Parameters:
- None
Returns:
- util::Map<std::string, T*> containing deserialized objects
Throws:
- std::runtime_error if deserialization fails for any record
*/
template <typename T>
objects<T> FileManager<T>::load()
{
@@ -52,7 +28,6 @@ namespace util
std::ifstream file(m_filePath);
if (!file.is_open())
{
ensureDirectoryExists(m_filePath);
std::ofstream newFile(m_filePath);
newFile.close();
file.open(m_filePath);
@@ -83,17 +58,6 @@ namespace util
return records;
}
/*
Function: save
Description: Saves records to the file. Serializes each object of type T into a string,
writes a header line, and then writes all serialized records to the file.
Parameters:
- records: const util::Map<std::string, T*>&, map of objects to save
Returns:
- void
Throws:
- std::runtime_error if the file cannot be opened for writing
*/
template <typename T>
void FileManager<T>::save(const objects<T>& records)
{
@@ -62,7 +62,6 @@ namespace util
*/
inline void pressEnter()
{
std::cout << std::endl;
system("pause");
}
}
@@ -21,28 +21,4 @@ namespace util
{
std::cout << "\x1B[2J\x1B[H" << std::flush;
}
/*
Function: truncateString
Description:
Truncates a string if its length exceeds the given maximum length.
The truncated string ends with "..." to indicate omitted characters.
Parameters:
- text: const std::string&, input string to truncate
- maxLength: size_t, maximum allowed length of the returned string
Returns:
- std::string: Original string if within limit, otherwise truncated string with "..."
*/
inline std::string truncateString(const std::string& text, size_t maxLength)
{
if (text.length() <= maxLength)
{
return text;
}
if (maxLength <= 3)
{
return std::string(maxLength, '.');
}
return text.substr(0, maxLength - 3) + "...";
}
}
@@ -1,26 +1,8 @@
/*
File: StringHelper.h
Description: Provides utility functions for extracting numeric values from strings.
Useful for parsing IDs, codes, or mixed alphanumeric inputs where
digits need to be isolated and converted into integers.
Author: Trenser
Date: 22-May-2026
*/
#include <cctype>
#include <string>
namespace util
{
/*
Function: extractNumber
Description: Extracts all digits from the given string and converts them into an integer.
Ignores non-digit characters. For example, "abc123xyz" returns 123.
Parameters:
- input: const std::string&, the input string containing digits and/or other characters
Returns:
- int: The integer value formed by concatenating all digits in the string
*/
inline int extractNumber(const std::string& input)
{
int result = 0;
@@ -1,17 +1,17 @@
/*
File: Utility.h
Description: Header file declaring utility functions used across the system
Description: Header file declaring utility functions used across the system,
including cost calculation for services based on required inventory items.
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include "Service.h"
#include "ComboPackage.h"
#include "DataStore.h"
#include "FileHelper.h"
#include "InventoryItem.h"
#include "NotificationManagementService.h"
#include "Service.h"
#include "FileHelper.h"
#include "DataStore.h"
namespace util
{
@@ -37,9 +37,11 @@ namespace util
/*
Function: calculateComboServiceEstimatedCost
Description: Calculates the estimated total cost of a combo package by summing
the labor and parts costs of all services included in the package.
Parameter: const ComboPackage* comboPackage - pointer to the combo package object
Return type: double - estimated total cost of the combo package
the labor cost and parts cost of all services included in the package.
Parameters:
- comboPackage: const ComboPackage*, pointer to the combo package whose cost is to be estimated
Returns:
- double: The estimated total cost of the combo package
*/
inline double calculateComboServiceEstimatedCost(const ComboPackage* comboPackage)
{
@@ -54,20 +56,6 @@ namespace util
return cost;
}
/*
Function: loadObservers
Description: Loads observer IDs from a file and attaches the corresponding users
to the notification management service. Validates that each observer ID
exists in the datastore before attaching.
Parameters:
- filePath: const std::string&, path to the file containing observer IDs
- service: NotificationManagementService*, pointer to the notification service
- dataStore: DataStore&, reference to the datastore containing users
Returns:
- void
Throws:
- std::runtime_error if an observer ID is invalid (not found in datastore)
*/
inline void loadObservers(const std::string& filePath, NotificationManagementService* service, DataStore& dataStore)
{
auto observerIDs = util::loadRecords(filePath);
@@ -84,16 +72,6 @@ namespace util
}
}
/*
Function: saveObservers
Description: Saves the current observer IDs from the notification management service
to a file for persistence.
Parameters:
- filePath: const std::string&, path to the file where observer IDs will be saved
- service: NotificationManagementService*, pointer to the notification service
Returns:
- void
*/
inline void saveObservers(const std::string& filePath, NotificationManagementService* service)
{
auto observerIDs = service->getObserverIDs();
@@ -107,69 +107,3 @@ bool util::isPasswordValid(const std::string& password)
return hasUpper && hasLower && hasDigit && hasSpecial;
}
/*
* Function: isUsernameDuplicate
* Description: Checks if the given username already exists among active users.
* Parameters:
* username - string containing the username to validate
* usersMap - map of user objects keyed by identifier
* Returns:
* bool - true if the username is already in use by an active user, false otherwise
* Notes:
* - Only considers users with state util::State::ACTIVE
*/
bool util::isUsernameDuplicate(const std::string& username, const util::Map<std::string, User*>& usersMap)
{
int index = usersMap.findIf(
[&](const std::string&, User* user)
{
return (user->getUserName() == username && user->getState() == util::State::ACTIVE);
}
);
return index != -1;
}
/*
* Function: isPhoneDuplicate
* Description: Checks if the given phone number already exists among active users.
* Parameters:
* phone - string containing the phone number to validate
* usersMap - map of user objects keyed by identifier
* Returns:
* bool - true if the phone number is already in use by an active user, false otherwise
* Notes:
* - Only considers users with state util::State::ACTIVE
*/
bool util::isPhoneDuplicate(const std::string& phone, const util::Map<std::string, User*>& usersMap)
{
int index = usersMap.findIf(
[&](const std::string&, User* user)
{
return (user->getPhone() == phone && user->getState() == util::State::ACTIVE);
}
);
return index != -1;
}
/*
* Function: isEmailDuplicate
* Description: Checks if the given email address already exists among active users.
* Parameters:
* email - string containing the email address to validate
* usersMap - map of user objects keyed by identifier
* Returns:
* bool - true if the email address is already in use by an active user, false otherwise
* Notes:
* - Only considers users with state util::State::ACTIVE
*/
bool util::isEmailDuplicate(const std::string& email, const util::Map<std::string, User*>& usersMap)
{
int index = usersMap.findIf(
[&](const std::string&, User* user)
{
return (user->getEmail() == email && user->getState() == util::State::ACTIVE);
}
);
return index != -1;
}
@@ -9,15 +9,10 @@
#include<string>
#include<algorithm>
#include<cctype>
#include "Map.h"
#include "User.h"
namespace util
{
bool isPhoneNumberValid(const std::string&);
bool isEmailValid(const std::string&);
bool isPasswordValid(const std::string&);
bool isUsernameDuplicate(const std::string&, const util::Map<std::string, User*>&);
bool isPhoneDuplicate(const std::string&, const util::Map<std::string, User*>&);
bool isEmailDuplicate(const std::string&, const util::Map<std::string, User*>&);
}
File diff suppressed because it is too large Load Diff
@@ -6,7 +6,6 @@ Description: Header file declaring the AdminMenu class, which provides
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include "Controller.h"
@@ -24,13 +23,10 @@ public:
void removeInventoryItem();
void checkStockAvailability();
void assignJob();
void displayServices();
void createService();
void removeService();
void displayUsers();
void addTechnician();
void removeUser();
void displayComboPackages();
void createComboPackages();
void removeComboPackage();
void viewNotifications();
@@ -1,36 +1,41 @@
/*
File: CustomerMenu.cpp
Description: Implementation file containing the method definitions of the
CustomerMenu class, including menu handling, service selection,
combo package booking, profile updates, and password management.
Description: Implements the CustomerMenu class which provides the customers console interface
in the Vehicle Service Management System. Handles menu display, user input, and
customer-specific operations such as booking services, viewing history, managing payments,
invoices, and notifications.
Author: Trenser
Date:19-May-2026
Date: 19-May-2026
*/
#include <iomanip>
#include <iostream>
#include "ComboPackage.h"
#include "CustomerMenu.h"
#include "MenuHelper.h"
#include "Enums.h"
#include "InputHelper.h"
#include "OutputHelper.h"
#include "InventoryItem.h"
#include "Invoice.h"
#include "Map.h"
#include "MenuHelper.h"
#include "OutputHelper.h"
#include "Service.h"
#include "ServiceBooking.h"
#include "Timestamp.h"
#include "User.h"
#include "Utility.h"
#include "Validator.h"
#include "Vector.h"
/*
Function: showMenu
Description: Displays the customer menu and handles user input until logout is selected.
Parameter: None
Return type: void
Description: Displays the customer menu in a loop until the user chooses to logout.
Handles exceptions and ensures smooth user interaction.
Parameters:
- None
Returns:
- void
*/
void CustomerMenu::showMenu()
{
while (true)
@@ -65,12 +70,6 @@ void CustomerMenu::showMenu()
}
}
/*
Function: handleOperation
Description: Executes the corresponding customer operation based on the selected menu choice.
Parameter: int choice - selected menu option
Return type: bool - true if menu continues, false if logout
*/
bool CustomerMenu::handleOperation(int choice)
{
switch (choice)
@@ -112,44 +111,37 @@ bool CustomerMenu::handleOperation(int choice)
return true;
}
/*
Function: logout
Description: Logs out the currently authenticated customer user.
Parameter: None
Return type: void
*/
void CustomerMenu::logout()
{
m_controller.logout();
}
/*
Function: changePassword
Description: Allows the customer to change their password after validation.
Parameter: None
Return type: void
*/
void CustomerMenu::changePassword()
{
changePasswordHelper(m_controller);
std::string newPassword;
util::clear();
std::cout << "Enter new password: ";
util::read(newPassword);
m_controller.changePassword(newPassword);
if (!util::isPasswordValid(newPassword))
{
std::cout << "Error: Password is not strong enough!";
util::pressEnter();
return;
}
std::cout << "Password changed successfully";
util::pressEnter();
}
/*
Function: updateDetails
Description: Allows the customer to update their email and phone number after validation.
Parameter: None
Return type: void
*/
void CustomerMenu::updateDetails()
{
std::string email, phone;
util::clear();
std::cout << "Update Details\n";
std::cout << "Enter new email: ";
util::read(email);
if (!util::isEmailValid(email))
{
std::cout << "Error: Email is invalid!\n";
std::cout << "Error: Email is invalid!";
util::pressEnter();
return;
}
@@ -157,35 +149,64 @@ void CustomerMenu::updateDetails()
util::read(phone);
if (!util::isPhoneNumberValid(phone))
{
std::cout << "Error: Phone number is invalid!\n";
std::cout << "Error: Phone number is invalid!";
util::pressEnter();
return;
}
m_controller.updateUserDetails(email, phone);
std::cout << "Profile details updated successfully\n";
std::cout << "Profile details updated successfully";
util::pressEnter();
}
/*
Function: selectService
Description: Allows the customer to select a service, provide vehicle details,
and book the service through the controller.
Parameter: None
Return type: void
*/
static const Service* selectServiceFromServices(const util::Map<std::string, const Service*>& services)
{
util::Map<int, const Service*> activeServicesMap;
int currentIndex = 1;
int userInputIndex;
std::cout << std::left
<< std::setw(10) << "Index"
<< std::setw(15) << "Service ID"
<< std::setw(25) << "Service Name"
<< std::setw(15) << "Estimated Cost"
<< std::endl;
for (int index = 0; index < services.getSize(); index++)
{
const Service* currentService = services.getValueAt(index);
if (currentService->getState() != util::State::ACTIVE)
{
continue;
}
activeServicesMap.insert(currentIndex, currentService);
double partsCost = util::calculatePartsCost(currentService);
std::cout << std::left
<< std::setw(10) << currentIndex
<< std::setw(15) << currentService->getId()
<< std::setw(25) << currentService->getName()
<< std::setw(15) << (currentService->getLaborCost() + partsCost)
<< std::endl;
currentIndex++;
}
if (activeServicesMap.getSize() == 0)
{
std::cout << "No active services available." << std::endl;
return nullptr;
}
std::cout << "Enter service index: ";
util::read(userInputIndex);
if (activeServicesMap.find(userInputIndex) == -1)
{
std::cout << "Invalid service index." << std::endl;
return nullptr;
}
return activeServicesMap[userInputIndex];
}
void CustomerMenu::selectService()
{
std::string vehicleNumber, vehicleBrand, vehicleModel;
util::clear();
std::cout << "Select a Service\n";
auto services = m_controller.getServices();
if (services.isEmpty())
{
std::cout << "No services available!";
util::pressEnter();
return;
}
util::Vector<std::string> selectedServices;
util::clear();
const Service* selectedService = selectServiceFromServices(services);
if (selectedService == nullptr)
{
@@ -195,7 +216,6 @@ void CustomerMenu::selectService()
}
selectedServices.push_back(selectedService->getId());
util::clear();
std::cout << "Enter Vehicle Details\n";
std::cout << "Enter vehicle number: ";
util::read(vehicleNumber);
std::cout << "Enter vehicle brand: ";
@@ -207,37 +227,61 @@ void CustomerMenu::selectService()
util::pressEnter();
}
/*
Function: selectComboPackage
Description: Allows the customer to select a combo package, provide vehicle details,
and book the package through the controller.
Parameter: None
Return type: void
*/
static const ComboPackage* selectComboPackageFromPackages(const util::Map<std::string, const ComboPackage*>& comboPackages)
{
util::Map<int, const ComboPackage*> activeComboPackages;
int currentIndex = 1;
int userInputIndex;
std::cout << std::left
<< std::setw(10) << "Index"
<< std::setw(15) << "Combo Package ID"
<< std::setw(15) << "Combo Package Name"
<< std::setw(15) << "Estimate Cost"
<< std::endl;
for (int index = 0; index < comboPackages.getSize(); index++)
{
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
if (currentComboPackage->getState() != util::State::ACTIVE)
{
continue;
}
activeComboPackages.insert(currentIndex, currentComboPackage);
std::cout << std::left
<< std::setw(10) << currentIndex
<< std::setw(15) << currentComboPackage->getId()
<< std::setw(25) << currentComboPackage->getPackageName()
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
<< std::endl;
currentIndex++;
}
if (activeComboPackages.getSize() == 0)
{
std::cout << "No active combo packages available." << std::endl;
return nullptr;
}
std::cout << "Enter combo package index: ";
util::read(userInputIndex);
if (activeComboPackages.find(userInputIndex) == -1)
{
std::cout << "Invalid combo package index." << std::endl;
return nullptr;
}
return activeComboPackages[userInputIndex];
}
void CustomerMenu::selectComboPackage()
{
std::string vehicleNumber, vehicleBrand, vehicleModel;
util::clear();
std::cout << "Select a Combo Package\n";
auto comboPackages = m_controller.getComboPackages();
util::Map<std::string, const ComboPackage*> activeComboPackages = filterComboPackages(comboPackages);
if (activeComboPackages.isEmpty())
{
std::cout << "No combo packages available!\n\n";
util::pressEnter();
return;
}
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(activeComboPackages);
util::clear();
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(comboPackages);
if (selectedComboPackage == nullptr)
{
std::cout << "Failed to book combo package!\n\n";
std::cout << "Failed to book combo package!";
util::pressEnter();
return;
}
std::cout << "Combo Package selected\n";
util::pressEnter();
util::clear();
std::cout << "Enter the vehicle details\n";
std::cout << "Enter vehicle number: ";
util::read(vehicleNumber);
std::cout << "Enter vehicle brand: ";
@@ -245,37 +289,27 @@ void CustomerMenu::selectComboPackage()
std::cout << "Enter vehicle model: ";
util::read(vehicleModel);
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
std::cout << "Combo Package has been booked successfully\n\n";
std::cout << "Combo Package has been booked successfully";
util::pressEnter();
}
/*
Function: viewServiceHistory
Description: Displays the customers past service bookings in tabular format,
including booking ID, technician, vehicle details, discount percentage, and status.
Parameters:
- None
Returns:
- void
*/
void CustomerMenu::viewServiceHistory()
{
util::clear();
bool hasServiceHistory = false;
const User* currentUser = m_controller.getAuthenticatedUser();
std::string currentUserID = currentUser->getId();
util::Map<std::string, const ServiceBooking*> serviceBookingsByCurrentUser = m_controller.getServiceBookingsByUser(currentUserID);
std::cout << "View Service History" << std::endl;
util::clear();
bool hasServiceHistory = false;
const User* currentUser = m_controller.getAuthenticatedUser();
std::string currentUserID = currentUser->getId();
util::Map<std::string, const ServiceBooking*> serviceBookingsByCurrentUser = m_controller.getServiceBookingsByUser(currentUserID);
if (serviceBookingsByCurrentUser.getSize() != 0)
{
std::cout << std::left
<< std::setw(15) << "Booking ID"
<< std::setw(12) << "Booking ID"
<< std::setw(20) << "Technician"
<< std::setw(20) << "Vehicle Brand"
<< std::setw(20) << "Vehicle Number"
<< std::setw(20) << "Vehicle Model"
<< std::setw(20) << "Discount %"
<< std::setw(20) << "Status"
<< std::setw(15) << "Vehicle Brand"
<< std::setw(15) << "Vehicle Number"
<< std::setw(15) << "Vehicle Model"
<< std::setw(10) << "Discount %"
<< std::setw(12) << "Status"
<< std::endl;
for (int iterator = 0; iterator < serviceBookingsByCurrentUser.getSize(); iterator++)
{
@@ -284,13 +318,13 @@ void CustomerMenu::viewServiceHistory()
? "Not Assigned"
: currentBooking->getAssignedTechnician()->getName();
std::cout << std::left
<< std::setw(15) << currentBooking->getId()
<< std::setw(12) << currentBooking->getId()
<< std::setw(20) << technicianName
<< std::setw(20) << currentBooking->getVehicleBrand()
<< std::setw(20) << currentBooking->getVehicleNumber()
<< std::setw(20) << currentBooking->getVehicleModel()
<< std::setw(20) << currentBooking->getDiscountPercentage()
<< std::setw(20) << util::getServiceJobStatusString(currentBooking->getStatus())
<< std::setw(15) << currentBooking->getVehicleBrand()
<< std::setw(15) << currentBooking->getVehicleNumber()
<< std::setw(15) << currentBooking->getVehicleModel()
<< std::setw(10) << currentBooking->getDiscountPercentage()
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
<< std::endl;
hasServiceHistory = true;
}
@@ -299,73 +333,155 @@ void CustomerMenu::viewServiceHistory()
{
std::cout << "No history available." << std::endl;
}
util::pressEnter();
}
/*
Function: completePayments
Description: Allows the customer to complete pending payments for invoices.
Validates invoice selection and payment mode before completing payment.
Parameters:
- None
Returns:
- void
*/
static std::string selectInvoiceFromUserForPayment(const util::Map<std::string, const Invoice*>& currentInvoices)
{
int currentIndex = 1, choice;
util::Map<int, const Invoice*> pendingInvoicesForPayment;
std::cout << std::left
<< std::setw(6) << "Index"
<< std::setw(12) << "BookingID"
<< std::setw(15) << "VehicleBrand"
<< std::setw(15) << "VehicleNumber"
<< std::setw(12) << "TechID"
<< std::setw(20) << "TechnicianName"
<< std::setw(10) << "Discount(%)"
<< std::setw(12) << "TotalAmount"
<< std::setw(20) << "InvoiceDate"
<< std::endl;
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
{
const Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING)
{
std::cout << std::left
<< std::setw(6) << currentIndex
<< std::setw(12) << currentInvoice->getBookingId()
<< std::setw(15) << currentInvoice->getBooking()->getVehicleBrand()
<< std::setw(15) << currentInvoice->getBooking()->getVehicleNumber()
<< std::setw(12) << currentInvoice->getBooking()->getAssignedTechnician()->getId()
<< std::setw(20) << currentInvoice->getBooking()->getAssignedTechnician()->getName()
<< std::setw(10) << currentInvoice->getDiscountPercentage()
<< std::setw(12) << currentInvoice->getTotalAmount()
<< std::setw(20) << currentInvoice->getInvoiceDate().toString()
<< std::endl;
pendingInvoicesForPayment.insert(currentIndex++, currentInvoice);
}
}
if (pendingInvoicesForPayment.getSize() == 0)
{
std::cout << "No pending invoices available for payment.\n";
return "";
}
std::cout << "Select the Invoice to pay (Index): ";
util::read(choice);
int selectedIndex = pendingInvoicesForPayment.find(choice);
if (selectedIndex != -1)
{
const Invoice* selectedInvoice = pendingInvoicesForPayment.getValueAt(selectedIndex);
return selectedInvoice->getId();
}
else
{
std::cout << "Invalid choice.\n";
return "";
}
}
static util::PaymentMode selectPaymentMode()
{
int choice;
std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: ";
util::read(choice);
if (choice == 1)
{
std::cout << "Offline mode selected.\n";
return util::PaymentMode::OFFLINE;
}
else if (choice == 2)
{
std::cout << "Online mode selected.\n";
return util::PaymentMode::ONLINE;
}
else
{
std::cout << "Invalid choice, Offline mode selected.\n";
return util::PaymentMode::OFFLINE;
}
}
void CustomerMenu::completePayments()
{
util::clear();
std::cout << "Complete Payments\n";
util::Map<std::string, const Invoice*> currentInvoices = m_controller.getInvoicesByUser();
if (currentInvoices.isEmpty())
{
std::cout << "No pending invoices available for payment.\n";
util::pressEnter();
return;
}
bool hasPending = false;
for (int index = 0; index < currentInvoices.getSize(); ++index)
{
const Invoice* invoice = currentInvoices.getValueAt(index);
if (invoice && invoice->getStatus() == util::PaymentStatus::PENDING)
{
hasPending = true;
break;
}
}
if (!hasPending)
{
std::cout << "No pending invoices available for payment.\n";
util::pressEnter();
return;
}
std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices);
if (selectedID == "")
{
std::cout << "Payment failed.\n";
util::pressEnter();
return;
}
util::PaymentMode paymentMode = selectPaymentMode();
m_controller.completePayment(selectedID, paymentMode);
std::cout << "Payment completed successfully.\n";
util::pressEnter();
}
/*
Function: viewInvoices
Description: Displays invoices associated with the customer by calling displayInvoices.
Parameters:
- None
Returns:
- void
*/
static void displayInvoices(util::Map<std::string, const Invoice*> currentUserInvoices)
{
if (currentUserInvoices.getSize() == 0)
{
std::cout << "No invoices found for this account." << std::endl;
util::pressEnter();
return;
}
else
{
for (int index = 0; index < currentUserInvoices.getSize(); index++)
{
const Invoice* currentInvoice = currentUserInvoices.getValueAt(index);
if (currentInvoice)
{
std::cout << "\nInvoice Details\n";
std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl;
std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl;
std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl;
std::cout << "Technician ID: " << currentInvoice->getBooking()->getAssignedTechnician()->getId() << std::endl;
std::cout << "Technician Name: " << currentInvoice->getBooking()->getAssignedTechnician()->getName() << std::endl;
std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl;
std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl;
std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl;
std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl;
auto inventoryItemsInInvoice = currentInvoice->getParts();
std::cout << "\nItems Used:\n";
std::cout << std::left
<< std::setw(20) << "ItemName"
<< std::setw(10) << "Quantity"
<< std::setw(10) << "Price"
<< std::endl;
std::cout << std::string(40, '-') << std::endl;
for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++)
{
InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator);
std::cout << std::left
<< std::setw(20) << currentItem->getPartName()
<< std::setw(10) << currentItem->getQuantity()
<< std::setw(10) << currentItem->getPrice()
<< std::endl;
}
}
else
{
throw std::runtime_error("Null invoice encountered while displaying invoices.");
}
}
}
}
void CustomerMenu::viewInvoices()
{
util::clear();
std::cout << "View Invoices\n";
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
displayInvoices(currentUserInvoices);
util::pressEnter();
}
/*
@@ -381,6 +497,38 @@ void CustomerMenu::viewNotifications()
viewAndDeleteNotification(m_controller);
}
/*
Function: getNotificationPreference (static helper)
Description: Helper function to configure notification preferences for a specific service.
Parameters:
- serviceName: Name of the service for which notifications are being configured.
Returns:
- bool: True if notifications are enabled, False if disabled.
*/
static bool getNotificationPreference(const std::string& serviceName)
{
int choice;
while (true)
{
util::clear();
std::cout << " Configure Notification Preferences\n";
std::cout << "\n" << serviceName << " Notifications\n";
std::cout << "1. Enable Notifications\n";
std::cout << "2. Disable Notifications\n";
std::cout << "Enter your choice: ";
util::read(choice);
if (choice == 1)
{
return true;
}
if (choice == 2)
{
return false;
}
std::cout << "\nInvalid choice. Please enter 1 or 2.\n";
util::pressEnter();
}
}
/*
Function: configureNotifications
@@ -1,11 +1,10 @@
/*
File: CustomerMenu.h
Description: Header file declaring the CustomerMenu class, which provides
customer operations such as selecting services, booking combo
packages, updating profile details, managing payments, viewing
invoices, and configuring notifications.
Description: Declares the CustomerMenu class which provides the customer-facing console menu in the Vehicle Service Management System.
Supports operations such as account management, service selection, combo package booking, viewing service history,
handling payments and invoices, and managing notifications.
Author: Trenser
Date:19-May-2026
Date: 19-May-2026
*/
#pragma once
File diff suppressed because it is too large Load Diff
@@ -7,6 +7,7 @@ Author: Trenser
Date:19-May-2026
*/
#include <iomanip>
#include "Enums.h"
#include "InputHelper.h"
#include "JobCard.h"
@@ -34,11 +35,10 @@ void TechnicianMenu::showMenu()
int choice;
util::clear();
std::cout << "Technician Menu"
<< "\n1. Display My Jobs"
<< "\n2. Mark Job as Completed"
<< "\n3. View Notifications"
<< "\n4. Change Password"
<< "\n5. Logout"
<< "\n1. Mark Job as Completed"
<< "\n2. View Notifications"
<< "\n3. Change Password"
<< "\n4. Logout"
<< "\nEnter a choice: ";
util::read(choice);
if (!handleOperation(choice))
@@ -65,18 +65,15 @@ bool TechnicianMenu::handleOperation(int choice)
switch (choice)
{
case 1:
displayJobs();
break;
case 2:
completeJob();
break;
case 3:
case 2:
viewNotifications();
break;
case 4:
case 3:
changePassword();
break;
case 5:
case 4:
logout();
return false;
default:
@@ -86,46 +83,69 @@ bool TechnicianMenu::handleOperation(int choice)
return true;
}
/*
Function: displayJobs
Description: Displays all Jobs assigned to a Technician
Parameters:
- None
Returns:
- void
*/
void TechnicianMenu::displayJobs()
static std::string selectJobCardToComplete(util::Map<std::string, const JobCard*>& assignedJobCards, util::Map<int, const JobCard*>& incompleteJobCards)
{
util::clear();
std::cout << "My Jobs\n";
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
displayAllJobs(startedJobCards);
util::pressEnter();
int currentIndex = 1;
int choice;
bool hasIncompleteJobCard = false;
std::cout << std::left
<< std::setw(6) << "Index"
<< std::setw(12) << "BookingID"
<< std::setw(12) << "JobID"
<< std::setw(20) << "ServiceName"
<< std::setw(12) << "ServiceID"
<< std::endl;
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
{
const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator);
if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED))
{
std::cout << std::left << std::setw(6) << currentIndex
<< std::setw(12) << currentJobCard->getBookingId()
<< std::setw(12) << currentJobCard->getId()
<< std::setw(20) << currentJobCard->getService()->getName()
<< std::setw(12) << currentJobCard->getServiceId()
<< std::endl;
hasIncompleteJobCard = true;
incompleteJobCards.insert(currentIndex++, currentJobCard);
}
}
if (!hasIncompleteJobCard)
{
std::cout << "No pending jobs are present.\n";
return "";
}
std::cout << "Select the Job Card to complete (Index): ";
util::read(choice);
int selectedJobCardIndex = incompleteJobCards.find(choice);
if (selectedJobCardIndex != -1)
{
const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex);
return selectedJobCard->getId();
}
else
{
std::cout << "Invalid choice.\n";
return "";
}
}
/*
Function: completeJob
Description: Allows the technician to mark a selected job card as completed.
Validates selection and updates job status through the controller.
Parameters:
- None
Returns:
- void
*/
void TechnicianMenu::completeJob()
{
util::clear();
std::cout << "Complete Job\n";
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
std::string selectedJobID = selectJobCardToComplete(startedJobCards);
if (!selectedJobID.empty())
util::Map<int, const JobCard*> incompleteJobCards;
std::cout << "Jobs to be completed.\n";
std::string selectedJobID = selectJobCardToComplete(assignedJobCards, incompleteJobCards);
if (selectedJobID == "")
{
std::cout << "Failed to complete the job.\n";
}
else
{
m_controller.completeJob(selectedJobID);
std::cout << "\nJob marked as completed.\n\n";
std::cout << "Job marked as completed.\n";
}
util::pressEnter();
}
/*
@@ -149,7 +169,7 @@ Return type: void
*/
void TechnicianMenu::logout()
{
m_controller.logout();
m_controller.logout();
}
/*
@@ -158,8 +178,23 @@ Description: Allows the technician to change their password after validation.
Parameter: None
Return type: void
*/
void TechnicianMenu::changePassword()
{
changePasswordHelper(m_controller);
std::string newPassword;
while (true)
{
util::clear();
std::cout << "Enter new password: ";
util::read(newPassword);
if (!util::isPasswordValid(newPassword))
{
std::cout << "Error: Password is not strong enough!\n";
util::pressEnter();
continue;
}
m_controller.changePassword(newPassword);
std::cout << "Password changed successfully\n";
util::pressEnter();
break;
}
}
@@ -6,7 +6,6 @@ Description: Header file declaring the TechnicianMenu class, which provides
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include "Controller.h"
@@ -17,7 +16,6 @@ private:
bool handleOperation(int choice);
public:
void showMenu();
void displayJobs();
void completeJob();
void viewNotifications();
void logout();
@@ -6,14 +6,11 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
#include <iostream>
#include <stdexcept>
#include "UserInterface.h"
#include "Enums.h"
#include "InputHelper.h"
#include "OutputHelper.h"
#include "User.h"
#include "UserInterface.h"
#include "Validator.h"
/*
@@ -25,44 +22,29 @@ Return type: void
*/
void UserInterface::run()
{
try
m_controller.loadSystemData();
m_controller.runSystemChecks();
bool isMenuActive = true;
while (isMenuActive)
{
m_controller.loadSystemData();
m_controller.runSystemChecks();
bool isMenuActive = true;
while (isMenuActive)
try
{
try
int choice;
util::clear();
std::cout << "Vehicle Service System\n1. Login\n2. Register Customer\n3. Exit\nEnter your Choice: ";
util::read(choice);
if (!handleOperation(choice))
{
int choice;
util::clear();
std::cout << "Vehicle Service System\n1. Login\n2. Register Customer\n3. Exit\nEnter your Choice: ";
util::read(choice);
if (!handleOperation(choice))
{
isMenuActive = false;
}
}
catch (const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
util::pressEnter();
isMenuActive = false;
}
}
m_controller.saveSystemData();
}
catch (const std::invalid_argument& exception)
{
std::cout << "Exception: Invalid Argument: " << exception.what() << std::endl;
}
catch (const std::exception& exception)
{
std::cout << "Exception: " << exception.what() << std::endl;
}
catch (...)
{
std::cout << "Unknown error occurred." << std::endl;
catch (const std::exception& e)
{
std::cout << "Exception: " << e.what() << std::endl;
util::pressEnter();
}
}
m_controller.saveSystemData();
}
/*
@@ -102,7 +84,6 @@ void UserInterface::login()
{
std::string username, password;
util::clear();
std::cout << "Login\n";
std::cout << "Enter username: ";
util::read(username);
std::cout << "Enter password: ";
@@ -110,7 +91,7 @@ void UserInterface::login()
if (m_controller.login(username, password))
{
const User* authenticatedUser = m_controller.getAuthenticatedUser();
if (authenticatedUser && authenticatedUser->getState() != util::State::INACTIVE)
if (authenticatedUser != nullptr)
{
switch (authenticatedUser->getUserType())
{
@@ -128,32 +109,25 @@ void UserInterface::login()
break;
}
}
else if (authenticatedUser && authenticatedUser->getState() == util::State::INACTIVE)
{
std::cout << "\nError: Your account has been disabled. Please contact your Administrator.";
util::pressEnter();
}
}
else
{
std::cout << "\nError: Invalid Username or Password";
util::pressEnter();
}
}
/*
Function: registerCustomer
Description: Registers a new customer by collecting and validating details such as
username, name, email, password, and phone number. Delegates creation
to the controller.
Parameter: None
Return type: void
Description: Handles the registration process for new customers.
Parameters:
- None
Returns:
- void
*/
void UserInterface::registerCustomer()
{
std::string username, name, email, phone, password;
util::clear();
std::cout << "Register Customer\n";
std::cout << "Enter username: ";
util::read(username);
std::cout << "Enter name: ";
@@ -7,7 +7,6 @@ Description: Header file declaring the UserInterface class, which provides
Author: Trenser
Date:19-May-2026
*/
#pragma once
#include "Controller.h"
#include "AdminMenu.h"