Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1b6125d88 | |||
| e739ec6ee2 | |||
| f78e02ed3d | |||
| 807490443e | |||
| b7bc1f574d | |||
| b25b3d59cf | |||
| c1bd2a6ef1 | |||
| 859f7bbeaa | |||
| d6cc6fc04f | |||
| 62cd7dcc89 | |||
| c67bf962c1 | |||
| efd8b32a5f | |||
| 01596e825e | |||
| fb50aeba47 | |||
| defee9aa15 | |||
| 67e5917a57 | |||
| 83e2bed432 | |||
| a9c8ec93b7 | |||
| 13b7d6d40a | |||
| 665e83d56a | |||
| 8268b90d82 | |||
| 7646ce6644 | |||
| 05499e4890 | |||
| 3b82648e45 | |||
| 937ba2e7cf | |||
| f63e4056f2 |
+1
-3
@@ -409,10 +409,8 @@ void Controller::removeUser(const std::string& userID)
|
|||||||
User* user = m_userManagementService.getUser(userID);
|
User* user = m_userManagementService.getUser(userID);
|
||||||
if (!user)
|
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);
|
m_userManagementService.removeUser(userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Place files here.
|
|
||||||
@@ -24,9 +24,10 @@ Parameters: None
|
|||||||
Returns: A new ServiceBooking object.
|
Returns: A new ServiceBooking object.
|
||||||
*/
|
*/
|
||||||
ServiceBooking::ServiceBooking()
|
ServiceBooking::ServiceBooking()
|
||||||
: m_id("SRV" + std::to_string(++m_uid)),
|
: m_id("SBK" + std::to_string(++m_uid)),
|
||||||
m_customer(nullptr),
|
m_customer(nullptr),
|
||||||
m_assignedTechnician(nullptr),
|
m_assignedTechnician(nullptr),
|
||||||
|
m_status(util::ServiceJobStatus::PENDING),
|
||||||
m_discountPercentage(0.0) {}
|
m_discountPercentage(0.0) {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -56,7 +57,7 @@ ServiceBooking::ServiceBooking(
|
|||||||
const std::string& vehicleModel,
|
const std::string& vehicleModel,
|
||||||
double discountPercentage
|
double discountPercentage
|
||||||
)
|
)
|
||||||
: m_id("SRV" + std::to_string(++m_uid)),
|
: m_id("SBK" + std::to_string(++m_uid)),
|
||||||
m_status(status),
|
m_status(status),
|
||||||
m_services(services),
|
m_services(services),
|
||||||
m_customerId(customerId),
|
m_customerId(customerId),
|
||||||
|
|||||||
+8
-7
@@ -294,7 +294,7 @@ void PaymentManagementService::generateInvoice(ServiceBooking* booking)
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Invoice generation failed: booking is null.");
|
throw std::runtime_error("Invoice generation failed: booking is null.");
|
||||||
}
|
}
|
||||||
double totalLabourCost = 0, totalPartsCost = 0, totalServiceCost = 0;
|
double totalLaborCost = 0, totalPartsCost = 0, totalServiceCost = 0;
|
||||||
double discountPercentage = booking->getDiscountPercentage();
|
double discountPercentage = booking->getDiscountPercentage();
|
||||||
std::string bookingID = booking->getId();
|
std::string bookingID = booking->getId();
|
||||||
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
|
util::Map<std::string, Service*> servicesInTheBookedService = booking->getServices();
|
||||||
@@ -303,9 +303,10 @@ void PaymentManagementService::generateInvoice(ServiceBooking* booking)
|
|||||||
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentJobCards.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
|
JobCard* currentJobCard = currentJobCards.getValueAt(iterator);
|
||||||
if (currentJobCard->getBookingId() == bookingID && currentJobCard->getStatus() != util::ServiceJobStatus::COMPLETED)
|
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 + "'.");
|
throw std::runtime_error("Invoice generation failed: Not all job cards are completed for booking '" + bookingID + "'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
|
for (int iterator = 0; iterator < servicesInTheBookedService.getSize(); iterator++)
|
||||||
@@ -314,13 +315,13 @@ void PaymentManagementService::generateInvoice(ServiceBooking* booking)
|
|||||||
if (currentService)
|
if (currentService)
|
||||||
{
|
{
|
||||||
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
|
createInventoryItemsMap(completeInventoryItemMapOfBooking, currentService);
|
||||||
totalLabourCost += currentService->getLaborCost();
|
totalLaborCost += currentService->getLaborCost();
|
||||||
totalPartsCost += util::calculatePartsCost(currentService);
|
totalPartsCost += util::calculatePartsCost(currentService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
totalServiceCost = totalLabourCost + totalPartsCost;
|
totalServiceCost = totalLaborCost + totalPartsCost;
|
||||||
totalServiceCost -= (totalServiceCost * (discountPercentage / 100));
|
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);
|
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();
|
util::Map<std::string, Invoice*>& currentInvoices = m_dataStore.getInvoices();
|
||||||
currentInvoices.insert(invoice->getId(), invoice);
|
currentInvoices.insert(invoice->getId(), invoice);
|
||||||
}
|
}
|
||||||
@@ -375,7 +376,7 @@ void PaymentManagementService::completePayment(const std::string& invoiceID, uti
|
|||||||
invoice->setStatus(util::PaymentStatus::COMPLETED);
|
invoice->setStatus(util::PaymentStatus::COMPLETED);
|
||||||
std::string title, message;
|
std::string title, message;
|
||||||
title = "Payment successful";
|
title = "Payment successful";
|
||||||
message = "Payment successful for invoice ID " + invoiceID;
|
message = "Payment successful for Invoice ID " + invoiceID;
|
||||||
sendNotification(currentUser, title, message);
|
sendNotification(currentUser, title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+183
-84
@@ -23,7 +23,6 @@ Date:19-May-2026
|
|||||||
#include "ServiceBooking.h"
|
#include "ServiceBooking.h"
|
||||||
#include "ServiceManagementService.h"
|
#include "ServiceManagementService.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "Timestamp.h"
|
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include "UserManagementService.h"
|
#include "UserManagementService.h"
|
||||||
#include "Utility.h"
|
#include "Utility.h"
|
||||||
@@ -100,7 +99,7 @@ void ServiceManagementService::purchaseComboPackage(const std::string& comboPack
|
|||||||
}
|
}
|
||||||
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
const ComboPackage* comboPackage = comboPackagesMap[comboPackageID];
|
||||||
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
util::Map<std::string, Service*> selectedServices = comboPackage->getServices();
|
||||||
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::STARTED, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
ServiceBooking* serviceBooking = Factory::getObject<ServiceBooking>(util::ServiceJobStatus::PENDING, selectedServices, authenticatedUser->getId(), authenticatedUser, vehicleNumber, vehicleBrand, vehicleModel, comboPackage->getDiscountPercentage());
|
||||||
if (serviceBooking == nullptr)
|
if (serviceBooking == nullptr)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create combo package service booking");
|
throw std::runtime_error("Failed to create combo package service booking");
|
||||||
@@ -508,6 +507,89 @@ void ServiceManagementService::saveObservers()
|
|||||||
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
util::saveObservers(config::file::SERVICEMANAGEMENTOBSERVERS, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: restoreInventory
|
||||||
|
Description: Restores inventory quantities for all required items in the services associated
|
||||||
|
with a given booking. Each item's quantity is incremented by a fixed value.
|
||||||
|
Parameter: ServiceBooking* booking - Pointer to the booking whose inventory items need to be restored
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
static void restoreInventory(ServiceBooking* booking)
|
||||||
|
{
|
||||||
|
const int INCREMENT_VALUE = 1;
|
||||||
|
if (!booking)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto& services = booking->getServices();
|
||||||
|
for (int serviceIterator = 0; serviceIterator < services.getSize(); ++serviceIterator)
|
||||||
|
{
|
||||||
|
Service* service = services.getValueAt(serviceIterator);
|
||||||
|
if (!service)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const auto& items = service->getRequiredInventoryItems();
|
||||||
|
for (int InventoryIterator = 0; InventoryIterator < items.getSize(); ++InventoryIterator)
|
||||||
|
{
|
||||||
|
InventoryItem* item = items.getValueAt(InventoryIterator);
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: processBookingCancellation
|
||||||
|
Description: Cancels jobs and updates the status of a given booking. Sends notifications to the
|
||||||
|
specified user, resets technician assignment if needed, and restores inventory items.
|
||||||
|
Parameter: ServiceBooking* booking - Pointer to the booking being cancelled
|
||||||
|
util::ServiceJobStatus newServiceBookingStatus - New status to assign to the booking
|
||||||
|
const std::string& notificationTitle - Title of the booking cancellation notification
|
||||||
|
const std::string& notificationMessage - Message body of the booking cancellation notification
|
||||||
|
User* notifyUser - User to notify about the cancellation
|
||||||
|
util::ServiceJobStatus jobCardStatus - New status to assign to associated job cards
|
||||||
|
const std::string& jobNotificationTitle - Title of the job cancellation notification
|
||||||
|
const std::string& jobNotificationMessage - Message body of the job cancellation notification
|
||||||
|
util::Map<std::string, JobCard*>& jobs - Collection of job cards to update
|
||||||
|
ServiceManagementService& currentService - Reference to the service for sending notifications
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
static void processBookingCancellation(ServiceBooking* booking,
|
||||||
|
util::ServiceJobStatus newServiceBookingStatus,
|
||||||
|
const std::string& notificationTitle,
|
||||||
|
const std::string& notificationMessage,
|
||||||
|
User* notifyUser,
|
||||||
|
util::ServiceJobStatus jobCardStatus,
|
||||||
|
const std::string& jobNotificationTitle,
|
||||||
|
const std::string& jobNotificationMessage,
|
||||||
|
util::Map<std::string, JobCard*>& jobs, ServiceManagementService& currentService)
|
||||||
|
{
|
||||||
|
if (!booking || !notifyUser)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator)
|
||||||
|
{
|
||||||
|
JobCard* jobCard = jobs.getValueAt(jobIterator);
|
||||||
|
if (jobCard && jobCard->getBookingId() == booking->getId())
|
||||||
|
{
|
||||||
|
jobCard->setStatus(jobCardStatus);
|
||||||
|
currentService.sendNotification(notifyUser, jobNotificationTitle, jobNotificationMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
booking->setStatus(newServiceBookingStatus);
|
||||||
|
currentService.sendNotification(notifyUser, notificationTitle, notificationMessage);
|
||||||
|
if (newServiceBookingStatus == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
booking->setAssignedTechnician(nullptr);
|
||||||
|
booking->setAssignedTechnicianId("");
|
||||||
|
}
|
||||||
|
restoreInventory(booking);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: cancelCustomerServiceBookings
|
Function: cancelCustomerServiceBookings
|
||||||
Description: Cancels all service bookings associated with a given customer or technician.
|
Description: Cancels all service bookings associated with a given customer or technician.
|
||||||
@@ -516,69 +598,47 @@ Description: Cancels all service bookings associated with a given customer or te
|
|||||||
Parameter: const std::string& userID - ID of the customer or technician
|
Parameter: const std::string& userID - ID of the customer or technician
|
||||||
Return type: void
|
Return type: void
|
||||||
*/
|
*/
|
||||||
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& userID)
|
void ServiceManagementService::cancelCustomerServiceBookings(const std::string& customerID)
|
||||||
{
|
{
|
||||||
const int INCREMENT_VALUE = 1;
|
|
||||||
auto& users = m_dataStore.getUsers();
|
auto& users = m_dataStore.getUsers();
|
||||||
int userIndex = users.find(userID);
|
int userIndex = users.find(customerID);
|
||||||
if (userIndex == -1)
|
if (userIndex == -1)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("User not found: " + userID);
|
throw std::runtime_error("User not found: " + customerID);
|
||||||
}
|
}
|
||||||
User* user = users.getValueAt(userIndex);
|
User* customer = users.getValueAt(userIndex);
|
||||||
if (user == nullptr)
|
if (!customer)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("User not found: " + userID);
|
throw std::runtime_error("User not found: " + customerID);
|
||||||
}
|
}
|
||||||
util::UserType type = user->getUserType();
|
auto& bookings = m_dataStore.getServiceBookings();
|
||||||
auto& bookings = DataStore::getInstance().getServiceBookings();
|
auto& jobs = m_dataStore.getJobCards();
|
||||||
for (int bookingIterator = 0; bookingIterator < bookings.getSize(); bookingIterator++)
|
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||||
{
|
{
|
||||||
ServiceBooking* booking = bookings.getValueAt(bookingIterator);
|
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||||
if (booking != nullptr &&
|
if (!booking)
|
||||||
(booking->getCustomerId() == userID || booking->getAssignedTechnicianId() == userID))
|
|
||||||
{
|
{
|
||||||
if (booking->getStatus() == util::ServiceJobStatus::PENDING ||
|
continue;
|
||||||
booking->getStatus() == util::ServiceJobStatus::STARTED)
|
|
||||||
{
|
|
||||||
if (type == util::UserType::CUSTOMER)
|
|
||||||
{
|
|
||||||
booking->setStatus(util::ServiceJobStatus::CANCELLED);
|
|
||||||
booking->setCustomer(nullptr);
|
|
||||||
booking->setCustomerId("");
|
|
||||||
User* assignedTechnician = booking->getAssignedTechnician();
|
|
||||||
std::string title = "Customer Service Cancelled";
|
|
||||||
std::string message = "The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.";
|
|
||||||
sendNotification(assignedTechnician, title, message);
|
|
||||||
}
|
|
||||||
else if (type == util::UserType::TECHNICIAN)
|
|
||||||
{
|
|
||||||
booking->setStatus(util::ServiceJobStatus::PENDING);
|
|
||||||
std::string title = "Technician Unavailable";
|
|
||||||
std::string message = "Your assigned technician is no longer available. Your booking has been reset to pending, and we will reassign a new technician shortly.";
|
|
||||||
sendNotification(booking->getCustomer(), title, message);
|
|
||||||
}
|
|
||||||
booking->setAssignedTechnician(nullptr);
|
|
||||||
booking->setAssignedTechnicianId("");
|
|
||||||
const auto& ListOfServices = booking->getServices();
|
|
||||||
for (int serviceIterator = 0; serviceIterator < ListOfServices.getSize(); serviceIterator++)
|
|
||||||
{
|
|
||||||
Service* service = ListOfServices.getValueAt(serviceIterator);
|
|
||||||
if (service != nullptr)
|
|
||||||
{
|
|
||||||
const auto& items = service->getRequiredInventoryItems();
|
|
||||||
for (int itemIterator = 0; itemIterator < items.getSize(); itemIterator++)
|
|
||||||
{
|
|
||||||
InventoryItem* item = items.getValueAt(itemIterator);
|
|
||||||
if (item != nullptr)
|
|
||||||
{
|
|
||||||
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (booking->getCustomerId() != customerID)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
User* assignedTechnician = booking->getAssignedTechnician();
|
||||||
|
std::string titleToTechnician = "Customer Service Cancelled";
|
||||||
|
std::string messageToTechnician = "The customer has cancelled their service booking. Your assigned job card has been cancelled and the inventory has been restocked.";
|
||||||
|
std::string jobTitle = "Job Cancelled";
|
||||||
|
std::string jobMessage = "The job has been cancelled. Your job card has been cancelled and the inventory has been restocked.";
|
||||||
|
processBookingCancellation(booking,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
titleToTechnician, messageToTechnician, assignedTechnician,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
jobTitle, jobMessage, jobs, *this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -591,34 +651,48 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
|
void ServiceManagementService::cancelTechnicianJobs(const std::string& technicianID)
|
||||||
{
|
{
|
||||||
const int INCREMENT_VALUE = 1;
|
auto& users = m_dataStore.getUsers();
|
||||||
auto& jobs = m_dataStore.getJobCards();
|
int userIndex = users.find(technicianID);
|
||||||
for (int jobIterator = 0; jobIterator < jobs.getSize(); jobIterator++)
|
if (userIndex == -1)
|
||||||
{
|
{
|
||||||
JobCard* job = jobs.getValueAt(jobIterator);
|
throw std::runtime_error("User not found: " + technicianID);
|
||||||
if (job != nullptr && job->getTechnicianId() == technicianID)
|
}
|
||||||
|
User* technician = users.getValueAt(userIndex);
|
||||||
|
if (!technician)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("User not found: " + technicianID);
|
||||||
|
}
|
||||||
|
auto& bookings = m_dataStore.getServiceBookings();
|
||||||
|
auto& jobs = m_dataStore.getJobCards();
|
||||||
|
for (int iteratorOne = 0; iteratorOne < bookings.getSize(); iteratorOne++)
|
||||||
|
{
|
||||||
|
ServiceBooking* booking = bookings.getValueAt(iteratorOne);
|
||||||
|
if (!booking)
|
||||||
{
|
{
|
||||||
if (job->getStatus() == util::ServiceJobStatus::PENDING || job->getStatus() == util::ServiceJobStatus::STARTED)
|
continue;
|
||||||
{
|
|
||||||
job->setStatus(util::ServiceJobStatus::CANCELLED);
|
|
||||||
std::string title = "Job Cancelled";
|
|
||||||
std::string message = "The Job has cancelled. Your job card has been cancelled and the inventory has been restocked.";
|
|
||||||
sendNotification(job->getTechnician(), title, message);
|
|
||||||
Service* service = job->getService();
|
|
||||||
if (service != nullptr)
|
|
||||||
{
|
|
||||||
const auto& items = service->getRequiredInventoryItems();
|
|
||||||
for (int itemIterator = 0; itemIterator < items.getSize(); itemIterator++)
|
|
||||||
{
|
|
||||||
InventoryItem* item = items.getValueAt(itemIterator);
|
|
||||||
if (item != nullptr)
|
|
||||||
{
|
|
||||||
item->setQuantity(item->getQuantity() + INCREMENT_VALUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
std::string technicianId = booking->getAssignedTechnicianId();
|
||||||
|
if (technicianId != technicianID)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
User* customer = booking->getCustomer();
|
||||||
|
if (!customer)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string title = "Technician Unavailable";
|
||||||
|
std::string message = "Your assigned technician is no longer available. Your booking has been reset to pending and we will reassign a new technician shortly.";
|
||||||
|
processBookingCancellation(booking,
|
||||||
|
util::ServiceJobStatus::PENDING,
|
||||||
|
title, message, customer,
|
||||||
|
util::ServiceJobStatus::CANCELLED,
|
||||||
|
title, message, jobs, *this
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -817,6 +891,10 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
|||||||
}
|
}
|
||||||
currentBooking->setAssignedTechnician(selectedTechnician);
|
currentBooking->setAssignedTechnician(selectedTechnician);
|
||||||
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
|
currentBooking->setAssignedTechnicianId(selectedTechnician->getId());
|
||||||
|
if (currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
currentBooking->setStatus(util::ServiceJobStatus::STARTED);
|
||||||
|
}
|
||||||
std::string title = "Job card created";
|
std::string title = "Job card created";
|
||||||
std::string message = "Job card created for the service and you are assigned for that.";
|
std::string message = "Job card created for the service and you are assigned for that.";
|
||||||
JobCard* jobCard = Factory::getObject<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
|
JobCard* jobCard = Factory::getObject<JobCard>(bookingID, currentBooking, currentService, serviceID, technicianID, selectedTechnician, util::Timestamp(), util::ServiceJobStatus::STARTED, util::Timestamp());
|
||||||
@@ -829,6 +907,9 @@ void ServiceManagementService::createJobCard(const std::string& bookingID, const
|
|||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to create job card.");
|
throw std::runtime_error("Failed to create job card.");
|
||||||
}
|
}
|
||||||
|
title = "Technician assigned";
|
||||||
|
message = "A technician has been assigned to your Service Booking with ID " + bookingID;
|
||||||
|
sendNotification(currentBooking->getCustomer(), title, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -906,9 +987,27 @@ Throws:
|
|||||||
void ServiceManagementService::removeService(const std::string& serviceID)
|
void ServiceManagementService::removeService(const std::string& serviceID)
|
||||||
{
|
{
|
||||||
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
util::Map<std::string, Service*>& currentServices = m_dataStore.getServices();
|
||||||
|
util::Map<std::string, ComboPackage*>& currentComboPackages = m_dataStore.getComboPackages();
|
||||||
if (currentServices.find(serviceID) != -1)
|
if (currentServices.find(serviceID) != -1)
|
||||||
{
|
{
|
||||||
currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE);
|
currentServices.getValueAt(currentServices.find(serviceID))->setState(util::State::INACTIVE);
|
||||||
|
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
ComboPackage* currentComboPackage = currentComboPackages.getValueAt(iterator);
|
||||||
|
if (currentComboPackage && currentComboPackage->getState() == util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
util::Map<std::string, Service*> currentServices = currentComboPackage->getServices();
|
||||||
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
auto currentService = currentServices.getValueAt(iterator);
|
||||||
|
if (currentService->getId() == serviceID)
|
||||||
|
{
|
||||||
|
currentComboPackage->setState(util::State::INACTIVE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1033,11 +1132,11 @@ void ServiceManagementService::completeJob(const std::string& jobID)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to complete the job, some error occured or job already completed.");
|
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
||||||
}
|
}
|
||||||
if (!jobStatusUpdated)
|
if (!jobStatusUpdated)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to complete the job, some error occured or job already completed.");
|
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
||||||
@@ -1045,8 +1144,8 @@ void ServiceManagementService::completeJob(const std::string& jobID)
|
|||||||
{
|
{
|
||||||
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||||
paymentManagementService.generateInvoice(currentJob->getBooking());
|
paymentManagementService.generateInvoice(currentJob->getBooking());
|
||||||
std::string title = "Service Booking completed,Invoice Generated.\n";
|
std::string title = "Service Booking completed. Invoice Generated.";
|
||||||
std::string message = "Services completed for the booking and invoice generated.\n";
|
std::string message = "Services completed for the booking and invoice generated.";
|
||||||
sendNotification(currentJob->getBooking()->getCustomer(), title, message);
|
sendNotification(currentJob->getBooking()->getCustomer(), title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+15
-1
@@ -297,13 +297,27 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void UserManagementService::removeUser(const std::string& userID)
|
void UserManagementService::removeUser(const std::string& userID)
|
||||||
{
|
{
|
||||||
|
InventoryManagementService inventoryManagementService;
|
||||||
|
PaymentManagementService paymentManagementService;
|
||||||
|
ServiceManagementService serviceManagementService;
|
||||||
int index = m_dataStore.getUsers().find(userID);
|
int index = m_dataStore.getUsers().find(userID);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
{
|
{
|
||||||
User* user = m_dataStore.getUsers().getValueAt(index);
|
User* user = m_dataStore.getUsers().getValueAt(index);
|
||||||
if (user != nullptr)
|
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);
|
user->setState(util::State::INACTIVE);
|
||||||
|
inventoryManagementService.detach(user);
|
||||||
|
paymentManagementService.detach(user);
|
||||||
|
serviceManagementService.detach(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,7 +329,7 @@ util::Map<std::string, User*> UserManagementService::getUsers(util::UserType typ
|
|||||||
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentUsers.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
User* currentUser = currentUsers.getValueAt(iterator);
|
User* currentUser = currentUsers.getValueAt(iterator);
|
||||||
if (currentUser->getUserType() == type)
|
if (currentUser && currentUser->getState() == util::State::ACTIVE && currentUser->getUserType() == type)
|
||||||
{
|
{
|
||||||
filteredUsersMap.insert(currentUser->getId(), currentUser);
|
filteredUsersMap.insert(currentUser->getId(), currentUser);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ namespace util
|
|||||||
{
|
{
|
||||||
return PaymentMode::OFFLINE;
|
return PaymentMode::OFFLINE;
|
||||||
}
|
}
|
||||||
|
if (value == "NOTSET")
|
||||||
|
{
|
||||||
|
return PaymentMode::NOTSET;
|
||||||
|
}
|
||||||
throw std::invalid_argument("Invalid PaymentMode string");
|
throw std::invalid_argument("Invalid PaymentMode string");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,39 @@ Date: 22-May-2026
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <direct.h>
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
namespace util
|
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
|
Function: loadRecords
|
||||||
Description: Loads records from a given file path into a vector of strings.
|
Description: Loads records from a given file path into a vector of strings.
|
||||||
@@ -32,6 +61,7 @@ namespace util
|
|||||||
std::ifstream file(filePath);
|
std::ifstream file(filePath);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
|
ensureDirectoryExists(filePath);
|
||||||
std::ofstream newFile(filePath);
|
std::ofstream newFile(filePath);
|
||||||
newFile.close();
|
newFile.close();
|
||||||
file.open(filePath);
|
file.open(filePath);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Date: 22-May-2026
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
|
#include "FileHelper.h"
|
||||||
|
|
||||||
namespace util
|
namespace util
|
||||||
{
|
{
|
||||||
@@ -51,6 +52,7 @@ namespace util
|
|||||||
std::ifstream file(m_filePath);
|
std::ifstream file(m_filePath);
|
||||||
if (!file.is_open())
|
if (!file.is_open())
|
||||||
{
|
{
|
||||||
|
ensureDirectoryExists(m_filePath);
|
||||||
std::ofstream newFile(m_filePath);
|
std::ofstream newFile(m_filePath);
|
||||||
newFile.close();
|
newFile.close();
|
||||||
file.open(m_filePath);
|
file.open(m_filePath);
|
||||||
|
|||||||
@@ -21,4 +21,28 @@ namespace util
|
|||||||
{
|
{
|
||||||
std::cout << "\x1B[2J\x1B[H" << std::flush;
|
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) + "...";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -218,13 +218,15 @@ void AdminMenu::addInventoryItem()
|
|||||||
int choice, quantity;
|
int choice, quantity;
|
||||||
double price;
|
double price;
|
||||||
std::string partName;
|
std::string partName;
|
||||||
std::cout << "1. Add new item \n2. Add Quantity\nEnter your choice : ";
|
std::cout << "Add Inventory Item\n";
|
||||||
|
std::cout << "1. Add new item \n2. Restock Item\n\nEnter your choice : ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
std::cout << "--------Enter Item Details----------\n";
|
util::clear();
|
||||||
|
std::cout << "Enter Item Details\n";
|
||||||
std::cout << "Part Name : ";
|
std::cout << "Part Name : ";
|
||||||
util::read(partName);
|
util::read(partName);
|
||||||
std::cout << "Quantity : ";
|
std::cout << "Quantity : ";
|
||||||
@@ -232,15 +234,21 @@ void AdminMenu::addInventoryItem()
|
|||||||
std::cout << "Price : ";
|
std::cout << "Price : ";
|
||||||
util::read(price);
|
util::read(price);
|
||||||
m_controller.addInventoryItem(partName, quantity, price);
|
m_controller.addInventoryItem(partName, quantity, price);
|
||||||
std::cout << "New Item " << partName << " added to the Inventory.\n";
|
std::cout << "\nNew Item " << partName << " added to the Inventory.\n\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Select Item to Restock\n";
|
||||||
auto inventoryItems = m_controller.getInventoryItems();
|
auto inventoryItems = m_controller.getInventoryItems();
|
||||||
addQuantityToItem(inventoryItems, m_controller);
|
addQuantityToItem(inventoryItems, m_controller);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
std::cout << "\nEnter a valid choice.\n\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
@@ -255,6 +263,7 @@ Return type: void
|
|||||||
void AdminMenu::removeInventoryItem()
|
void AdminMenu::removeInventoryItem()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Remove Inventory Item\n";
|
||||||
auto inventoryItems = m_controller.getInventoryItems();
|
auto inventoryItems = m_controller.getInventoryItems();
|
||||||
auto activeItems = filterActiveItems(inventoryItems);
|
auto activeItems = filterActiveItems(inventoryItems);
|
||||||
int activeItemsSize = activeItems.getSize();
|
int activeItemsSize = activeItems.getSize();
|
||||||
@@ -333,14 +342,16 @@ Returns:
|
|||||||
void AdminMenu::assignJob()
|
void AdminMenu::assignJob()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Assign Job to Technician\n";
|
||||||
std::string selectedService;
|
std::string selectedService;
|
||||||
bool hasPendingService = false;
|
bool hasPendingService = false;
|
||||||
auto currentBookings = m_controller.getServiceBookings();
|
auto currentBookings = m_controller.getServiceBookings();
|
||||||
|
auto pendingServiceBookings = filterActiveServiceBookings(currentBookings);
|
||||||
auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN);
|
auto availableTechnicians = m_controller.getUsers(util::UserType::TECHNICIAN);
|
||||||
int bookingsSize = currentBookings.getSize();
|
int bookingsSize = pendingServiceBookings.getSize();
|
||||||
util::Map<int, const ServiceBooking*> serviceBookingsMap;
|
util::Map<int, const ServiceBooking*> serviceBookingsMap;
|
||||||
util::Map<int, const User*> currentAvailableTechniciansMap;
|
util::Map<int, const User*> currentAvailableTechniciansMap;
|
||||||
if (listServiceBookings(currentBookings, bookingsSize, serviceBookingsMap))
|
if (listServiceBookings(pendingServiceBookings, bookingsSize, serviceBookingsMap))
|
||||||
{
|
{
|
||||||
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
const ServiceBooking* selectedService = selectPendingServiceBookings(serviceBookingsMap);
|
||||||
if (selectedService)
|
if (selectedService)
|
||||||
@@ -356,14 +367,19 @@ void AdminMenu::assignJob()
|
|||||||
{
|
{
|
||||||
m_controller.createJobCard(selectedService->getId(), selectedTechnician->getId(), servicesInBooking.getValueAt(iterator)->getId());
|
m_controller.createJobCard(selectedService->getId(), selectedTechnician->getId(), servicesInBooking.getValueAt(iterator)->getId());
|
||||||
}
|
}
|
||||||
|
std::cout << "Job card created for each service and technician successfully assigned.\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "No technicians are currently available.";
|
std::cout << "No technicians are currently available.\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "No pending service bookings available.\n\n";
|
||||||
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,17 +394,24 @@ Returns:
|
|||||||
void AdminMenu::createService()
|
void AdminMenu::createService()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Create Service\n";
|
||||||
std::string serviceName;
|
std::string serviceName;
|
||||||
double labourCost;
|
double labourCost;
|
||||||
std::cout << "Enter the service name: ";
|
std::cout << "Enter the service name: ";
|
||||||
util::read(serviceName);
|
util::read(serviceName);
|
||||||
util::Map<std::string, const InventoryItem*> currentInventoryItems = m_controller.getInventoryItems();
|
util::Map<std::string, const InventoryItem*> currentInventoryItems = m_controller.getInventoryItems();
|
||||||
|
util::Map<std::string, const InventoryItem*> activeInventoryItems = filterActiveItems(currentInventoryItems);
|
||||||
util::Vector<std::string> selectedInventoryItems;
|
util::Vector<std::string> selectedInventoryItems;
|
||||||
selectInventoryItems(currentInventoryItems,selectedInventoryItems);
|
selectInventoryItems(activeInventoryItems,selectedInventoryItems);
|
||||||
std::cout << "Enter the labour cost: ";
|
if (selectedInventoryItems.isEmpty())
|
||||||
|
{
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "\nEnter the labour cost: ";
|
||||||
util::read(labourCost);
|
util::read(labourCost);
|
||||||
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
||||||
std::cout << "Service created sucessfully.\n";
|
std::cout << "\nService created sucessfully.\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,17 +426,19 @@ Returns:
|
|||||||
void AdminMenu::removeService()
|
void AdminMenu::removeService()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Remove Service\n";
|
||||||
std::string selectedServiceID;
|
std::string selectedServiceID;
|
||||||
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
||||||
selectedServiceID = selectServicesToRemove(currentServices);
|
util::Map<std::string, const Service*> currentActiveServices = filterActiveServices(currentServices);
|
||||||
|
selectedServiceID = selectServicesToRemove(currentActiveServices);
|
||||||
if (selectedServiceID != "")
|
if (selectedServiceID != "")
|
||||||
{
|
{
|
||||||
m_controller.removeService(selectedServiceID);
|
m_controller.removeService(selectedServiceID);
|
||||||
std::cout << "Service removed sucessfully.";
|
std::cout << "Service removed successfully.\n\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to remove service.";
|
std::cout << "Failed to remove service.\n\n";
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
@@ -428,36 +453,37 @@ void AdminMenu::addTechnician()
|
|||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
std::string username, name, password, email, phoneNumber;
|
std::string username, name, password, email, phoneNumber;
|
||||||
std::cout << std::left << std::setw(25) << "Enter Technician Username: ";
|
std::cout << "Add Technician\n";
|
||||||
|
std::cout << "Enter Technician Username: ";
|
||||||
util::read(username);
|
util::read(username);
|
||||||
std::cout << std::left << std::setw(25) << "Enter Technician Name: ";
|
std::cout << "Enter Technician Name: ";
|
||||||
util::read(name);
|
util::read(name);
|
||||||
std::cout << std::setw(25) << "Enter Technician Password: ";
|
std::cout << "Enter Technician Password: ";
|
||||||
util::read(password);
|
util::read(password);
|
||||||
if(!util::isPasswordValid(password))
|
if(!util::isPasswordValid(password))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Password is invalid!";
|
std::cout << "\nError: Password is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << std::setw(25) << "Enter Technician Email: ";
|
std::cout << "Enter Technician Email: ";
|
||||||
util::read(email);
|
util::read(email);
|
||||||
if(!util::isEmailValid(email))
|
if(!util::isEmailValid(email))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Email is invalid!";
|
std::cout << "\nError: Email is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << std::setw(25) << "Enter Technician Phone: ";
|
std::cout << "Enter Technician Phone: ";
|
||||||
util::read(phoneNumber);
|
util::read(phoneNumber);
|
||||||
if(!util::isPhoneNumberValid(phoneNumber))
|
if(!util::isPhoneNumberValid(phoneNumber))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Phone Number is invalid!";
|
std::cout << "\nError: Phone Number is invalid!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_controller.createTechnician(username, name, password, email, phoneNumber);
|
m_controller.createTechnician(username, name, password, email, phoneNumber);
|
||||||
std::cout << "\nTechnician Added Successfully.\n";
|
std::cout << "\nTechnician Added Successfully.\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +535,10 @@ Return type: void
|
|||||||
void AdminMenu::createComboPackages()
|
void AdminMenu::createComboPackages()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Create Combo Packages\n";
|
||||||
auto serviceList = m_controller.getServices();
|
auto serviceList = m_controller.getServices();
|
||||||
|
auto activeServices = filterActiveServices(serviceList);
|
||||||
|
int currentActiveServicesCount = activeServices.getSize();
|
||||||
const int NUMBER_OF_SERVICE_PER_PACKAGE = 2;
|
const int NUMBER_OF_SERVICE_PER_PACKAGE = 2;
|
||||||
util::Vector<std::string> selectedServiceID;
|
util::Vector<std::string> selectedServiceID;
|
||||||
for (int iterator = 0; iterator < NUMBER_OF_SERVICE_PER_PACKAGE; iterator++)
|
for (int iterator = 0; iterator < NUMBER_OF_SERVICE_PER_PACKAGE; iterator++)
|
||||||
@@ -517,10 +546,10 @@ void AdminMenu::createComboPackages()
|
|||||||
const Service* chosenService = nullptr;
|
const Service* chosenService = nullptr;
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
chosenService = selectServiceFromServices(serviceList);
|
chosenService = selectServiceFromServices(activeServices);
|
||||||
if (chosenService == nullptr)
|
if (!chosenService)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create combo package!";
|
std::cout << "Failed to create combo package!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -535,13 +564,21 @@ void AdminMenu::createComboPackages()
|
|||||||
}
|
}
|
||||||
if (alreadyChosen)
|
if (alreadyChosen)
|
||||||
{
|
{
|
||||||
|
if (currentActiveServicesCount < 2)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
std::cout << "Service already selected. Please choose a different one." << std::endl;
|
std::cout << "Service already selected. Please choose a different one." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
selectedServiceID.push_back(chosenService->getId());
|
selectedServiceID.push_back(chosenService->getId());
|
||||||
util::clear();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (currentActiveServicesCount < 2)
|
||||||
|
{
|
||||||
|
std::cout << "All the available services selected\n\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
std::string packageName;
|
std::string packageName;
|
||||||
double discountPercentage;
|
double discountPercentage;
|
||||||
@@ -569,16 +606,17 @@ Return type: void
|
|||||||
void AdminMenu::removeComboPackage()
|
void AdminMenu::removeComboPackage()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Remove Combo Package\n";
|
||||||
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
||||||
std::string selectedComboPackageID = selectComboPackage(currentComboPackages);
|
std::string selectedComboPackageID = selectComboPackage(currentComboPackages);
|
||||||
if (selectedComboPackageID != "")
|
if (!selectedComboPackageID.empty())
|
||||||
{
|
{
|
||||||
m_controller.removeComboPackage(selectedComboPackageID);
|
m_controller.removeComboPackage(selectedComboPackageID);
|
||||||
std::cout << "Combo Package removed successfully.\n";
|
std::cout << "Combo Package removed successfully.\n\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Combo package removal failed.\n";
|
std::cout << "Combo package removal failed.\n\n";
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,20 +220,24 @@ void CustomerMenu::selectComboPackage()
|
|||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Select a Combo Package\n";
|
std::cout << "Select a Combo Package\n";
|
||||||
auto comboPackages = m_controller.getComboPackages();
|
auto comboPackages = m_controller.getComboPackages();
|
||||||
if (comboPackages.isEmpty())
|
util::Map<std::string, const ComboPackage*> activeComboPackages = filterComboPackages(comboPackages);
|
||||||
|
if (activeComboPackages.isEmpty())
|
||||||
{
|
{
|
||||||
std::cout << "No combo packages available!";
|
std::cout << "No combo packages available!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(comboPackages);
|
const ComboPackage* selectedComboPackage = selectComboPackageFromPackages(activeComboPackages);
|
||||||
if (selectedComboPackage == nullptr)
|
if (selectedComboPackage == nullptr)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to book combo package!";
|
std::cout << "Failed to book combo package!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
std::cout << "Combo Package selected\n";
|
||||||
|
util::pressEnter();
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "Enter the vehicle details\n";
|
||||||
std::cout << "Enter vehicle number: ";
|
std::cout << "Enter vehicle number: ";
|
||||||
util::read(vehicleNumber);
|
util::read(vehicleNumber);
|
||||||
std::cout << "Enter vehicle brand: ";
|
std::cout << "Enter vehicle brand: ";
|
||||||
@@ -241,7 +245,7 @@ void CustomerMenu::selectComboPackage()
|
|||||||
std::cout << "Enter vehicle model: ";
|
std::cout << "Enter vehicle model: ";
|
||||||
util::read(vehicleModel);
|
util::read(vehicleModel);
|
||||||
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
|
m_controller.purchaseComboPackage(selectedComboPackage->getId(), vehicleNumber, vehicleBrand, vehicleModel);
|
||||||
std::cout << "Combo Package has been booked successfully";
|
std::cout << "Combo Package has been booked successfully\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,6 +362,7 @@ Returns:
|
|||||||
void CustomerMenu::viewInvoices()
|
void CustomerMenu::viewInvoices()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
|
std::cout << "View Invoices\n";
|
||||||
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
util::Map<std::string, const Invoice*> currentUserInvoices = m_controller.getInvoicesByUser();
|
||||||
displayInvoices(currentUserInvoices);
|
displayInvoices(currentUserInvoices);
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
@@ -393,4 +398,4 @@ void CustomerMenu::configureNotifications()
|
|||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Notification preferences updated successfully.\n";
|
std::cout << "Notification preferences updated successfully.\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
@@ -39,35 +39,33 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline std::string selectServicesToRemove(util::Map<std::string, const Service*> currentServices)
|
inline std::string selectServicesToRemove(util::Map<std::string, const Service*> currentServices)
|
||||||
{
|
{
|
||||||
|
if (currentServices.getSize() == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No Services Currently Available.\n";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
util::Map<int, const Service*> currentServicesMap;
|
util::Map<int, const Service*> currentServicesMap;
|
||||||
bool hasServices = false;
|
|
||||||
int currentIndex = 1, choice;
|
int currentIndex = 1, choice;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(6) << "Index"
|
||||||
<< std::setw(12) << "Service ID"
|
<< std::setw(12) << "Service ID"
|
||||||
<< std::setw(20) << "Name"
|
<< std::setw(35) << "Name"
|
||||||
<< std::setw(10) << "Labor Cost"
|
<< std::setw(10) << "Labor Cost"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
const Service* currentService = currentServices.getValueAt(iterator);
|
const Service* currentService = currentServices.getValueAt(iterator);
|
||||||
if (currentService->getState() == util::State::INACTIVE)
|
if (currentService == nullptr || currentService->getState() == util::State::INACTIVE)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << currentIndex
|
<< std::setw(6) << currentIndex
|
||||||
<< std::setw(12) << currentService->getId()
|
<< std::setw(12) << currentService->getId()
|
||||||
<< std::setw(20) << currentService->getName()
|
<< std::setw(35) << util::truncateString(currentService->getName(), 30)
|
||||||
<< std::setw(10) << currentService->getLaborCost()
|
<< std::setw(10) << currentService->getLaborCost()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
hasServices = true;
|
|
||||||
currentServicesMap.insert(currentIndex++, currentService);
|
currentServicesMap.insert(currentIndex++, currentService);
|
||||||
}
|
|
||||||
if (!hasServices)
|
|
||||||
{
|
|
||||||
std::cout << "No services currently available." << std::endl;
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
std::cout << "Enter your choice: ";
|
std::cout << "Enter your choice: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
@@ -93,69 +91,104 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& currentInventoryItems, util::Vector<std::string>& selectedInventoryItems)
|
inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& currentInventoryItems, util::Vector<std::string>& selectedInventoryItems)
|
||||||
{
|
{
|
||||||
bool doRun = true, hasInventoryItems = false;
|
bool doRun = true;
|
||||||
util::Map<int, const InventoryItem*> currentInventoryMap;
|
util::Map<int, const InventoryItem*> currentInventoryMap;
|
||||||
int currentIndex = 1;
|
int choice;
|
||||||
int choice;
|
if (currentInventoryItems.isEmpty())
|
||||||
if (currentInventoryItems.getSize() == 0)
|
|
||||||
{
|
|
||||||
std::cout << "Inventory empty.";
|
|
||||||
}
|
|
||||||
while (doRun)
|
|
||||||
{
|
|
||||||
bool hasInventoryItems = false;
|
|
||||||
int currentIndex = 1;
|
|
||||||
currentInventoryMap.clear();
|
|
||||||
std::cout << std::left
|
|
||||||
<< std::setw(6) << "Index"
|
|
||||||
<< std::setw(12) << "Item ID"
|
|
||||||
<< std::setw(20) << "Part Name"
|
|
||||||
<< std::setw(10) << "Price"
|
|
||||||
<< std::setw(10) << "Quantity"
|
|
||||||
<< std::endl;
|
|
||||||
for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++)
|
|
||||||
{
|
{
|
||||||
const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator);
|
std::cout << "No Items Present, Inventory empty.\n";
|
||||||
if (currentInventoryItem->getState() == util::State::INACTIVE)
|
return;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
std::cout << std::left
|
|
||||||
<< std::setw(6) << currentIndex
|
|
||||||
<< std::setw(12) << currentInventoryItem->getId()
|
|
||||||
<< std::setw(20) << currentInventoryItem->getPartName()
|
|
||||||
<< std::setw(10) << currentInventoryItem->getPrice()
|
|
||||||
<< std::setw(10) << currentInventoryItem->getQuantity()
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
hasInventoryItems = true;
|
|
||||||
currentInventoryMap.insert(currentIndex++, currentInventoryItem);
|
|
||||||
}
|
|
||||||
if (!hasInventoryItems)
|
|
||||||
{
|
|
||||||
std::cout << "No items present in the inventory." << std::endl;
|
|
||||||
doRun = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
std::cout << "Select the item (Index) or enter -1 to exit: ";
|
while (doRun)
|
||||||
util::read(choice);
|
{
|
||||||
|
util::clear();
|
||||||
if (choice == -1)
|
std::cout << "Create Service\n";
|
||||||
{
|
std::cout << "\nSelect Required Items\n";
|
||||||
doRun = false;
|
bool hasInventoryItems = false;
|
||||||
|
int currentIndex = 1;
|
||||||
|
currentInventoryMap.clear();
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(6) << "Index"
|
||||||
|
<< std::setw(12) << "Item ID"
|
||||||
|
<< std::setw(20) << "Part Name"
|
||||||
|
<< std::setw(10) << "Price"
|
||||||
|
<< std::setw(10) << "Quantity"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < currentInventoryItems.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const InventoryItem* currentInventoryItem = currentInventoryItems.getValueAt(iterator);
|
||||||
|
if (currentInventoryItem == nullptr || currentInventoryItem->getState() == util::State::INACTIVE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
bool alreadySelected = false;
|
||||||
|
for (int iteratorOne = 0; iteratorOne < selectedInventoryItems.getSize(); iteratorOne++)
|
||||||
|
{
|
||||||
|
if (selectedInventoryItems[iteratorOne] == currentInventoryItem->getId())
|
||||||
|
{
|
||||||
|
alreadySelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (alreadySelected)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(6) << currentIndex
|
||||||
|
<< std::setw(12) << currentInventoryItem->getId()
|
||||||
|
<< std::setw(20) << currentInventoryItem->getPartName()
|
||||||
|
<< std::setw(10) << currentInventoryItem->getPrice()
|
||||||
|
<< std::setw(10) << currentInventoryItem->getQuantity()
|
||||||
|
<< std::endl;
|
||||||
|
currentInventoryMap.insert(currentIndex++, currentInventoryItem);
|
||||||
|
hasInventoryItems = true;
|
||||||
}
|
}
|
||||||
else if (currentInventoryMap.find(choice) != -1)
|
if (!hasInventoryItems)
|
||||||
{
|
{
|
||||||
selectedInventoryItems.push_back(currentInventoryMap.getValueAt(choice)->getId());
|
break;
|
||||||
std::cout << "Item added successfully." << std::endl;
|
}
|
||||||
|
std::cout << "Select the item (Index) or enter 0 to exit: ";
|
||||||
|
util::read(choice);
|
||||||
|
if (choice == 0)
|
||||||
|
{
|
||||||
|
doRun = false;
|
||||||
|
}
|
||||||
|
else if (currentInventoryMap.find(choice) != -1)
|
||||||
|
{
|
||||||
|
selectedInventoryItems.push_back(currentInventoryMap.getValueAt(currentInventoryMap.find(choice))->getId());
|
||||||
|
std::cout << "Item added successfully.\n" << std::endl;
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Enter a valid integer." << std::endl;
|
std::cout << "Enter a valid integer.\n" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: filterActiveServiceBookings
|
||||||
|
Description: Filters the given service bookings and returns only bookings with PENDING status.
|
||||||
|
Parameters:
|
||||||
|
- currentBookings: util::Map<std::string, const ServiceBooking*>, collection of current service bookings
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const ServiceBooking*>: map containing only active (PENDING) service bookings
|
||||||
|
*/
|
||||||
|
inline util::Map<std::string, const ServiceBooking*> filterActiveServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings)
|
||||||
|
{
|
||||||
|
util::Map<std::string, const ServiceBooking*> activeServiceBookings;
|
||||||
|
for (int iterator = 0; iterator < currentBookings.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const ServiceBooking* currentServiceBooking = currentBookings.getValueAt(iterator);
|
||||||
|
if (currentServiceBooking && currentServiceBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
|
{
|
||||||
|
activeServiceBookings.insert(currentServiceBooking->getId(), currentServiceBooking);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeServiceBookings;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: listServiceBookings
|
Function: listServiceBookings
|
||||||
Description: Lists all pending service bookings and maps them to indices for selection.
|
Description: Lists all pending service bookings and maps them to indices for selection.
|
||||||
@@ -168,48 +201,42 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings, int& bookingsSize, util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
inline bool listServiceBookings(util::Map<std::string, const ServiceBooking*>& currentBookings, int& bookingsSize, util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
||||||
{
|
{
|
||||||
|
if (currentBookings.getSize() == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
bool hasPendingService = false;
|
std::cout << "\nSelect Service Booking" << std::endl;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(10) << "Index"
|
<< std::setw(10) << "Index"
|
||||||
<< std::setw(10) << "ID"
|
<< std::setw(10) << "ID"
|
||||||
<< std::setw(12) << "Status"
|
<< std::setw(12) << "Status"
|
||||||
<< std::setw(12) << "CustID"
|
<< std::setw(12) << "CustID"
|
||||||
<< std::setw(20) << "Customer"
|
<< std::setw(20) << "Customer"
|
||||||
<< std::setw(15) << "VehicleNo"
|
<< std::setw(15) << "VehicleNo"
|
||||||
<< std::setw(15) << "Brand"
|
<< std::setw(15) << "Brand"
|
||||||
<< std::setw(15) << "Model"
|
<< std::setw(15) << "Model"
|
||||||
<< std::setw(20) << "Technician"
|
|
||||||
<< std::setw(15) << "TechnicianID"
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < bookingsSize; iterator++)
|
for (int iterator = 0; iterator < bookingsSize; iterator++)
|
||||||
{
|
{
|
||||||
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
const ServiceBooking* currentBooking = currentBookings.getValueAt(iterator);
|
||||||
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
if (currentBooking && currentBooking->getStatus() == util::ServiceJobStatus::PENDING)
|
||||||
{
|
{
|
||||||
hasPendingService = true;
|
const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
|
||||||
const User* currentAssignedTechnician = currentBooking->getAssignedTechnician();
|
std::cout << std::left
|
||||||
std::cout << std::left
|
<< std::setw(10) << currentIndex
|
||||||
<< std::setw(10) << currentIndex
|
<< std::setw(10) << currentBooking->getId()
|
||||||
<< std::setw(10) << currentBooking->getId()
|
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
|
||||||
<< std::setw(12) << util::getServiceJobStatusString(currentBooking->getStatus())
|
<< std::setw(12) << currentBooking->getCustomerId()
|
||||||
<< std::setw(12) << currentBooking->getCustomerId()
|
<< std::setw(20) << currentBooking->getCustomer()->getName()
|
||||||
<< std::setw(20) << currentBooking->getCustomer()->getName()
|
<< std::setw(15) << currentBooking->getVehicleNumber()
|
||||||
<< std::setw(15) << currentBooking->getVehicleNumber()
|
<< std::setw(15) << currentBooking->getVehicleBrand()
|
||||||
<< std::setw(15) << currentBooking->getVehicleBrand()
|
<< std::setw(15) << currentBooking->getVehicleModel()
|
||||||
<< std::setw(15) << currentBooking->getVehicleModel()
|
<< std::endl;
|
||||||
<< std::setw(20) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getName().empty()) ? "Null" : currentAssignedTechnician->getName())
|
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
||||||
<< std::setw(15) << ((currentAssignedTechnician == nullptr || currentAssignedTechnician->getId().empty()) ? "Null" : currentAssignedTechnician->getId())
|
}
|
||||||
<< std::endl;
|
|
||||||
serviceBookingsMap.insert(currentIndex++, currentBooking);
|
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
if (!hasPendingService)
|
|
||||||
{
|
|
||||||
std::cout << "No pending service available." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -223,15 +250,15 @@ Returns:
|
|||||||
inline const ServiceBooking* selectPendingServiceBookings(util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
inline const ServiceBooking* selectPendingServiceBookings(util::Map<int, const ServiceBooking*>& serviceBookingsMap)
|
||||||
{
|
{
|
||||||
int userInputIndex;
|
int userInputIndex;
|
||||||
std::cout << "Enter a valid service index: ";
|
std::cout << "\nEnter a service index: ";
|
||||||
util::read(userInputIndex);
|
util::read(userInputIndex);
|
||||||
if (serviceBookingsMap.find(userInputIndex) != -1)
|
if (serviceBookingsMap.find(userInputIndex) != -1)
|
||||||
{
|
{
|
||||||
return serviceBookingsMap.getValueAt(userInputIndex);
|
return serviceBookingsMap.getValueAt(serviceBookingsMap.find(userInputIndex));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Enter a valid index.";
|
std::cout << "Enter a valid index.\n\n";
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,6 +277,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
|||||||
{
|
{
|
||||||
bool hasTechnicians = false;
|
bool hasTechnicians = false;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
|
std::cout << "\nSelect Technician\n";
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(6) << "Index"
|
||||||
<< std::setw(15) << "Technician ID"
|
<< std::setw(15) << "Technician ID"
|
||||||
@@ -272,7 +300,7 @@ inline void listAvailableTechnicians(util::Map<std::string, const User*> current
|
|||||||
}
|
}
|
||||||
if (!hasTechnicians)
|
if (!hasTechnicians)
|
||||||
{
|
{
|
||||||
std::cout << "No technicians currently available.";
|
std::cout << "No technicians currently available.\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,17 +313,18 @@ Returns:
|
|||||||
- const User*: Pointer to the selected technician, or nullptr if invalid
|
- const User*: Pointer to the selected technician, or nullptr if invalid
|
||||||
*/
|
*/
|
||||||
inline const User* selectTechnician(util::Map<int, const User*>& currentAvailableTechniciansMap)
|
inline const User* selectTechnician(util::Map<int, const User*>& currentAvailableTechniciansMap)
|
||||||
|
{
|
||||||
|
int userInputIndex;
|
||||||
|
std::cout << "\nEnter technician index: ";
|
||||||
|
util::read(userInputIndex);
|
||||||
|
if (currentAvailableTechniciansMap.find(userInputIndex) != -1)
|
||||||
{
|
{
|
||||||
int userInputIndex;
|
return currentAvailableTechniciansMap.getValueAt(currentAvailableTechniciansMap.find(userInputIndex));
|
||||||
util::read(userInputIndex);
|
}
|
||||||
if (currentAvailableTechniciansMap.find(userInputIndex) != -1)
|
else
|
||||||
{
|
{
|
||||||
return currentAvailableTechniciansMap.getValueAt(userInputIndex);
|
std::cout << "Enter a valid index.\n\n";
|
||||||
}
|
return nullptr;
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cout << "Enter a valid index.";
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,39 +338,38 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline std::string selectInvoiceFromUserForPayment(const util::Map<std::string, const Invoice*>& currentInvoices)
|
inline std::string selectInvoiceFromUserForPayment(const util::Map<std::string, const Invoice*>& currentInvoices)
|
||||||
{
|
{
|
||||||
util::clear();
|
|
||||||
int currentIndex = 1, choice;
|
int currentIndex = 1, choice;
|
||||||
util::Map<int, const Invoice*> pendingInvoicesForPayment;
|
util::Map<int, const Invoice*> pendingInvoicesForPayment;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(8) << "Index"
|
||||||
<< std::setw(12) << "BookingID"
|
<< std::setw(15) << "Booking ID"
|
||||||
<< std::setw(15) << "VehicleBrand"
|
<< std::setw(20) << "Vehicle Brand"
|
||||||
<< std::setw(15) << "VehicleNumber"
|
<< std::setw(20) << "Vehicle Number"
|
||||||
<< std::setw(12) << "Technician ID"
|
<< std::setw(18) << "Technician ID"
|
||||||
<< std::setw(20) << "Technician Name"
|
<< std::setw(25) << "Technician Name"
|
||||||
<< std::setw(10) << "Discount(%)"
|
<< std::setw(15) << "Discount(%)"
|
||||||
<< std::setw(12) << "TotalAmount"
|
<< std::setw(15) << "TotalAmount"
|
||||||
<< std::setw(20) << "InvoiceDate"
|
<< std::setw(22) << "Invoice Timestamp"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
const Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
|
const Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
|
||||||
if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING)
|
if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING)
|
||||||
{
|
{
|
||||||
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << currentIndex
|
<< std::setw(8) << currentIndex
|
||||||
<< std::setw(12) << currentInvoice->getBookingId()
|
<< std::setw(15) << currentInvoice->getBookingId()
|
||||||
<< std::setw(15) << currentInvoice->getBooking()->getVehicleBrand()
|
<< std::setw(20) << currentInvoice->getBooking()->getVehicleBrand()
|
||||||
<< std::setw(15) << currentInvoice->getBooking()->getVehicleNumber()
|
<< std::setw(20) << currentInvoice->getBooking()->getVehicleNumber()
|
||||||
<< std::setw(12) << ((currentTechnician != nullptr && currentTechnician->getId() != "") ?
|
<< std::setw(18) << ((currentTechnician != nullptr && currentTechnician->getId() != "") ?
|
||||||
currentTechnician->getId() : "Null")
|
currentTechnician->getId() : "Null")
|
||||||
<< std::setw(20) << ((currentTechnician != nullptr && currentTechnician->getName() != "") ?
|
<< std::setw(25) << ((currentTechnician != nullptr && currentTechnician->getName() != "") ?
|
||||||
currentTechnician->getName() : "Null")
|
currentTechnician->getName() : "Null")
|
||||||
<< std::setw(10) << currentInvoice->getDiscountPercentage()
|
<< std::setw(15) << currentInvoice->getDiscountPercentage()
|
||||||
<< std::setw(12) << currentInvoice->getTotalAmount()
|
<< std::setw(15) << currentInvoice->getTotalAmount()
|
||||||
<< std::setw(20) << currentInvoice->getInvoiceDate().toString()
|
<< std::setw(22) << currentInvoice->getInvoiceDate().toString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
pendingInvoicesForPayment.insert(currentIndex++, currentInvoice);
|
pendingInvoicesForPayment.insert(currentIndex++, currentInvoice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -375,23 +403,94 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
inline util::PaymentMode selectPaymentMode()
|
inline util::PaymentMode selectPaymentMode()
|
||||||
{
|
{
|
||||||
int choice;
|
int choice;
|
||||||
std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: ";
|
while (true)
|
||||||
util::read(choice);
|
|
||||||
if (choice == 1)
|
|
||||||
{
|
{
|
||||||
std::cout << "Offline mode selected.\n";
|
util::clear();
|
||||||
return util::PaymentMode::OFFLINE;
|
std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: ";
|
||||||
}
|
util::read(choice);
|
||||||
else if (choice == 2)
|
if (choice == 1)
|
||||||
{
|
{
|
||||||
std::cout << "Online mode selected.\n";
|
std::cout << "Offline mode selected.\n";
|
||||||
return util::PaymentMode::ONLINE;
|
return util::PaymentMode::OFFLINE;
|
||||||
}
|
}
|
||||||
else
|
else if (choice == 2)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid choice. Offline mode selected.\n";
|
std::cout << "Online mode selected.\n";
|
||||||
return util::PaymentMode::OFFLINE;
|
return util::PaymentMode::ONLINE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Invalid choice. Try again.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayInvoicesInTabularForm
|
||||||
|
Description:
|
||||||
|
Displays all invoices in a tabular format. Each row shows booking details,
|
||||||
|
vehicle info, technician details, discount, total amount, invoice date,
|
||||||
|
and payment status. If inventory items exist for an invoice, they are
|
||||||
|
displayed in a separate table below the invoice row.
|
||||||
|
Parameters:
|
||||||
|
- currentInvoices: util::Map<std::string, const Invoice*>
|
||||||
|
Map of invoice IDs to Invoice pointers.
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
inline const Invoice* selectInvoiceToDisplay(util::Map<std::string, const Invoice*>& currentInvoices)
|
||||||
|
{
|
||||||
|
int currentIndex = 1, choice;
|
||||||
|
util::Map<int, const Invoice*> currentInvoicesIndexMap;
|
||||||
|
if (currentInvoices.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "No invoices available.\n\n";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::cout
|
||||||
|
<< std::left
|
||||||
|
<< std::setw(10) << "Index"
|
||||||
|
<< std::setw(12) << "BookingID"
|
||||||
|
<< std::setw(20) << "Vehicle Number"
|
||||||
|
<< std::setw(20) << "Technician Name"
|
||||||
|
<< std::setw(15) << "Total Amount"
|
||||||
|
<< std::setw(25) << "Invoice Date"
|
||||||
|
<< std::setw(20) << "Payment Status"
|
||||||
|
<< std::setw(15) << "Payment Mode"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const Invoice* currentInvoice = currentInvoices.getValueAt(iterator);
|
||||||
|
if (!currentInvoice)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(10) << currentIndex
|
||||||
|
<< std::setw(12) << currentInvoice->getBookingId()
|
||||||
|
<< std::setw(20) << currentInvoice->getBooking()->getVehicleNumber()
|
||||||
|
<< std::setw(20) << ((currentTechnician && !currentTechnician->getName().empty()) ? currentTechnician->getName() : "NULL")
|
||||||
|
<< std::setw(15) << currentInvoice->getTotalAmount()
|
||||||
|
<< std::setw(25) << currentInvoice->getInvoiceDate().toString()
|
||||||
|
<< std::setw(20) << util::getPaymentStatusString(currentInvoice->getStatus())
|
||||||
|
<< std::setw(15) << util::getPaymentModeString(currentInvoice->getPaymentMethod())
|
||||||
|
<< std::endl;
|
||||||
|
currentInvoicesIndexMap.insert(currentIndex++, currentInvoice);
|
||||||
|
}
|
||||||
|
std::cout << "Enter an index: ";
|
||||||
|
util::read(choice);
|
||||||
|
int currentSelectedIndex = currentInvoicesIndexMap.find(choice);
|
||||||
|
if (currentSelectedIndex != -1)
|
||||||
|
{
|
||||||
|
return currentInvoicesIndexMap.getValueAt(currentSelectedIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Enter a valid index.\n";
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,59 +507,116 @@ Throws:
|
|||||||
*/
|
*/
|
||||||
inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserInvoices)
|
inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserInvoices)
|
||||||
{
|
{
|
||||||
if (currentUserInvoices.getSize() == 0)
|
std::cout << std::endl;
|
||||||
|
if (currentUserInvoices.getSize() == 0)
|
||||||
{
|
{
|
||||||
std::cout << "No invoices found for this account." << std::endl;
|
std::cout << "No invoices found for this account.\n\n";
|
||||||
util::pressEnter();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int index = 0; index < currentUserInvoices.getSize(); index++)
|
bool doRun = true;
|
||||||
{
|
do
|
||||||
const Invoice* currentInvoice = currentUserInvoices.getValueAt(index);
|
{
|
||||||
if (currentInvoice)
|
const Invoice* selectedInvoice;
|
||||||
{
|
int choice;
|
||||||
const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician();
|
selectedInvoice = selectInvoiceToDisplay(currentUserInvoices);
|
||||||
std::cout << "\nInvoice Details\n";
|
if (selectedInvoice)
|
||||||
std::cout << "Booking ID: " << currentInvoice->getBookingId() << std::endl;
|
{
|
||||||
std::cout << "Vehicle Brand: " << currentInvoice->getBooking()->getVehicleBrand() << std::endl;
|
const User* currentTechnician = selectedInvoice->getBooking()->getAssignedTechnician();
|
||||||
std::cout << "Vehicle Number: " << currentInvoice->getBooking()->getVehicleNumber() << std::endl;
|
util::clear();
|
||||||
std::cout << "Technician ID: " <<
|
std::cout << "Invoice Details\n";
|
||||||
((currentTechnician != nullptr && currentTechnician->getId() != "") ?
|
std::cout << std::left << std::setw(20) << "Booking ID:"
|
||||||
currentTechnician->getId() : "Null") << std::endl;
|
<< selectedInvoice->getBookingId() << std::endl;
|
||||||
std::cout << "Technician Name: " <<
|
std::cout << std::left << std::setw(20) << "Vehicle Brand:"
|
||||||
((currentTechnician != nullptr && currentTechnician->getName() != "") ?
|
<< selectedInvoice->getBooking()->getVehicleBrand() << std::endl;
|
||||||
currentTechnician->getName() : "Null") << std::endl;
|
std::cout << std::left << std::setw(20) << "Vehicle Number:"
|
||||||
std::cout << "Discount(%): " << currentInvoice->getDiscountPercentage() << std::endl;
|
<< selectedInvoice->getBooking()->getVehicleNumber() << std::endl;
|
||||||
std::cout << "Total Amount: " << currentInvoice->getTotalAmount() << std::endl;
|
std::cout << std::left << std::setw(20) << "Technician ID:"
|
||||||
std::cout << "Invoice Date: " << currentInvoice->getInvoiceDate().toString() << std::endl;
|
<< ((currentTechnician != nullptr && !currentTechnician->getId().empty())
|
||||||
std::cout << "Payment Status: " << util::getPaymentStatusString(currentInvoice->getStatus()) << std::endl;
|
? currentTechnician->getId() : "NULL") << std::endl;
|
||||||
auto inventoryItemsInInvoice = currentInvoice->getParts();
|
std::cout << std::left << std::setw(20) << "Technician Name:"
|
||||||
std::cout << "\nItems Used:\n";
|
<< ((currentTechnician != nullptr && !currentTechnician->getName().empty())
|
||||||
std::cout << std::left
|
? currentTechnician->getName() : "NULL") << std::endl;
|
||||||
<< std::setw(20) << "ItemName"
|
std::cout << std::left << std::setw(20) << "Discount(%):"
|
||||||
<< std::setw(10) << "Quantity"
|
<< selectedInvoice->getDiscountPercentage() << std::endl;
|
||||||
<< std::setw(10) << "Price"
|
std::cout << std::left << std::setw(20) << "Total Amount:"
|
||||||
<< std::endl;
|
<< selectedInvoice->getTotalAmount() << std::endl;
|
||||||
std::cout << std::string(40, '-') << std::endl;
|
std::cout << std::left << std::setw(20) << "Invoice Date:"
|
||||||
for (int iterator = 0; iterator < inventoryItemsInInvoice.getSize(); iterator++)
|
<< selectedInvoice->getInvoiceDate().toString() << std::endl;
|
||||||
{
|
std::cout << std::left << std::setw(20) << "Payment Status:"
|
||||||
InventoryItem* currentItem = inventoryItemsInInvoice.getValueAt(iterator);
|
<< util::getPaymentStatusString(selectedInvoice->getStatus()) << std::endl;
|
||||||
std::cout << std::left
|
std::cout << std::left << std::setw(20) << "Payment Mode:"
|
||||||
<< std::setw(20) << currentItem->getPartName()
|
<< util::getPaymentModeString(selectedInvoice->getPaymentMethod()) << std::endl;
|
||||||
<< std::setw(10) << currentItem->getQuantity()
|
auto inventoryItemsInInvoice = selectedInvoice->getParts();
|
||||||
<< std::setw(10) << currentItem->getPrice()
|
if (inventoryItemsInInvoice.isEmpty())
|
||||||
<< std::endl;
|
{
|
||||||
|
std::cout << "No inventory items used.\n\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
std::cout << "\n\nDo you want to display another Invoice (1-Yes, 2-No): ";
|
||||||
|
util::read(choice);
|
||||||
|
if (choice == 1)
|
||||||
|
{
|
||||||
|
doRun = true;
|
||||||
|
util::clear();
|
||||||
|
}
|
||||||
|
else if (choice == 2)
|
||||||
|
{
|
||||||
|
doRun = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Invalid choice\n";
|
||||||
|
doRun = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unable to fetch the selected invoice\n";
|
||||||
|
doRun = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (doRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/*
|
||||||
|
Function: filterStartedJobCards
|
||||||
|
Description: Filters the given list of job cards and returns only those with status STARTED.
|
||||||
|
Parameters:
|
||||||
|
- assignedJobCards: Map of job card IDs to JobCard pointers.
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const JobCard*> containing only job cards with status STARTED.
|
||||||
|
*/
|
||||||
|
inline util::Map<std::string, const JobCard*> filterStartedJobCards(util::Map<std::string, const JobCard*>& assignedJobCards)
|
||||||
|
{
|
||||||
|
util::Map<std::string, const JobCard*> startedJobCards;
|
||||||
|
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator);
|
||||||
|
if (currentJobCard && currentJobCard->getStatus() == util::ServiceJobStatus::STARTED)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Null invoice encountered while displaying invoices.");
|
startedJobCards.insert(currentJobCard->getId(), currentJobCard);
|
||||||
util::pressEnter();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return startedJobCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -472,49 +628,50 @@ Parameters:
|
|||||||
Returns:
|
Returns:
|
||||||
- std::string: ID of the selected job card, or empty string if none selected
|
- std::string: ID of the selected job card, or empty string if none selected
|
||||||
*/
|
*/
|
||||||
inline std::string selectJobCardToComplete(util::Map<std::string, const JobCard*>& assignedJobCards, util::Map<int, const JobCard*>& incompleteJobCards)
|
inline std::string selectJobCardToComplete(util::Map<std::string, const JobCard*>& assignedJobCards)
|
||||||
|
{
|
||||||
|
util::Map<int, const JobCard* > incompleteJobCards;
|
||||||
|
if (assignedJobCards.getSize() == 0)
|
||||||
{
|
{
|
||||||
int currentIndex = 1;
|
std::cout << "No started jobs available to complete.\n";
|
||||||
int choice;
|
return "";
|
||||||
bool hasIncompleteJobCard = false;
|
}
|
||||||
std::cout << std::left
|
int currentIndex = 1;
|
||||||
<< std::setw(6) << "Index"
|
int choice;
|
||||||
<< std::setw(12) << "BookingID"
|
std::cout << std::endl;
|
||||||
<< std::setw(12) << "JobID"
|
std::cout << std::left
|
||||||
<< std::setw(20) << "ServiceName"
|
<< std::setw(6) << "Index"
|
||||||
<< std::setw(12) << "ServiceID"
|
<< std::setw(12) << "BookingID"
|
||||||
<< std::endl;
|
<< std::setw(12) << "JobID"
|
||||||
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
<< std::setw(20) << "ServiceName"
|
||||||
|
<< std::setw(12) << "ServiceID"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator);
|
const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator);
|
||||||
if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED))
|
if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED))
|
||||||
{
|
{
|
||||||
std::cout << std::left << std::setw(6) << currentIndex
|
std::cout << std::left << std::setw(6) << currentIndex
|
||||||
<< std::setw(12) << currentJobCard->getBookingId()
|
<< std::setw(12) << currentJobCard->getBookingId()
|
||||||
<< std::setw(12) << currentJobCard->getId()
|
<< std::setw(12) << currentJobCard->getId()
|
||||||
<< std::setw(20) << currentJobCard->getService()->getName()
|
<< std::setw(20) << currentJobCard->getService()->getName()
|
||||||
<< std::setw(12) << currentJobCard->getServiceId()
|
<< std::setw(12) << currentJobCard->getServiceId()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
hasIncompleteJobCard = true;
|
incompleteJobCards.insert(currentIndex++, currentJobCard);
|
||||||
incompleteJobCards.insert(currentIndex++, currentJobCard);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!hasIncompleteJobCard)
|
std::cout << "Select the Job Card to complete (Index): ";
|
||||||
{
|
|
||||||
std::cout << "No pending jobs are present.\n";
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
std::cout << "Select the Job Card to complete (Index): ";
|
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
int selectedJobCardIndex = incompleteJobCards.find(choice);
|
int selectedJobCardIndex = incompleteJobCards.find(choice);
|
||||||
if (selectedJobCardIndex != -1)
|
if (selectedJobCardIndex != -1)
|
||||||
{
|
{
|
||||||
const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex);
|
const JobCard* selectedJobCard = incompleteJobCards.getValueAt(selectedJobCardIndex);
|
||||||
return selectedJobCard->getId();
|
return selectedJobCard->getId();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Invalid index.\n";
|
std::cout << "Invalid index.\n";
|
||||||
|
std::cout << "Failed to complete jobs.\n\n";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,9 +688,9 @@ inline const Notification* selectNotification(const util::Vector<const Notificat
|
|||||||
{
|
{
|
||||||
util::Map<int, const Notification*> indexedNotifications;
|
util::Map<int, const Notification*> indexedNotifications;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(10) << "Index"
|
||||||
<< std::setw(15) << "ID"
|
<< std::setw(15) << "ID"
|
||||||
<< std::setw(30) << "Title"
|
<< std::setw(35) << "Title"
|
||||||
<< std::setw(25) << "Timestamp"
|
<< std::setw(25) << "Timestamp"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
@@ -543,9 +700,9 @@ inline const Notification* selectNotification(const util::Vector<const Notificat
|
|||||||
if (currentNotification)
|
if (currentNotification)
|
||||||
{
|
{
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << currentIndex
|
<< std::setw(10) << currentIndex
|
||||||
<< std::setw(15) << currentNotification->getId()
|
<< std::setw(15) << currentNotification->getId()
|
||||||
<< std::setw(35) << currentNotification->getTitle()
|
<< std::setw(35) << util::truncateString(currentNotification->getTitle(), 30)
|
||||||
<< std::setw(25) << currentNotification->getCreatedAt().toString()
|
<< std::setw(25) << currentNotification->getCreatedAt().toString()
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
indexedNotifications.insert(currentIndex, currentNotification);
|
indexedNotifications.insert(currentIndex, currentNotification);
|
||||||
@@ -698,6 +855,7 @@ inline void displayAllActiveUsers(util::Map<std::string, const User*>& activeUse
|
|||||||
std::cout << std::left << std::setw(10) << "Index"
|
std::cout << std::left << std::setw(10) << "Index"
|
||||||
<< std::setw(15) << "User ID"
|
<< std::setw(15) << "User ID"
|
||||||
<< std::setw(25) << "Username"
|
<< std::setw(25) << "Username"
|
||||||
|
<< std::setw(25) << "Full Name"
|
||||||
<< std::setw(25) << "User Type"
|
<< std::setw(25) << "User Type"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < activeUserCount; iterator++)
|
for (int iterator = 0; iterator < activeUserCount; iterator++)
|
||||||
@@ -708,6 +866,7 @@ inline void displayAllActiveUsers(util::Map<std::string, const User*>& activeUse
|
|||||||
std::cout << std::left << std::setw(10) << (iterator + 1)
|
std::cout << std::left << std::setw(10) << (iterator + 1)
|
||||||
<< std::setw(15) << user->getId()
|
<< std::setw(15) << user->getId()
|
||||||
<< std::setw(25) << user->getUserName()
|
<< std::setw(25) << user->getUserName()
|
||||||
|
<< std::setw(25) << user->getName()
|
||||||
<< std::setw(25) << util::getUserTypeString(user->getUserType())
|
<< std::setw(25) << util::getUserTypeString(user->getUserType())
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
@@ -720,6 +879,28 @@ inline void displayAllActiveUsers(util::Map<std::string, const User*>& activeUse
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: filterActiveServices
|
||||||
|
Description: Filters the given list of services and returns only those that are active.
|
||||||
|
Parameters:
|
||||||
|
- serviceList: Map of service IDs to Service pointers.
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const Service*> containing only active services.
|
||||||
|
*/
|
||||||
|
inline util::Map<std::string, const Service*> filterActiveServices(util::Map<std::string, const Service*>& serviceList)
|
||||||
|
{
|
||||||
|
util::Map<std::string, const Service*> activeServices;
|
||||||
|
for (int iterator = 0; iterator < serviceList.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const Service* currentService = serviceList.getValueAt(iterator);
|
||||||
|
if (currentService && currentService->getState() == util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
activeServices.insert(currentService->getId(), currentService);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeServices;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: selectServiceFromServices
|
Function: selectServiceFromServices
|
||||||
Description: Displays active services and allows the customer to select one by index.
|
Description: Displays active services and allows the customer to select one by index.
|
||||||
@@ -728,6 +909,12 @@ Return type: const Service* - selected service
|
|||||||
*/
|
*/
|
||||||
inline const Service* selectServiceFromServices(const util::Map<std::string, const Service*>& services)
|
inline const Service* selectServiceFromServices(const util::Map<std::string, const Service*>& services)
|
||||||
{
|
{
|
||||||
|
if (services.getSize() == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No active services available." << std::endl;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
util::Map<int, const Service*> activeServicesMap;
|
util::Map<int, const Service*> activeServicesMap;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
int userInputIndex;
|
int userInputIndex;
|
||||||
@@ -774,6 +961,31 @@ inline const Service* selectServiceFromServices(const util::Map<std::string, con
|
|||||||
return activeServicesMap[userInputIndex];
|
return activeServicesMap[userInputIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: filterComboPackages
|
||||||
|
Description:
|
||||||
|
Filters the given list of combo packages and returns only those that are ACTIVE.
|
||||||
|
Parameters:
|
||||||
|
- comboPackages: util::Map<std::string, const ComboPackage*>&
|
||||||
|
Map of combo package IDs to ComboPackage pointers.
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const ComboPackage*>
|
||||||
|
Map containing only active combo packages.
|
||||||
|
*/
|
||||||
|
inline util::Map<std::string, const ComboPackage*> filterComboPackages(util::Map<std::string, const ComboPackage*>& comboPackages)
|
||||||
|
{
|
||||||
|
util::Map<std::string, const ComboPackage*> activeComboPackages;
|
||||||
|
for (int iterator = 0; iterator < comboPackages.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const ComboPackage* currentComboPackage = comboPackages.getValueAt(iterator);
|
||||||
|
if (currentComboPackage && currentComboPackage->getState() == util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
activeComboPackages.insert(currentComboPackage->getId(), currentComboPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return activeComboPackages;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: selectComboPackageFromPackages
|
Function: selectComboPackageFromPackages
|
||||||
Description: Displays active combo packages and allows the customer to select one by index.
|
Description: Displays active combo packages and allows the customer to select one by index.
|
||||||
@@ -785,10 +997,11 @@ inline const ComboPackage* selectComboPackageFromPackages(const util::Map<std::s
|
|||||||
util::Map<int, const ComboPackage*> activeComboPackages;
|
util::Map<int, const ComboPackage*> activeComboPackages;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
int userInputIndex;
|
int userInputIndex;
|
||||||
|
std::cout << std::endl;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(10) << "Index"
|
<< std::setw(10) << "Index"
|
||||||
<< std::setw(15) << "Combo ID"
|
<< std::setw(15) << "Combo ID"
|
||||||
<< std::setw(15) << "Combo Name"
|
<< std::setw(35) << "Combo Name"
|
||||||
<< std::setw(15) << "Estimate Cost"
|
<< std::setw(15) << "Estimate Cost"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int index = 0; index < comboPackages.getSize(); index++)
|
for (int index = 0; index < comboPackages.getSize(); index++)
|
||||||
@@ -802,7 +1015,7 @@ inline const ComboPackage* selectComboPackageFromPackages(const util::Map<std::s
|
|||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(10) << currentIndex
|
<< std::setw(10) << currentIndex
|
||||||
<< std::setw(15) << currentComboPackage->getId()
|
<< std::setw(15) << currentComboPackage->getId()
|
||||||
<< std::setw(25) << currentComboPackage->getPackageName()
|
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
|
||||||
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
|
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
currentIndex++;
|
currentIndex++;
|
||||||
@@ -836,7 +1049,7 @@ inline bool getNotificationPreference(const std::string& serviceName)
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
std::cout << " Configure Notification Preferences\n";
|
std::cout << "Configure Notification Preferences\n";
|
||||||
std::cout << "\n" << serviceName << " Notifications\n";
|
std::cout << "\n" << serviceName << " Notifications\n";
|
||||||
std::cout << "1. Enable Notifications\n";
|
std::cout << "1. Enable Notifications\n";
|
||||||
std::cout << "2. Disable Notifications\n";
|
std::cout << "2. Disable Notifications\n";
|
||||||
@@ -870,7 +1083,7 @@ inline util::Map<std::string, const InventoryItem*> filterActiveItems(const util
|
|||||||
for (int index = 0; index < inventorySize; index++)
|
for (int index = 0; index < inventorySize; index++)
|
||||||
{
|
{
|
||||||
const InventoryItem* item = inventoryItems.getValueAt(index);
|
const InventoryItem* item = inventoryItems.getValueAt(index);
|
||||||
if (item != nullptr && item->getState() != util::State::INACTIVE)
|
if (item && item->getState() != util::State::INACTIVE)
|
||||||
{
|
{
|
||||||
activeItems.insert(item->getId(), item);
|
activeItems.insert(item->getId(), item);
|
||||||
}
|
}
|
||||||
@@ -908,6 +1121,7 @@ inline void displayInventoryWithItems(util::Map<std::string, const InventoryItem
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -927,7 +1141,7 @@ inline void addQuantityToItem(util::Map<std::string, const InventoryItem*>& inve
|
|||||||
int activeSize = activeItems.getSize();
|
int activeSize = activeItems.getSize();
|
||||||
if (activeSize == 0)
|
if (activeSize == 0)
|
||||||
{
|
{
|
||||||
std::cout << "No active items available in Inventory" << std::endl;
|
std::cout << "\nNo active items available in Inventory" << std::endl << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
displayInventoryWithItems(activeItems);
|
displayInventoryWithItems(activeItems);
|
||||||
@@ -935,7 +1149,7 @@ inline void addQuantityToItem(util::Map<std::string, const InventoryItem*>& inve
|
|||||||
util::read(itemIndex);
|
util::read(itemIndex);
|
||||||
if (itemIndex < 1 || itemIndex > activeSize)
|
if (itemIndex < 1 || itemIndex > activeSize)
|
||||||
{
|
{
|
||||||
std::cout << "Invalid index selected." << std::endl;
|
std::cout << "\nInvalid index selected." << std::endl << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << "Enter quantity to add: ";
|
std::cout << "Enter quantity to add: ";
|
||||||
@@ -950,13 +1164,14 @@ inline void addQuantityToItem(util::Map<std::string, const InventoryItem*>& inve
|
|||||||
{
|
{
|
||||||
std::string selectedItemId = selectedItem->getId();
|
std::string selectedItemId = selectedItem->getId();
|
||||||
m_controller.addInventoryItemStock(selectedItemId, quantity);
|
m_controller.addInventoryItemStock(selectedItemId, quantity);
|
||||||
std::cout << "Updated " << selectedItem->getPartName()
|
std::cout << "\nUpdated " << selectedItem->getPartName()
|
||||||
<< " stock. New quantity: " << selectedItem->getQuantity()
|
<< " stock. New quantity: " << selectedItem->getQuantity()
|
||||||
|
<< std::endl
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Error: Selected item could not be found." << std::endl;
|
std::cout << "\nError: Selected item could not be found." << std::endl << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -973,21 +1188,21 @@ inline void displayComboPackagesWithIndex(util::Map<int, const ComboPackage*>& c
|
|||||||
const ComboPackage* currentComboPackage = currentComboPackageIndexMap.getValueAt(iterator);
|
const ComboPackage* currentComboPackage = currentComboPackageIndexMap.getValueAt(iterator);
|
||||||
if (currentComboPackage == nullptr)
|
if (currentComboPackage == nullptr)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Error accessing the combopackage.\n");
|
throw std::runtime_error("Error accessing the combo package.\n");
|
||||||
}
|
}
|
||||||
if (iterator == 0)
|
if (iterator == 0)
|
||||||
{
|
{
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(8) << "Index"
|
<< std::setw(8) << "Index"
|
||||||
<< std::setw(10) << "ID"
|
<< std::setw(10) << "ID"
|
||||||
<< std::setw(20) << "Package Name"
|
<< std::setw(35) << "Package Name"
|
||||||
<< std::setw(15) << "Discount (%)"
|
<< std::setw(15) << "Discount (%)"
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(8) << currentComboPackageIndexMap.getKeyAt(iterator)
|
<< std::setw(8) << currentComboPackageIndexMap.getKeyAt(iterator)
|
||||||
<< std::setw(10) << currentComboPackage->getId()
|
<< std::setw(10) << currentComboPackage->getId()
|
||||||
<< std::setw(20) << currentComboPackage->getPackageName()
|
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
|
||||||
<< std::setw(15) << currentComboPackage->getDiscountPercentage()
|
<< std::setw(15) << currentComboPackage->getDiscountPercentage()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
}
|
}
|
||||||
@@ -1004,7 +1219,8 @@ inline std::string selectComboPackage(util::Map<std::string, const ComboPackage*
|
|||||||
util::Map<int, const ComboPackage*> currentComboPackageIndexMap;
|
util::Map<int, const ComboPackage*> currentComboPackageIndexMap;
|
||||||
if (currentComboPackages.getSize() == 0)
|
if (currentComboPackages.getSize() == 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("No combo packages are available.\n");
|
std::cout << "No combo packages are available.\n";
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
int currentIndex = 1, choice, selectedIndex;
|
int currentIndex = 1, choice, selectedIndex;
|
||||||
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentComboPackages.getSize(); iterator++)
|
||||||
@@ -1017,7 +1233,8 @@ inline std::string selectComboPackage(util::Map<std::string, const ComboPackage*
|
|||||||
}
|
}
|
||||||
if (currentComboPackageIndexMap.getSize() == 0)
|
if (currentComboPackageIndexMap.getSize() == 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("No combo packages currently active.");
|
std::cout << "No combo packages currently active.\n";
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
displayComboPackagesWithIndex(currentComboPackageIndexMap);
|
displayComboPackagesWithIndex(currentComboPackageIndexMap);
|
||||||
std::cout << "Enter your choice(Index): ";
|
std::cout << "Enter your choice(Index): ";
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
|
|||||||
Author: Trenser
|
Author: Trenser
|
||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "InputHelper.h"
|
#include "InputHelper.h"
|
||||||
#include "JobCard.h"
|
#include "JobCard.h"
|
||||||
@@ -92,18 +93,15 @@ Returns:
|
|||||||
*/
|
*/
|
||||||
void TechnicianMenu::completeJob()
|
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*> assignedJobCards = m_controller.getJobCardsByUser();
|
||||||
util::Map<int, const JobCard*> incompleteJobCards;
|
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
|
||||||
std::cout << "Jobs to be completed.\n";
|
std::string selectedJobID = selectJobCardToComplete(startedJobCards);
|
||||||
std::string selectedJobID = selectJobCardToComplete(assignedJobCards, incompleteJobCards);
|
if (!selectedJobID.empty())
|
||||||
if (selectedJobID == "")
|
|
||||||
{
|
|
||||||
std::cout << "Failed to complete the job.\n";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
m_controller.completeJob(selectedJobID);
|
m_controller.completeJob(selectedJobID);
|
||||||
std::cout << "Job marked as completed.\n";
|
std::cout << "\nJob marked as completed.\n\n";
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ Author: Trenser
|
|||||||
Date:19-May-2026
|
Date:19-May-2026
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "InputHelper.h"
|
#include "InputHelper.h"
|
||||||
#include "OutputHelper.h"
|
#include "OutputHelper.h"
|
||||||
@@ -23,29 +25,44 @@ Return type: void
|
|||||||
*/
|
*/
|
||||||
void UserInterface::run()
|
void UserInterface::run()
|
||||||
{
|
{
|
||||||
m_controller.loadSystemData();
|
try
|
||||||
m_controller.runSystemChecks();
|
|
||||||
bool isMenuActive = true;
|
|
||||||
while (isMenuActive)
|
|
||||||
{
|
{
|
||||||
try
|
m_controller.loadSystemData();
|
||||||
|
m_controller.runSystemChecks();
|
||||||
|
bool isMenuActive = true;
|
||||||
|
while (isMenuActive)
|
||||||
{
|
{
|
||||||
int choice;
|
try
|
||||||
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;
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
m_controller.saveSystemData();
|
||||||
{
|
}
|
||||||
std::cout << "Exception: " << e.what() << std::endl;
|
catch (const std::invalid_argument& exception)
|
||||||
util::pressEnter();
|
{
|
||||||
}
|
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;
|
||||||
}
|
}
|
||||||
m_controller.saveSystemData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user