diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index 3b674ed..e3a85b0 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -392,9 +392,9 @@ Parameters: Returns: - void */ -void Controller::completeJob(const std::string& jobID) +void Controller::updateJobStatus(const std::string& jobID) { - m_serviceManagementService.completeJob(jobID); + m_serviceManagementService.updateJobStatus(jobID); } /* @@ -462,6 +462,38 @@ util::Map Controller::getInvoicesByUser() return userInvoicesReadOnly; } +/* +Function: getAllInvoices +Description: Retrieves all invoices from the PaymentManagementService and returns them as a read-only map. +Parameters: + - none +Returns: + - util::Map: Map of invoice IDs to invoice objects +*/ +util::Map Controller::getAllInvoices() +{ + auto invoices = m_paymentManagementService.getAllInvoices(); + util::Map readOnlyInvoice; + for (int iterator = 0; iterator < invoices.getSize(); iterator++) + { + readOnlyInvoice.insert(invoices.getKeyAt(iterator), invoices.getValueAt(iterator)); + } + return readOnlyInvoice; +} + +/* +Function: confirmPayment +Description: Delegates payment confirmation for a given invoice ID to the PaymentManagementService. +Parameters: + - invoiceID: std::string, ID of the invoice to confirm +Returns: + - void +*/ +void Controller::confirmPayment(const std::string& invoiceID) +{ + m_paymentManagementService.confirmPayment(invoiceID); +} + /* Function: completePayment Description: Completes payment for a specific invoice using the given payment mode. diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index e75ebd4..35241a0 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -59,11 +59,13 @@ public: void createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost); void removeService(const std::string& serviceID); util::Map getJobCardsByUser(); - void completeJob(const std::string& jobID); + void updateJobStatus(const std::string& jobID); void removeUser(const std::string& userID); void createComboPackage(const std::string& name, const util::Vector& serviceIDs, double discountPercentage); void removeComboPackage(const std::string& comboPackageID); util::Map getInvoicesByUser(); + util::Map getAllInvoices(); + void confirmPayment(const std::string& invoiceID); void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode); util::Vector getNotifications(); void deleteNotification(const std::string& notificationID); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 2733577..1fc1ff8 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -368,12 +368,12 @@ void PaymentManagementService::completePayment(const std::string& invoiceID, uti if (invoiceIndex != -1) { Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); - if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED) + if (invoice && invoice->getStatus() != util::PaymentStatus::PAID) { User* currentUser = invoice->getBooking()->getCustomer(); invoice->setPaymentMethod(paymentMode); invoice->setPaymentDate(util::Timestamp()); - invoice->setStatus(util::PaymentStatus::COMPLETED); + invoice->setStatus(util::PaymentStatus::PAID); std::string title, message; title = "Payment successful"; message = "Payment successful for Invoice ID " + invoiceID; @@ -384,4 +384,48 @@ void PaymentManagementService::completePayment(const std::string& invoiceID, uti { throw std::runtime_error("Payment failed: invalid invoice ID."); } +} + +/* +Function: getAllInvoice +Description: Provides access to all invoices stored in the data store. +Parameters: + - none +Returns: + - util::Map&: Map of invoice IDs to invoice objects +*/ +util::Map& PaymentManagementService::getAllInvoices() +{ + return m_dataStore.getInvoices(); +} + +/* +Function: confirmPayment +Description: Confirms payment for a specific invoice. Updates payment date and status, + then sends a notification to the customer. +Parameters: + - invoiceID: std::string, ID of the invoice to confirm +Returns: + - void +Throws: + - std::runtime_error if the invoice ID is invalid +*/ +void PaymentManagementService::confirmPayment(const std::string& invoiceID) +{ + auto& currentInvoices = m_dataStore.getInvoices(); + int invoiceIndex = currentInvoices.find(invoiceID); + if (invoiceIndex == -1) + { + throw std::runtime_error("Payment confirmation failed: invalid invoice ID."); + } + Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); + if (!invoice || invoice->getStatus() != util::PaymentStatus::PAID) + { + throw std::runtime_error("Payment confirmation failed: invoice is not awaiting confirmation."); + } + User* currentUser = invoice->getBooking()->getCustomer(); + invoice->setStatus(util::PaymentStatus::COMPLETED); + std::string title = "Payment Confirmed"; + std::string message = "Payment Confirmed for Invoice ID " + invoiceID; + sendNotification(currentUser, title, message); } \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h index 14b8c11..8961a2d 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.h @@ -28,6 +28,8 @@ public: void generateInvoice(ServiceBooking* booking); util::Map getInvoices(const std::string& customerID); void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode); + util::Map& getAllInvoices(); + void confirmPayment(const std::string& invoiceID); void sendPaymentReminders(); void sendNotification(User* user, const std::string& title, const std::string& message) override; void attach(User* user) override; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 5cd870b..1a9f753 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -543,50 +543,65 @@ static void restoreInventory(ServiceBooking* booking) /* 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& jobs - Collection of job cards to update - ServiceManagementService& currentService - Reference to the service for sending notifications +Description: Handles cancellation or reassignment of a service booking based on user type. + Cancels associated job cards, updates booking status, clears technician assignments, + restores inventory, and sends appropriate notifications. +Parameters: + ServiceBooking* booking - The booking to cancel or reset + util::Map& jobs - Collection of job cards to update + ServiceManagementService& currentService - Service layer for notifications + util::UserType userType - Type of user initiating cancellation (CUSTOMER or TECHNICIAN) 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& jobs, ServiceManagementService& currentService) + util::Map& jobs, + ServiceManagementService& currentService, + util::UserType userType) { - if (!booking || !notifyUser) + if (!booking) { return; } for (int jobIterator = 0; jobIterator < jobs.getSize(); ++jobIterator) { JobCard* jobCard = jobs.getValueAt(jobIterator); - if (jobCard && jobCard->getBookingId() == booking->getId()) + if (!jobCard || jobCard->getBookingId() != booking->getId() || jobCard->getStatus() == util::ServiceJobStatus::CANCELLED) { - jobCard->setStatus(jobCardStatus); - currentService.sendNotification(notifyUser, jobNotificationTitle, jobNotificationMessage); + continue; + } + jobCard->setStatus(util::ServiceJobStatus::CANCELLED); + if (userType == util::UserType::CUSTOMER) + { + if (User* technician = booking->getAssignedTechnician()) + { + const std::string jobTitle = "Job Cancelled"; + const std::string jobMessage = "Your job card has been cancelled and the inventory has been restocked."; + currentService.sendNotification(technician, jobTitle, jobMessage); + } } } - booking->setStatus(newServiceBookingStatus); - currentService.sendNotification(notifyUser, notificationTitle, notificationMessage); - if (newServiceBookingStatus == util::ServiceJobStatus::PENDING) + if (userType == util::UserType::CUSTOMER) { - booking->setAssignedTechnician(nullptr); - booking->setAssignedTechnicianId(""); + booking->setStatus(util::ServiceJobStatus::CANCELLED); + if (User* technician = booking->getAssignedTechnician()) + { + const std::string title = "Customer Service Cancelled"; + const std::string message = "Your assigned job card has been cancelled and the inventory has been restocked."; + currentService.sendNotification(technician, title, message); + } } + else if (userType == util::UserType::TECHNICIAN) + { + booking->setStatus(util::ServiceJobStatus::PENDING); + if (User* customer = booking->getCustomer()) + { + const std::string title = "Technician Unavailable"; + const std::string message = "Your booking has been reset to pending and we will reassign a new technician shortly."; + currentService.sendNotification(customer, title, message); + } + } + booking->setAssignedTechnician(nullptr); + booking->setAssignedTechnicianId(""); restoreInventory(booking); } @@ -624,21 +639,13 @@ void ServiceManagementService::cancelCustomerServiceBookings(const std::string& { continue; } - if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED) + if (booking->getStatus() != util::ServiceJobStatus::PENDING && + booking->getStatus() != util::ServiceJobStatus::STARTED && + booking->getStatus() != util::ServiceJobStatus::IN_PROGRESS) { 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 - ); + processBookingCancellation(booking, jobs, *this, util::UserType::CUSTOMER); } } @@ -676,7 +683,9 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia { continue; } - if (booking->getStatus() != util::ServiceJobStatus::PENDING && booking->getStatus() != util::ServiceJobStatus::STARTED) + if (booking->getStatus() != util::ServiceJobStatus::PENDING && + booking->getStatus() != util::ServiceJobStatus::STARTED && + booking->getStatus() != util::ServiceJobStatus::IN_PROGRESS) { continue; } @@ -685,14 +694,7 @@ void ServiceManagementService::cancelTechnicianJobs(const std::string& technicia { 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 - ); + processBookingCancellation(booking, jobs, *this, util::UserType::TECHNICIAN); } } @@ -1080,7 +1082,7 @@ static bool hasCompletedAllJobs(std::string bookingId, util::MapgetBookingId() == bookingId) { - if (currentJob->getStatus() == util::ServiceJobStatus::STARTED) + if (currentJob->getStatus() != util::ServiceJobStatus::COMPLETED && currentJob->getStatus() != util::ServiceJobStatus::CANCELLED) { return false; } @@ -1090,18 +1092,19 @@ static bool hasCompletedAllJobs(std::string bookingId, util::MapgetStatus() == util::ServiceJobStatus::STARTED) { - currentJob->setStatus(util::ServiceJobStatus::COMPLETED); + currentJob->setStatus(util::ServiceJobStatus::IN_PROGRESS); 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 { - 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) { - throw std::runtime_error("Failed to complete the job, some error occurred or job already 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); + throw std::runtime_error("Failed to update job status. Job may already be completed."); } } \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h index 2fdcc93..b2a4384 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h @@ -37,7 +37,7 @@ public: void createService(const std::string& name, const util::Vector& inventoryItemIDs, double laborCost); void removeService(const std::string& serviceID); util::Map getJobCards(const std::string& technicianID); - void completeJob(const std::string& jobID); + void updateJobStatus(const std::string& jobID); void cancelCustomerServiceBookings(const std::string& customerID); void cancelTechnicianJobs(const std::string& technicianID); void createComboPackage(const std::string& packageName, const util::Vector& serviceIDs, double discountPercentage); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h index 16490f1..7585abc 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h @@ -29,7 +29,8 @@ namespace util enum class PaymentStatus { PENDING, - COMPLETED + COMPLETED, + PAID }; enum class ServiceJobStatus @@ -37,6 +38,7 @@ namespace util PENDING, STARTED, COMPLETED, + IN_PROGRESS, CANCELLED }; @@ -160,6 +162,8 @@ namespace util return "PENDING"; case PaymentStatus::COMPLETED: return "COMPLETED"; + case PaymentStatus::PAID: + return "PAID"; } throw std::invalid_argument("Invalid PaymentStatus"); } @@ -209,6 +213,8 @@ namespace util return "COMPLETED"; case ServiceJobStatus::CANCELLED: return "CANCELLED"; + case ServiceJobStatus::IN_PROGRESS: + return "IN_PROGRESS"; } throw std::invalid_argument("Invalid ServiceJobStatus"); } @@ -241,6 +247,10 @@ namespace util { return ServiceJobStatus::CANCELLED; } + if (value == "IN_PROGRESS") + { + return ServiceJobStatus::IN_PROGRESS; + } throw std::invalid_argument("Invalid ServiceJobStatus string"); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Validator.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Validator.cpp index f56d660..e8968d9 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Validator.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Validator.cpp @@ -116,15 +116,13 @@ bool util::isPasswordValid(const std::string& password) * usersMap - map of user objects keyed by identifier * Returns: * bool - true if the username is already in use by an active user, false otherwise - * Notes: - * - Only considers users with state util::State::ACTIVE */ bool util::isUsernameDuplicate(const std::string& username, const util::Map& usersMap) { int index = usersMap.findIf( [&](const std::string&, User* user) { - return (user->getUserName() == username && user->getState() == util::State::ACTIVE); + return (user->getUserName() == username); } ); return index != -1; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp index e7ee48a..76a1901 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp @@ -53,7 +53,8 @@ void AdminMenu::showMenu() << "\n14. Remove Combo Package" << "\n15. View Notifications" << "\n16. Change Password" - << "\n17. Logout" + << "\n17. Confirm Payment" + << "\n18. Logout" << "\nEnter a choice: "; util::read(choice); if (!handleOperation(choice)) @@ -127,7 +128,10 @@ bool AdminMenu::handleOperation(int choice) case 16: changePassword(); break; - case 17: + case 17: + confirmPayment(); + break; + case 18: logout(); return false; default: @@ -496,6 +500,54 @@ void AdminMenu::displayUsers() util::pressEnter(); } +/* +Function: confirmPayment +Description: Confirms payment for a selected invoice. Validates invoice status, updates payment date, + sets status to COMPLETED, and sends a notification to the customer. +Parameters: + - invoiceID: std::string, ID of the invoice to confirm +Returns: + - void +*/ +void AdminMenu::confirmPayment() +{ + util::clear(); + std::cout << "Confirm Payment\n"; + auto invoiceList = m_controller.getAllInvoices(); + if (invoiceList.isEmpty()) + { + std::cout << "No pending invoices available for confirmation."; + util::pressEnter(); + return; + } + bool hasConfirmableInvoice = false; + for (int index = 0; index < invoiceList.getSize(); ++index) + { + const Invoice* invoice = invoiceList.getValueAt(index); + if (invoice && invoice->getStatus() == util::PaymentStatus::PAID) + { + hasConfirmableInvoice = true; + break; + } + } + if (!hasConfirmableInvoice) + { + std::cout << "No invoices awaiting confirmation.\n"; + util::pressEnter(); + return; + } + std::string selectedID = selectInvoiceFromUserForPayment(invoiceList, util::PaymentStatus::PAID); + if (selectedID == "") + { + std::cout << "Payment failed.\n"; + util::pressEnter(); + return; + } + m_controller.confirmPayment(selectedID); + std::cout << "Payment Confirmed successfully.\n"; + util::pressEnter(); +} + /* Function: addTechnician Description: Adds a new technician after validating username, password, email, and phone number. diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.h index 2fe2283..bdffcb6 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.h @@ -28,6 +28,7 @@ public: void createService(); void removeService(); void displayUsers(); + void confirmPayment(); void addTechnician(); void removeUser(); void displayComboPackages(); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 022885f..3e56d99 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -338,7 +338,7 @@ void CustomerMenu::completePayments() util::pressEnter(); return; } - std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices); + std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices, util::PaymentStatus::PENDING); if (selectedID == "") { std::cout << "Payment failed.\n"; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h index f65c1f4..83720c0 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h @@ -364,14 +364,18 @@ inline const User* selectTechnician(util::Map& currentAvailabl } /* -Function: selectInvoiceFromUserForPayment -Description: Lists all pending invoices for the customer and allows selection by index. +Function: selectInvoiceFromUserForPayment +Description: Displays a list of invoices filtered by the required payment status. + Allows the user to select an invoice by index and returns the corresponding invoice ID. Parameters: - - currentInvoices: util::Map&, map of customer invoices + - currentInvoices: const util::Map&, + map of all invoices keyed by invoice ID + - requiredStatus: util::PaymentStatus, + the status to filter invoices (e.g., PENDING, PAID, COMPLETED) Returns: - - std::string: ID of the selected invoice, or empty string if none selected + - std::string: ID of the selected invoice, or empty string if none selected or invalid index */ -inline std::string selectInvoiceFromUserForPayment(const util::Map& currentInvoices) +inline std::string selectInvoiceFromUserForPayment(const util::Map& currentInvoices, util::PaymentStatus requiredStatus) { int currentIndex = 1, choice; util::Map pendingInvoicesForPayment; @@ -389,7 +393,7 @@ inline std::string selectInvoiceFromUserForPayment(const util::MapgetStatus() == util::PaymentStatus::PENDING) + if (currentInvoice && currentInvoice->getStatus() == requiredStatus) { const User* currentTechnician = currentInvoice->getBooking()->getAssignedTechnician(); std::cout << std::left @@ -627,7 +631,6 @@ inline void displayInvoices(util::Map currentUserIn std::cout << "Unable to fetch the selected invoice\n"; doRun = false; } - } while (doRun); } } @@ -646,7 +649,35 @@ inline util::Map filterStartedJobCards(util::MapgetStatus() == util::ServiceJobStatus::STARTED) + if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED || currentJobCard->getStatus() == util::ServiceJobStatus::IN_PROGRESS)) + { + startedJobCards.insert(currentJobCard->getId(), currentJobCard); + } + } + 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& + 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 + A map containing only job cards with the specified status. +*/ +inline util::Map filterJobCards(util::Map& assignedJobCards, util::ServiceJobStatus selectedJobStatus) +{ + util::Map 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); } @@ -675,16 +706,18 @@ inline void displayAllJobs(util::Map& assignedJobCa << 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)) + 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) << currentJobCard->getService()->getName() + << std::setw(20) << util::truncateString(currentJobCard->getService()->getName(), 15) << std::setw(12) << currentJobCard->getServiceId() + << std::setw(12) << util::getServiceJobStatusString(currentJobCard->getStatus()) << std::endl; } } @@ -698,16 +731,31 @@ Parameters: Returns: - std::string: ID of the selected job card, or empty string if none selected */ -inline std::string selectJobCardToComplete(util::Map& assignedJobCards) +inline std::string selectJobCardToUpdate(util::Map& assignedJobCards, util::ServiceJobStatus selectedJobStatusType) { util::Map incompleteJobCards; if (assignedJobCards.getSize() == 0) { - std::cout << "No started jobs available to complete.\n"; + std::cout << "\nNo jobs available.\n\n"; return ""; } int currentIndex = 1; int choice; + if (selectedJobStatusType == util::ServiceJobStatus::STARTED) + { + util::clear(); + std::cout << "Select a job to mark as In Progress\n"; + } + else if (selectedJobStatusType == util::ServiceJobStatus::IN_PROGRESS) + { + util::clear(); + std::cout << "Select a job to mark as Completed\n"; + } + else + { + std::cout << "Unable to update completed or pending jobs.\n\n"; + return ""; + } std::cout << std::endl; std::cout << std::left << std::setw(6) << "Index" @@ -715,22 +763,24 @@ inline std::string selectJobCardToComplete(util::MapgetStatus() == util::ServiceJobStatus::STARTED)) + if (currentJobCard && (currentJobCard->getStatus() == selectedJobStatusType)) { std::cout << std::left << std::setw(6) << currentIndex << std::setw(12) << currentJobCard->getBookingId() << std::setw(12) << currentJobCard->getId() - << std::setw(20) << currentJobCard->getService()->getName() + << std::setw(20) << util::truncateString(currentJobCard->getService()->getName(), 15) << std::setw(12) << currentJobCard->getServiceId() + << std::setw(12) << util::getServiceJobStatusString(currentJobCard->getStatus()) << std::endl; incompleteJobCards.insert(currentIndex++, currentJobCard); } } - std::cout << "Select the Job Card to complete (Index): "; + std::cout << "Enter the job index to update: "; util::read(choice); int selectedJobCardIndex = incompleteJobCards.find(choice); if (selectedJobCardIndex != -1) @@ -741,7 +791,7 @@ inline std::string selectJobCardToComplete(util::Map assignedJobCards = m_controller.getJobCardsByUser(); - util::Map startedJobCards = filterStartedJobCards(assignedJobCards); - displayAllJobs(startedJobCards); + util::Map jobCards = filterStartedJobCards(assignedJobCards); + displayAllJobs(jobCards); util::pressEnter(); } /* -Function: completeJob -Description: Allows the technician to mark a selected job card as completed. +Function: updateJobStatus +Description: Allows the technician to update a selected job card. Validates selection and updates job status through the controller. Parameters: - None Returns: - void */ -void TechnicianMenu::completeJob() +void TechnicianMenu::updateJobStatus() { 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 assignedJobCards = m_controller.getJobCardsByUser(); - util::Map startedJobCards = filterStartedJobCards(assignedJobCards); - std::string selectedJobID = selectJobCardToComplete(startedJobCards); + std::cout << "Select the type of job you want to update:\n1.Started\n2.In Progress\nChoice: "; + 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 selectedTypeJobCard = filterJobCards(assignedJobCards, selectedJobStatus); + selectedJobID = selectJobCardToUpdate(selectedTypeJobCard, selectedJobStatus); if (!selectedJobID.empty()) { - m_controller.completeJob(selectedJobID); - std::cout << "\nJob marked as completed.\n\n"; + m_controller.updateJobStatus(selectedJobID); + std::cout << "\nJob status updated.\n\n"; } util::pressEnter(); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h index d0c5ca9..a17ccb1 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h @@ -18,7 +18,7 @@ private: public: void showMenu(); void displayJobs(); - void completeJob(); + void updateJobStatus(); void viewNotifications(); void logout(); void changePassword(); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.h index 501cfce..4a485de 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.h @@ -27,4 +27,4 @@ public: void run(); void login(); void registerCustomer(); -}; +}; \ No newline at end of file