Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70ec47df04 | |||
| 2ea77bf9b6 | |||
| 972e353832 | |||
| c5ada405e6 | |||
| d6b4310de6 | |||
| 451085e9c2 | |||
| 4657d3e8d1 | |||
| b1b6125d88 | |||
| e739ec6ee2 | |||
| f78e02ed3d | |||
| 807490443e | |||
| b7bc1f574d | |||
| b25b3d59cf | |||
| c1bd2a6ef1 | |||
| 859f7bbeaa | |||
| d6cc6fc04f |
+3
-5
@@ -392,9 +392,9 @@ Parameters:
|
|||||||
Returns:
|
Returns:
|
||||||
- void
|
- void
|
||||||
*/
|
*/
|
||||||
void Controller::completeJob(const std::string& jobID)
|
void Controller::updateJobStatus(const std::string& jobID)
|
||||||
{
|
{
|
||||||
m_serviceManagementService.completeJob(jobID);
|
m_serviceManagementService.updateJobStatus(jobID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
||||||
void removeService(const std::string& serviceID);
|
void removeService(const std::string& serviceID);
|
||||||
util::Map<std::string, const JobCard*> getJobCardsByUser();
|
util::Map<std::string, const JobCard*> getJobCardsByUser();
|
||||||
void completeJob(const std::string& jobID);
|
void updateJobStatus(const std::string& jobID);
|
||||||
void removeUser(const std::string& userID);
|
void removeUser(const std::string& userID);
|
||||||
void createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
void createComboPackage(const std::string& name, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
||||||
void removeComboPackage(const std::string& comboPackageID);
|
void removeComboPackage(const std::string& comboPackageID);
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Place files here.
|
|
||||||
+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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+181
-101
@@ -507,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.
|
||||||
@@ -515,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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1005,7 +1080,7 @@ static bool hasCompletedAllJobs(std::string bookingId, util::Map<std::string, Jo
|
|||||||
JobCard* currentJob = currentAssignedJobs.getValueAt(iterator);
|
JobCard* currentJob = currentAssignedJobs.getValueAt(iterator);
|
||||||
if (currentJob->getBookingId() == bookingId)
|
if (currentJob->getBookingId() == bookingId)
|
||||||
{
|
{
|
||||||
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
if (currentJob->getStatus() != util::ServiceJobStatus::COMPLETED && currentJob->getStatus() != util::ServiceJobStatus::CANCELLED)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1015,18 +1090,19 @@ static bool hasCompletedAllJobs(std::string bookingId, util::Map<std::string, Jo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: completeJob
|
Function: updateJobStatus
|
||||||
Description: Marks a job card as completed for the authenticated technician.
|
Description:
|
||||||
If all job cards in the booking are completed, marks the booking as completed
|
Updates the status of a job card assigned to the currently authenticated technician.
|
||||||
and generates an invoice.
|
- If the job is STARTED, it moves to IN_PROGRESS.
|
||||||
|
- If the job is IN_PROGRESS, it moves to COMPLETED.
|
||||||
|
When all jobs in a service booking are completed, the booking status is updated,
|
||||||
|
an invoice is generated, and a notification is sent to the customer.
|
||||||
Parameters:
|
Parameters:
|
||||||
- jobID: std::string, ID of the job card
|
- jobID: const std::string&, unique identifier of the job card to update.
|
||||||
Returns:
|
Returns:
|
||||||
- void
|
- void
|
||||||
Throws:
|
|
||||||
- std::runtime_error if technician is not authenticated, job card not found, or job already completed
|
|
||||||
*/
|
*/
|
||||||
void ServiceManagementService::completeJob(const std::string& jobID)
|
void ServiceManagementService::updateJobStatus(const std::string& jobID)
|
||||||
{
|
{
|
||||||
AuthenticationManagementService authenticationManagementService;
|
AuthenticationManagementService authenticationManagementService;
|
||||||
PaymentManagementService paymentManagementService;
|
PaymentManagementService paymentManagementService;
|
||||||
@@ -1051,26 +1127,30 @@ void ServiceManagementService::completeJob(const std::string& jobID)
|
|||||||
}
|
}
|
||||||
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
|
||||||
{
|
{
|
||||||
currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
|
currentJob->setStatus(util::ServiceJobStatus::IN_PROGRESS);
|
||||||
jobStatusUpdated = true;
|
jobStatusUpdated = true;
|
||||||
}
|
}
|
||||||
|
else if (currentJob->getStatus() == util::ServiceJobStatus::IN_PROGRESS)
|
||||||
|
{
|
||||||
|
currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||||
|
jobStatusUpdated = true;
|
||||||
|
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
||||||
|
if (serviceBookingCompleted)
|
||||||
|
{
|
||||||
|
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
||||||
|
paymentManagementService.generateInvoice(currentJob->getBooking());
|
||||||
|
std::string title = "Service Booking completed. Invoice Generated.";
|
||||||
|
std::string message = "Services completed for the booking and invoice generated.";
|
||||||
|
sendNotification(currentJob->getBooking()->getCustomer(), title, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
throw std::runtime_error("Failed to update job status. Job may already be completed.");
|
||||||
}
|
}
|
||||||
if (!jobStatusUpdated)
|
if (!jobStatusUpdated)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
|
throw std::runtime_error("Failed to update job status. Job may already be completed.");
|
||||||
}
|
|
||||||
|
|
||||||
serviceBookingCompleted = hasCompletedAllJobs(currentJob->getBookingId(), currentAssignedJobs);
|
|
||||||
if (serviceBookingCompleted)
|
|
||||||
{
|
|
||||||
currentJob->getBooking()->setStatus(util::ServiceJobStatus::COMPLETED);
|
|
||||||
paymentManagementService.generateInvoice(currentJob->getBooking());
|
|
||||||
std::string title = "Service Booking completed,Invoice Generated.";
|
|
||||||
std::string message = "Services completed for the booking and invoice generated.";
|
|
||||||
sendNotification(currentJob->getBooking()->getCustomer(), title, message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -37,7 +37,7 @@ public:
|
|||||||
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
void createService(const std::string& name, const util::Vector<std::string>& inventoryItemIDs, double laborCost);
|
||||||
void removeService(const std::string& serviceID);
|
void removeService(const std::string& serviceID);
|
||||||
util::Map<std::string, JobCard*> getJobCards(const std::string& technicianID);
|
util::Map<std::string, JobCard*> getJobCards(const std::string& technicianID);
|
||||||
void completeJob(const std::string& jobID);
|
void updateJobStatus(const std::string& jobID);
|
||||||
void cancelCustomerServiceBookings(const std::string& customerID);
|
void cancelCustomerServiceBookings(const std::string& customerID);
|
||||||
void cancelTechnicianJobs(const std::string& technicianID);
|
void cancelTechnicianJobs(const std::string& technicianID);
|
||||||
void createComboPackage(const std::string& packageName, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
void createComboPackage(const std::string& packageName, const util::Vector<std::string>& serviceIDs, double discountPercentage);
|
||||||
|
|||||||
+8
@@ -306,6 +306,14 @@ void UserManagementService::removeUser(const std::string& userID)
|
|||||||
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);
|
inventoryManagementService.detach(user);
|
||||||
paymentManagementService.detach(user);
|
paymentManagementService.detach(user);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ namespace util
|
|||||||
PENDING,
|
PENDING,
|
||||||
STARTED,
|
STARTED,
|
||||||
COMPLETED,
|
COMPLETED,
|
||||||
|
IN_PROGRESS,
|
||||||
CANCELLED
|
CANCELLED
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -137,6 +138,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");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,6 +210,8 @@ namespace util
|
|||||||
return "COMPLETED";
|
return "COMPLETED";
|
||||||
case ServiceJobStatus::CANCELLED:
|
case ServiceJobStatus::CANCELLED:
|
||||||
return "CANCELLED";
|
return "CANCELLED";
|
||||||
|
case ServiceJobStatus::IN_PROGRESS:
|
||||||
|
return "IN_PROGRESS";
|
||||||
}
|
}
|
||||||
throw std::invalid_argument("Invalid ServiceJobStatus");
|
throw std::invalid_argument("Invalid ServiceJobStatus");
|
||||||
}
|
}
|
||||||
@@ -237,6 +244,10 @@ namespace util
|
|||||||
{
|
{
|
||||||
return ServiceJobStatus::CANCELLED;
|
return ServiceJobStatus::CANCELLED;
|
||||||
}
|
}
|
||||||
|
if (value == "IN_PROGRESS")
|
||||||
|
{
|
||||||
|
return ServiceJobStatus::IN_PROGRESS;
|
||||||
|
}
|
||||||
throw std::invalid_argument("Invalid ServiceJobStatus string");
|
throw std::invalid_argument("Invalid ServiceJobStatus 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);
|
||||||
|
|||||||
@@ -42,15 +42,18 @@ void AdminMenu::showMenu()
|
|||||||
<< "\n3. Remove Inventory Item"
|
<< "\n3. Remove Inventory Item"
|
||||||
<< "\n4. Check Stock Availability"
|
<< "\n4. Check Stock Availability"
|
||||||
<< "\n5. Assign Job to Technician"
|
<< "\n5. Assign Job to Technician"
|
||||||
<< "\n6. Add Technician"
|
<< "\n6. Display Users"
|
||||||
<< "\n7. Remove Customer/Technician"
|
<< "\n7. Add Technician"
|
||||||
<< "\n8. Create Service"
|
<< "\n8. Remove Customer/Technician"
|
||||||
<< "\n9. Remove Service"
|
<< "\n9. Display Services"
|
||||||
<< "\n10. Create Combo Package"
|
<< "\n10. Create Service"
|
||||||
<< "\n11. Remove Combo Package"
|
<< "\n11. Remove Service"
|
||||||
<< "\n12. View Notifications"
|
<< "\n12. Display Combo Packages"
|
||||||
<< "\n13. Change Password"
|
<< "\n13. Create Combo Package"
|
||||||
<< "\n14. Logout"
|
<< "\n14. Remove Combo Package"
|
||||||
|
<< "\n15. View Notifications"
|
||||||
|
<< "\n16. Change Password"
|
||||||
|
<< "\n17. Logout"
|
||||||
<< "\nEnter a choice: ";
|
<< "\nEnter a choice: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
if (!handleOperation(choice))
|
if (!handleOperation(choice))
|
||||||
@@ -92,30 +95,39 @@ bool AdminMenu::handleOperation(int choice)
|
|||||||
assignJob();
|
assignJob();
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
addTechnician();
|
displayUsers();
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
removeUser();
|
addTechnician();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
createService();
|
removeUser();
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
removeService();
|
displayServices();
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
createComboPackages();
|
createService();
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
removeComboPackage();
|
removeService();
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
viewNotifications();
|
displayComboPackages();
|
||||||
break;
|
break;
|
||||||
case 13:
|
case 13:
|
||||||
changePassword();
|
createComboPackages();
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
|
removeComboPackage();
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
viewNotifications();
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
changePassword();
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
logout();
|
logout();
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
@@ -263,6 +275,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();
|
||||||
@@ -382,6 +395,24 @@ void AdminMenu::assignJob()
|
|||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayServices()
|
||||||
|
Description: Display all active services
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayServices()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "List of all Services\n";
|
||||||
|
util::Map<std::string, const Service*> currentServices = m_controller.getServices();
|
||||||
|
util::Map<std::string, const Service*> currentActiveServices = filterActiveServices(currentServices);
|
||||||
|
displayAllServices(currentActiveServices);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: createService
|
Function: createService
|
||||||
Description: Allows the admin to create a new service by selecting inventory items and specifying labor cost.
|
Description: Allows the admin to create a new service by selecting inventory items and specifying labor cost.
|
||||||
@@ -402,6 +433,11 @@ void AdminMenu::createService()
|
|||||||
util::Map<std::string, const InventoryItem*> activeInventoryItems = filterActiveItems(currentInventoryItems);
|
util::Map<std::string, const InventoryItem*> activeInventoryItems = filterActiveItems(currentInventoryItems);
|
||||||
util::Vector<std::string> selectedInventoryItems;
|
util::Vector<std::string> selectedInventoryItems;
|
||||||
selectInventoryItems(activeInventoryItems,selectedInventoryItems);
|
selectInventoryItems(activeInventoryItems,selectedInventoryItems);
|
||||||
|
if (selectedInventoryItems.isEmpty())
|
||||||
|
{
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::cout << "\nEnter the labour cost: ";
|
std::cout << "\nEnter the labour cost: ";
|
||||||
util::read(labourCost);
|
util::read(labourCost);
|
||||||
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
m_controller.createService(serviceName, selectedInventoryItems, labourCost);
|
||||||
@@ -428,7 +464,7 @@ void AdminMenu::removeService()
|
|||||||
if (selectedServiceID != "")
|
if (selectedServiceID != "")
|
||||||
{
|
{
|
||||||
m_controller.removeService(selectedServiceID);
|
m_controller.removeService(selectedServiceID);
|
||||||
std::cout << "Service removed sucessfully.\n\n";
|
std::cout << "Service removed successfully.\n\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -437,6 +473,29 @@ void AdminMenu::removeService()
|
|||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayUsers
|
||||||
|
Description: Displays all users.
|
||||||
|
Parameter: None
|
||||||
|
Return type: void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayUsers()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
auto listOfUsers = m_controller.getUsers();
|
||||||
|
auto listOfActiveUsers = filterActiveUsers(listOfUsers);
|
||||||
|
int activeUserCount = listOfActiveUsers.getSize();
|
||||||
|
std::cout << "List of all Users\n";
|
||||||
|
if (activeUserCount < 1)
|
||||||
|
{
|
||||||
|
std::cout << "No Active users." << std::endl;
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayAllUsers(listOfActiveUsers);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: addTechnician
|
Function: addTechnician
|
||||||
Description: Adds a new technician after validating username, password, email, and phone number.
|
Description: Adds a new technician after validating username, password, email, and phone number.
|
||||||
@@ -501,12 +560,12 @@ void AdminMenu::removeUser()
|
|||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
displayAllActiveUsers(listOfActiveUsers, activeUserCount);
|
displayAllUsers(listOfActiveUsers);
|
||||||
std::cout << "Enter the index of the user to delete : ";
|
std::cout << "Enter the index of the user to delete : ";
|
||||||
util::read(indexChoice);
|
util::read(indexChoice);
|
||||||
if (indexChoice < 1 || indexChoice > activeUserCount)
|
if (indexChoice < 1 || indexChoice > activeUserCount)
|
||||||
{
|
{
|
||||||
std::cout << "Error Invaild index.\n" << std::endl;
|
std::cout << "Error invalid index.\n" << std::endl;
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -520,6 +579,24 @@ void AdminMenu::removeUser()
|
|||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayComboPackages()
|
||||||
|
Description: Display all active combo packages
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void AdminMenu::displayComboPackages()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "List of all Combo Packages\n";
|
||||||
|
util::Map<std::string, const ComboPackage*> currentComboPackages = m_controller.getComboPackages();
|
||||||
|
util::Map<std::string, const ComboPackage*> currentActiveComboPackages = filterComboPackages(currentComboPackages);
|
||||||
|
displayAllComboPackages(currentActiveComboPackages);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: createComboPackages
|
Function: createComboPackages
|
||||||
Description: Creates a new combo package by selecting two active services and applying a discount.
|
Description: Creates a new combo package by selecting two active services and applying a discount.
|
||||||
@@ -541,7 +618,7 @@ void AdminMenu::createComboPackages()
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
chosenService = selectServiceFromServices(activeServices);
|
chosenService = selectServiceFromServices(activeServices);
|
||||||
if (chosenService == nullptr)
|
if (!chosenService)
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create combo package!\n\n";
|
std::cout << "Failed to create combo package!\n\n";
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
|
|||||||
@@ -24,10 +24,13 @@ public:
|
|||||||
void removeInventoryItem();
|
void removeInventoryItem();
|
||||||
void checkStockAvailability();
|
void checkStockAvailability();
|
||||||
void assignJob();
|
void assignJob();
|
||||||
|
void displayServices();
|
||||||
void createService();
|
void createService();
|
||||||
void removeService();
|
void removeService();
|
||||||
|
void displayUsers();
|
||||||
void addTechnician();
|
void addTechnician();
|
||||||
void removeUser();
|
void removeUser();
|
||||||
|
void displayComboPackages();
|
||||||
void createComboPackages();
|
void createComboPackages();
|
||||||
void removeComboPackage();
|
void removeComboPackage();
|
||||||
void viewNotifications();
|
void viewNotifications();
|
||||||
|
|||||||
@@ -29,6 +29,41 @@ Date: 21-May-2026
|
|||||||
#include "Validator.h"
|
#include "Validator.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayAllServices
|
||||||
|
Description: Displays all active services
|
||||||
|
Parameters:
|
||||||
|
- currentServices: util::Map<std::string, const Service*>, available services
|
||||||
|
Returns:
|
||||||
|
- void;
|
||||||
|
*/
|
||||||
|
inline void displayAllServices(util::Map<std::string, const Service*> currentServices)
|
||||||
|
{
|
||||||
|
if (currentServices.getSize() == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No Services Currently Available.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(12) << "Service ID"
|
||||||
|
<< std::setw(35) << "Name"
|
||||||
|
<< std::setw(10) << "Labor Cost"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < currentServices.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const Service* currentService = currentServices.getValueAt(iterator);
|
||||||
|
if (currentService == nullptr || currentService->getState() == util::State::INACTIVE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(12) << currentService->getId()
|
||||||
|
<< std::setw(35) << util::truncateString(currentService->getName(), 30)
|
||||||
|
<< std::setw(10) << currentService->getLaborCost()
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: selectServicesToRemove
|
Function: selectServicesToRemove
|
||||||
Description: Allows selection of a service to remove by index.
|
Description: Allows selection of a service to remove by index.
|
||||||
@@ -49,7 +84,7 @@ inline std::string selectServicesToRemove(util::Map<std::string, const Service*>
|
|||||||
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++)
|
||||||
@@ -62,7 +97,7 @@ inline std::string selectServicesToRemove(util::Map<std::string, const Service*>
|
|||||||
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;
|
||||||
currentServicesMap.insert(currentIndex++, currentService);
|
currentServicesMap.insert(currentIndex++, currentService);
|
||||||
@@ -94,13 +129,15 @@ inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& c
|
|||||||
bool doRun = true;
|
bool doRun = true;
|
||||||
util::Map<int, const InventoryItem*> currentInventoryMap;
|
util::Map<int, const InventoryItem*> currentInventoryMap;
|
||||||
int choice;
|
int choice;
|
||||||
if (currentInventoryItems.getSize() == 0)
|
if (currentInventoryItems.isEmpty())
|
||||||
{
|
{
|
||||||
std::cout << "No Items Present, Inventory empty.\n";
|
std::cout << "No Items Present, Inventory empty.\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
while (doRun)
|
while (doRun)
|
||||||
{
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Create Service\n";
|
||||||
std::cout << "\nSelect Required Items\n";
|
std::cout << "\nSelect Required Items\n";
|
||||||
bool hasInventoryItems = false;
|
bool hasInventoryItems = false;
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
@@ -119,6 +156,19 @@ inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& c
|
|||||||
{
|
{
|
||||||
continue;
|
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::cout << std::left
|
||||||
<< std::setw(6) << currentIndex
|
<< std::setw(6) << currentIndex
|
||||||
<< std::setw(12) << currentInventoryItem->getId()
|
<< std::setw(12) << currentInventoryItem->getId()
|
||||||
@@ -133,10 +183,9 @@ inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& c
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
std::cout << "Select the item (Index) or enter -1 to exit: ";
|
std::cout << "Select the item (Index) or enter 0 to exit: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
|
if (choice == 0)
|
||||||
if (choice == -1)
|
|
||||||
{
|
{
|
||||||
doRun = false;
|
doRun = false;
|
||||||
}
|
}
|
||||||
@@ -144,6 +193,7 @@ inline void selectInventoryItems(util::Map<std::string, const InventoryItem*>& c
|
|||||||
{
|
{
|
||||||
selectedInventoryItems.push_back(currentInventoryMap.getValueAt(currentInventoryMap.find(choice))->getId());
|
selectedInventoryItems.push_back(currentInventoryMap.getValueAt(currentInventoryMap.find(choice))->getId());
|
||||||
std::cout << "Item added successfully.\n" << std::endl;
|
std::cout << "Item added successfully.\n" << std::endl;
|
||||||
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -438,12 +488,12 @@ inline const Invoice* selectInvoiceToDisplay(util::Map<std::string, const Invoic
|
|||||||
<< std::left
|
<< std::left
|
||||||
<< std::setw(10) << "Index"
|
<< std::setw(10) << "Index"
|
||||||
<< std::setw(12) << "BookingID"
|
<< std::setw(12) << "BookingID"
|
||||||
<< std::setw(15) << "VehicleNumber"
|
<< std::setw(20) << "Vehicle Number"
|
||||||
<< std::setw(20) << "TechnicianName"
|
<< std::setw(20) << "Technician Name"
|
||||||
<< std::setw(15) << "TotalAmount"
|
<< std::setw(15) << "Total Amount"
|
||||||
<< std::setw(25) << "InvoiceDate"
|
<< std::setw(25) << "Invoice Date"
|
||||||
<< std::setw(15) << "PaymentStatus"
|
<< std::setw(20) << "Payment Status"
|
||||||
<< std::setw(15) << "PaymentMode"
|
<< std::setw(15) << "Payment Mode"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++)
|
||||||
{
|
{
|
||||||
@@ -456,11 +506,11 @@ inline const Invoice* selectInvoiceToDisplay(util::Map<std::string, const Invoic
|
|||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(10) << currentIndex
|
<< std::setw(10) << currentIndex
|
||||||
<< std::setw(12) << currentInvoice->getBookingId()
|
<< std::setw(12) << currentInvoice->getBookingId()
|
||||||
<< std::setw(15) << currentInvoice->getBooking()->getVehicleNumber()
|
<< std::setw(20) << currentInvoice->getBooking()->getVehicleNumber()
|
||||||
<< std::setw(20) << ((currentTechnician && !currentTechnician->getName().empty()) ? currentTechnician->getName() : "NULL")
|
<< std::setw(20) << ((currentTechnician && !currentTechnician->getName().empty()) ? currentTechnician->getName() : "NULL")
|
||||||
<< std::setw(15) << currentInvoice->getTotalAmount()
|
<< std::setw(15) << currentInvoice->getTotalAmount()
|
||||||
<< std::setw(25) << currentInvoice->getInvoiceDate().toString()
|
<< std::setw(25) << currentInvoice->getInvoiceDate().toString()
|
||||||
<< std::setw(15) << util::getPaymentStatusString(currentInvoice->getStatus())
|
<< std::setw(20) << util::getPaymentStatusString(currentInvoice->getStatus())
|
||||||
<< std::setw(15) << util::getPaymentModeString(currentInvoice->getPaymentMethod())
|
<< std::setw(15) << util::getPaymentModeString(currentInvoice->getPaymentMethod())
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
currentInvoicesIndexMap.insert(currentIndex++, currentInvoice);
|
currentInvoicesIndexMap.insert(currentIndex++, currentInvoice);
|
||||||
@@ -577,7 +627,6 @@ inline void displayInvoices(util::Map<std::string, const Invoice*> currentUserIn
|
|||||||
std::cout << "Unable to fetch the selected invoice\n";
|
std::cout << "Unable to fetch the selected invoice\n";
|
||||||
doRun = false;
|
doRun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (doRun);
|
} while (doRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -596,7 +645,7 @@ inline util::Map<std::string, const JobCard*> filterStartedJobCards(util::Map<st
|
|||||||
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
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 || currentJobCard->getStatus() == util::ServiceJobStatus::IN_PROGRESS))
|
||||||
{
|
{
|
||||||
startedJobCards.insert(currentJobCard->getId(), currentJobCard);
|
startedJobCards.insert(currentJobCard->getId(), currentJobCard);
|
||||||
}
|
}
|
||||||
@@ -604,25 +653,105 @@ inline util::Map<std::string, const JobCard*> filterStartedJobCards(util::Map<st
|
|||||||
return startedJobCards;
|
return startedJobCards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: filterJobCards
|
||||||
|
Description:
|
||||||
|
Filters the given list of job cards and returns only those
|
||||||
|
whose status matches the specified ServiceJobStatus.
|
||||||
|
Parameters:
|
||||||
|
- assignedJobCards: util::Map<std::string, const JobCard*>&
|
||||||
|
Map of job card IDs to JobCard pointers assigned to the technician.
|
||||||
|
- selectedJobStatus: util::ServiceJobStatus
|
||||||
|
The status type to filter job cards by.
|
||||||
|
Returns:
|
||||||
|
- util::Map<std::string, const JobCard*>
|
||||||
|
A map containing only job cards with the specified status.
|
||||||
|
*/
|
||||||
|
inline util::Map<std::string, const JobCard*> filterJobCards(util::Map<std::string, const JobCard*>& assignedJobCards, util::ServiceJobStatus selectedJobStatus)
|
||||||
|
{
|
||||||
|
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() == selectedJobStatus)
|
||||||
|
{
|
||||||
|
startedJobCards.insert(currentJobCard->getId(), currentJobCard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return startedJobCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayAllJobs
|
||||||
|
Description: Displays all Jobs assigned to a Technician
|
||||||
|
Parameters:
|
||||||
|
- assignedJobCards: util::Map<std::string, const JobCard*>&, job cards assigned to the technician
|
||||||
|
Returns:
|
||||||
|
- std::string: ID of the selected job card, or empty string if none selected
|
||||||
|
*/
|
||||||
|
inline void displayAllJobs(util::Map<std::string, const JobCard*>& assignedJobCards)
|
||||||
|
{
|
||||||
|
if (assignedJobCards.getSize() == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No active jobs assigned.\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(12) << "BookingID"
|
||||||
|
<< std::setw(12) << "JobID"
|
||||||
|
<< std::setw(20) << "ServiceName"
|
||||||
|
<< std::setw(12) << "ServiceID"
|
||||||
|
<< std::setw(12) << "Status"
|
||||||
|
<< std::endl;
|
||||||
|
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
||||||
|
{
|
||||||
|
const JobCard* currentJobCard = assignedJobCards.getValueAt(iterator);
|
||||||
|
if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED || currentJobCard->getStatus() == util::ServiceJobStatus::IN_PROGRESS))
|
||||||
|
{
|
||||||
|
std::cout << std::left << std::setw(12) << currentJobCard->getBookingId()
|
||||||
|
<< std::setw(12) << currentJobCard->getId()
|
||||||
|
<< std::setw(20) << util::truncateString(currentJobCard->getService()->getName(), 15)
|
||||||
|
<< std::setw(12) << currentJobCard->getServiceId()
|
||||||
|
<< std::setw(12) << util::getServiceJobStatusString(currentJobCard->getStatus())
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: selectJobCardToComplete
|
Function: selectJobCardToComplete
|
||||||
Description: Lists all incomplete job cards assigned to the technician and allows selection by index.
|
Description: Lists all incomplete job cards assigned to the technician and allows selection by index.
|
||||||
Parameters:
|
Parameters:
|
||||||
- assignedJobCards: util::Map<std::string, const JobCard*>&, job cards assigned to the technician
|
- assignedJobCards: util::Map<std::string, const JobCard*>&, job cards assigned to the technician
|
||||||
- incompleteJobCards: util::Map<int, const JobCard*>&, map of incomplete job cards indexed for selection
|
|
||||||
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)
|
inline std::string selectJobCardToUpdate(util::Map<std::string, const JobCard*>& assignedJobCards, util::ServiceJobStatus selectedJobStatusType)
|
||||||
{
|
{
|
||||||
util::Map<int, const JobCard* > incompleteJobCards;
|
util::Map<int, const JobCard* > incompleteJobCards;
|
||||||
if (assignedJobCards.getSize() == 0)
|
if (assignedJobCards.getSize() == 0)
|
||||||
{
|
{
|
||||||
std::cout << "No started jobs available to complete.\n";
|
std::cout << "No jobs available.\n\n";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
int currentIndex = 1;
|
int currentIndex = 1;
|
||||||
int choice;
|
int choice;
|
||||||
|
if (selectedJobStatusType == util::ServiceJobStatus::STARTED)
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Select a job to update to Inprogress\n";
|
||||||
|
}
|
||||||
|
else if (selectedJobStatusType == util::ServiceJobStatus::IN_PROGRESS)
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "Select a job to update to Completed\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Unable to update completed or pending jobs.\n\n";
|
||||||
|
return "";
|
||||||
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << std::left
|
std::cout << std::left
|
||||||
<< std::setw(6) << "Index"
|
<< std::setw(6) << "Index"
|
||||||
@@ -630,22 +759,24 @@ inline std::string selectJobCardToComplete(util::Map<std::string, const JobCard*
|
|||||||
<< std::setw(12) << "JobID"
|
<< std::setw(12) << "JobID"
|
||||||
<< std::setw(20) << "ServiceName"
|
<< std::setw(20) << "ServiceName"
|
||||||
<< std::setw(12) << "ServiceID"
|
<< std::setw(12) << "ServiceID"
|
||||||
|
<< std::setw(12) << "JobStatus"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
for (int iterator = 0; iterator < assignedJobCards.getSize(); iterator++)
|
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() == selectedJobStatusType))
|
||||||
{
|
{
|
||||||
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) << util::truncateString(currentJobCard->getService()->getName(), 15)
|
||||||
<< std::setw(12) << currentJobCard->getServiceId()
|
<< std::setw(12) << currentJobCard->getServiceId()
|
||||||
|
<< std::setw(12) << util::getServiceJobStatusString(currentJobCard->getStatus())
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
incompleteJobCards.insert(currentIndex++, currentJobCard);
|
incompleteJobCards.insert(currentIndex++, currentJobCard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "Select the Job Card to complete (Index): ";
|
std::cout << "Select the Job Card to Update (Index): ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
int selectedJobCardIndex = incompleteJobCards.find(choice);
|
int selectedJobCardIndex = incompleteJobCards.find(choice);
|
||||||
if (selectedJobCardIndex != -1)
|
if (selectedJobCardIndex != -1)
|
||||||
@@ -656,7 +787,7 @@ inline std::string selectJobCardToComplete(util::Map<std::string, const JobCard*
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Invalid index.\n";
|
std::cout << "Invalid index.\n";
|
||||||
std::cout << "Failed to complete jobs.\n\n";
|
std::cout << "Failed to update job.\n\n";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -829,17 +960,18 @@ inline util::Map<std::string, const User*> filterActiveUsers(const util::Map<std
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: displayAllActiveUsers
|
Function: displayAllUsers
|
||||||
Description: Displays all active users in a tabular format with index, ID, username, and type.
|
Description: Displays all active users in a tabular format with index, ID, username, and type.
|
||||||
Parameter: util::Map<std::string, const User*>& activeUsers - active users list
|
Parameter: util::Map<std::string, const User*>& activeUsers - active users list
|
||||||
int activeUserCount - number of active users
|
|
||||||
Return type: void
|
Return type: void
|
||||||
*/
|
*/
|
||||||
inline void displayAllActiveUsers(util::Map<std::string, const User*>& activeUsers, int activeUserCount)
|
inline void displayAllUsers(util::Map<std::string, const User*>& activeUsers)
|
||||||
{
|
{
|
||||||
|
int activeUserCount = activeUsers.getSize();
|
||||||
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++)
|
||||||
@@ -850,6 +982,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;
|
||||||
}
|
}
|
||||||
@@ -969,6 +1102,43 @@ inline util::Map<std::string, const ComboPackage*> filterComboPackages(util::Map
|
|||||||
return activeComboPackages;
|
return activeComboPackages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: displayAllComboPackages
|
||||||
|
Description: Displays all active combo packages
|
||||||
|
Parameters:
|
||||||
|
- currentComboPackages: util::Map<std::string, const ComboPackage*>, available combo packages
|
||||||
|
Returns:
|
||||||
|
- void;
|
||||||
|
*/
|
||||||
|
inline void displayAllComboPackages(util::Map<std::string, const ComboPackage*> comboPackages)
|
||||||
|
{
|
||||||
|
std::cout << std::endl;
|
||||||
|
if (comboPackages.getSize() == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No active combo packages available." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(15) << "Combo ID"
|
||||||
|
<< std::setw(35) << "Combo Name"
|
||||||
|
<< std::setw(15) << "Estimate Cost"
|
||||||
|
<< std::endl;
|
||||||
|
for (int index = 0; index < comboPackages.getSize(); index++)
|
||||||
|
{
|
||||||
|
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
|
||||||
|
if (currentComboPackage && currentComboPackage->getState() != util::State::ACTIVE)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << std::left
|
||||||
|
<< std::setw(15) << currentComboPackage->getId()
|
||||||
|
<< std::setw(35) << util::truncateString(currentComboPackage->getPackageName(), 30)
|
||||||
|
<< std::setw(15) << util::calculateComboServiceEstimatedCost(currentComboPackage)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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.
|
||||||
@@ -990,7 +1160,7 @@ inline const ComboPackage* selectComboPackageFromPackages(const util::Map<std::s
|
|||||||
for (int index = 0; index < comboPackages.getSize(); index++)
|
for (int index = 0; index < comboPackages.getSize(); index++)
|
||||||
{
|
{
|
||||||
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
|
const ComboPackage* currentComboPackage = comboPackages.getValueAt(index);
|
||||||
if (currentComboPackage->getState() != util::State::ACTIVE)
|
if (currentComboPackage && currentComboPackage->getState() != util::State::ACTIVE)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1066,7 +1236,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);
|
||||||
}
|
}
|
||||||
@@ -1171,21 +1341,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";
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-15
@@ -34,10 +34,11 @@ void TechnicianMenu::showMenu()
|
|||||||
int choice;
|
int choice;
|
||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Technician Menu"
|
std::cout << "Technician Menu"
|
||||||
<< "\n1. Mark Job as Completed"
|
<< "\n1. Display My Jobs"
|
||||||
<< "\n2. View Notifications"
|
<< "\n2. Update Job Status"
|
||||||
<< "\n3. Change Password"
|
<< "\n3. View Notifications"
|
||||||
<< "\n4. Logout"
|
<< "\n4. Change Password"
|
||||||
|
<< "\n5. Logout"
|
||||||
<< "\nEnter a choice: ";
|
<< "\nEnter a choice: ";
|
||||||
util::read(choice);
|
util::read(choice);
|
||||||
if (!handleOperation(choice))
|
if (!handleOperation(choice))
|
||||||
@@ -64,15 +65,18 @@ bool TechnicianMenu::handleOperation(int choice)
|
|||||||
switch (choice)
|
switch (choice)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
completeJob();
|
displayJobs();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
viewNotifications();
|
updateJobStatus();
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
changePassword();
|
viewNotifications();
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
|
changePassword();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
logout();
|
logout();
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
@@ -83,25 +87,62 @@ bool TechnicianMenu::handleOperation(int choice)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Function: completeJob
|
Function: displayJobs
|
||||||
Description: Allows the technician to mark a selected job card as completed.
|
Description: Displays all Jobs assigned to a Technician
|
||||||
|
Parameters:
|
||||||
|
- None
|
||||||
|
Returns:
|
||||||
|
- void
|
||||||
|
*/
|
||||||
|
void TechnicianMenu::displayJobs()
|
||||||
|
{
|
||||||
|
util::clear();
|
||||||
|
std::cout << "My Jobs\n";
|
||||||
|
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
|
||||||
|
util::Map<std::string, const JobCard*> jobCards = filterStartedJobCards(assignedJobCards);
|
||||||
|
displayAllJobs(jobCards);
|
||||||
|
util::pressEnter();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function: updateJobStatus
|
||||||
|
Description: Allows the technician to update a selected job card.
|
||||||
Validates selection and updates job status through the controller.
|
Validates selection and updates job status through the controller.
|
||||||
Parameters:
|
Parameters:
|
||||||
- None
|
- None
|
||||||
Returns:
|
Returns:
|
||||||
- void
|
- void
|
||||||
*/
|
*/
|
||||||
void TechnicianMenu::completeJob()
|
void TechnicianMenu::updateJobStatus()
|
||||||
{
|
{
|
||||||
util::clear();
|
util::clear();
|
||||||
std::cout << "Complete Job\n";
|
std::cout << "Update Job Status\n";
|
||||||
|
int choice;
|
||||||
|
std::string selectedJobID;
|
||||||
|
util::ServiceJobStatus selectedJobStatus = util::ServiceJobStatus::PENDING;
|
||||||
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
|
util::Map<std::string, const JobCard*> assignedJobCards = m_controller.getJobCardsByUser();
|
||||||
util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
|
std::cout << "Select the type of job you want to update\n1.Started\n2.Inprogress\nChoice: ";
|
||||||
std::string selectedJobID = selectJobCardToComplete(startedJobCards);
|
util::read(choice);
|
||||||
|
if (choice == 1)
|
||||||
|
{
|
||||||
|
selectedJobStatus = util::ServiceJobStatus::STARTED;
|
||||||
|
}
|
||||||
|
else if (choice == 2)
|
||||||
|
{
|
||||||
|
selectedJobStatus = util::ServiceJobStatus::IN_PROGRESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Invalid choice. Please try again.\n";
|
||||||
|
util::pressEnter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
util::Map<std::string, const JobCard*> selectedTypeJobCard = filterJobCards(assignedJobCards, selectedJobStatus);
|
||||||
|
selectedJobID = selectJobCardToUpdate(selectedTypeJobCard, selectedJobStatus);
|
||||||
if (!selectedJobID.empty())
|
if (!selectedJobID.empty())
|
||||||
{
|
{
|
||||||
m_controller.completeJob(selectedJobID);
|
m_controller.updateJobStatus(selectedJobID);
|
||||||
std::cout << "\nJob marked as completed.\n\n";
|
std::cout << "\nJob status updated.\n\n";
|
||||||
}
|
}
|
||||||
util::pressEnter();
|
util::pressEnter();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ private:
|
|||||||
bool handleOperation(int choice);
|
bool handleOperation(int choice);
|
||||||
public:
|
public:
|
||||||
void showMenu();
|
void showMenu();
|
||||||
void completeJob();
|
void displayJobs();
|
||||||
|
void updateJobStatus();
|
||||||
void viewNotifications();
|
void viewNotifications();
|
||||||
void logout();
|
void logout();
|
||||||
void changePassword();
|
void changePassword();
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
void login();
|
void login();
|
||||||
void registerCustomer();
|
void registerCustomer();
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user