Compare commits

..

1 Commits

Author SHA1 Message Date
Avinash Rajesh 931aa4c406 Implement Confirm Payment Functionality
<User Story> Complete Payments - 1797</User Story>

<Changes>
1. Added Controller::getAllInvoices
   - Retrieves all invoices from PaymentManagementService and returns them as a read-only map.
2. Implemented Controller::confirmPayment
   - Delegates payment confirmation for a given invoice ID to PaymentManagementService.
3. Introduced PaymentManagementService::getAllInvoice
   - Provides access to all invoices stored in the datastore.
4. Added PaymentManagementService::confirmPayment
   - Confirms payment for a specific invoice, updates payment date and status, and sends notification.
5. Extended util::PaymentStatus enum
   - Added PAID status and updated string conversion.
6. Integrated AdminMenu::confirmPayment
   - Validates invoice list, filters by status, allows selection, and confirms payment.
7. Updated CustomerMenu::completePayments
   - Uses parameterized status filtering for invoice selection.
8. Enhanced MenuHelper::selectInvoiceFromUserForPayment
   - Accepts requiredStatus parameter for flexible filtering.
9. Adjusted AdminMenu options
   - Added "Confirm Payment" before Logout.
</Changes>

<Test>
Acceptance Criteria:
1. Admin selects "Confirm Payment" from menu.
   - Verify system prompts and displays invoices filtered by status.
2. Admin selects invoice with status = PAID.
   - Verify payment confirmation updates date, sets status, and sends notification.
3. Admin attempts confirmation with empty invoice list.
   - Verify error message: "No pending invoices available for confirmation."
4. Customer completes payment.
   - Verify selection uses util::PaymentStatus::PENDING and payment flow works correctly.
5. Invalid invoice ID entered.
   - Verify system throws runtime_error with "Payment failed: invalid invoice ID."

Precondition:
1. Admin logged into system.
2. At least one invoice exists in datastore.
3. Notification system available.

Steps:
1. Navigate to Admin menu → Confirm Payment.
2. Select invoice with PAID status.
3. Confirm payment and check notification.
4. Attempt with empty invoice list.
5. Attempt with invalid invoice ID.
</Test>

<Review>
Sreeja Reghukumar
</Review>
2026-05-29 13:24:34 +05:30
12 changed files with 77 additions and 150 deletions
@@ -392,9 +392,9 @@ Parameters:
Returns: Returns:
- void - void
*/ */
void Controller::updateJobStatus(const std::string& jobID) void Controller::completeJob(const std::string& jobID)
{ {
m_serviceManagementService.updateJobStatus(jobID); m_serviceManagementService.completeJob(jobID);
} }
/* /*
@@ -472,7 +472,7 @@ Returns:
*/ */
util::Map<std::string, const Invoice*> Controller::getAllInvoices() util::Map<std::string, const Invoice*> Controller::getAllInvoices()
{ {
auto invoices = m_paymentManagementService.getAllInvoices(); auto invoices = m_paymentManagementService.getAllInvoice();
util::Map<std::string, const Invoice*> readOnlyInvoice; util::Map<std::string, const Invoice*> readOnlyInvoice;
for (int iterator = 0; iterator < invoices.getSize(); iterator++) for (int iterator = 0; iterator < invoices.getSize(); iterator++)
{ {
@@ -489,7 +489,7 @@ Parameters:
Returns: Returns:
- void - void
*/ */
void Controller::confirmPayment(const std::string& invoiceID) void Controller::confirmPayment(std::string invoiceID)
{ {
m_paymentManagementService.confirmPayment(invoiceID); m_paymentManagementService.confirmPayment(invoiceID);
} }
@@ -59,13 +59,13 @@ 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 updateJobStatus(const std::string& jobID); void completeJob(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);
util::Map<std::string, const Invoice*> getInvoicesByUser(); util::Map<std::string, const Invoice*> getInvoicesByUser();
util::Map<std::string, const Invoice*> getAllInvoices(); util::Map<std::string, const Invoice*> getAllInvoices();
void confirmPayment(const std::string& invoiceID); void confirmPayment(std::string invoiceID);
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode); void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
util::Vector<const Notification*> getNotifications(); util::Vector<const Notification*> getNotifications();
void deleteNotification(const std::string& notificationID); void deleteNotification(const std::string& notificationID);
@@ -394,7 +394,7 @@ Parameters:
Returns: Returns:
- util::Map<std::string, Invoice*>&: Map of invoice IDs to invoice objects - util::Map<std::string, Invoice*>&: Map of invoice IDs to invoice objects
*/ */
util::Map<std::string, Invoice*>& PaymentManagementService::getAllInvoices() util::Map<std::string, Invoice*>& PaymentManagementService::getAllInvoice()
{ {
return m_dataStore.getInvoices(); return m_dataStore.getInvoices();
} }
@@ -410,22 +410,26 @@ Returns:
Throws: Throws:
- std::runtime_error if the invoice ID is invalid - std::runtime_error if the invoice ID is invalid
*/ */
void PaymentManagementService::confirmPayment(const std::string& invoiceID) void PaymentManagementService::confirmPayment(std::string invoiceID)
{ {
std::string title, message;
auto& currentInvoices = m_dataStore.getInvoices(); auto& currentInvoices = m_dataStore.getInvoices();
int invoiceIndex = currentInvoices.find(invoiceID); int invoiceIndex = currentInvoices.find(invoiceID);
if (invoiceIndex == -1) if (invoiceIndex != -1)
{ {
throw std::runtime_error("Payment confirmation failed: invalid invoice ID."); Invoice* invoice = currentInvoices.getValueAt(invoiceIndex);
if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED)
{
User* currentUser = invoice->getBooking()->getCustomer();
invoice->setPaymentDate(util::Timestamp());
invoice->setStatus(util::PaymentStatus::COMPLETED);
title = "Payment Confirmed";
message = "Payment Confirmed for Invoice ID " + invoiceID;
sendNotification(currentUser, title, message);
}
} }
Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); else
if (!invoice || invoice->getStatus() != util::PaymentStatus::PAID)
{ {
throw std::runtime_error("Payment confirmation failed: invoice is not awaiting confirmation."); throw std::runtime_error("Payment failed: invalid invoice ID.");
} }
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);
} }
@@ -28,8 +28,8 @@ public:
void generateInvoice(ServiceBooking* booking); void generateInvoice(ServiceBooking* booking);
util::Map<std::string, Invoice*> getInvoices(const std::string& customerID); util::Map<std::string, Invoice*> getInvoices(const std::string& customerID);
void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode); void completePayment(const std::string& invoiceID, util::PaymentMode paymentMode);
util::Map<std::string, Invoice*>& getAllInvoices(); util::Map<std::string, Invoice*>& getAllInvoice();
void confirmPayment(const std::string& invoiceID); void confirmPayment(std::string invoiceID);
void sendPaymentReminders(); void sendPaymentReminders();
void sendNotification(User* user, const std::string& title, const std::string& message) override; void sendNotification(User* user, const std::string& title, const std::string& message) override;
void attach(User* user) override; void attach(User* user) override;
@@ -1080,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::COMPLETED && currentJob->getStatus() != util::ServiceJobStatus::CANCELLED) if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
{ {
return false; return false;
} }
@@ -1090,19 +1090,18 @@ static bool hasCompletedAllJobs(std::string bookingId, util::Map<std::string, Jo
} }
/* /*
Function: updateJobStatus Function: completeJob
Description: Description: Marks a job card as completed for the authenticated technician.
Updates the status of a job card assigned to the currently authenticated technician. If all job cards in the booking are completed, marks the booking as completed
- If the job is STARTED, it moves to IN_PROGRESS. and generates an invoice.
- 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: const std::string&, unique identifier of the job card to update. - jobID: std::string, ID of the job card
Returns: Returns:
- void - void
Throws:
- std::runtime_error if technician is not authenticated, job card not found, or job already completed
*/ */
void ServiceManagementService::updateJobStatus(const std::string& jobID) void ServiceManagementService::completeJob(const std::string& jobID)
{ {
AuthenticationManagementService authenticationManagementService; AuthenticationManagementService authenticationManagementService;
PaymentManagementService paymentManagementService; PaymentManagementService paymentManagementService;
@@ -1127,30 +1126,26 @@ void ServiceManagementService::updateJobStatus(const std::string& jobID)
} }
if (currentJob->getStatus() == util::ServiceJobStatus::STARTED) if (currentJob->getStatus() == util::ServiceJobStatus::STARTED)
{ {
currentJob->setStatus(util::ServiceJobStatus::IN_PROGRESS); currentJob->setStatus(util::ServiceJobStatus::COMPLETED);
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 update job status. Job may already be completed."); throw std::runtime_error("Failed to complete the job, some error occurred or job already completed.");
} }
if (!jobStatusUpdated) if (!jobStatusUpdated)
{ {
throw std::runtime_error("Failed to update job status. Job may already be completed."); 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);
} }
} }
@@ -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 updateJobStatus(const std::string& jobID); void completeJob(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);
@@ -38,7 +38,6 @@ namespace util
PENDING, PENDING,
STARTED, STARTED,
COMPLETED, COMPLETED,
IN_PROGRESS,
CANCELLED CANCELLED
}; };
@@ -213,8 +212,6 @@ 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");
} }
@@ -247,10 +244,6 @@ 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");
} }
@@ -503,7 +503,7 @@ void AdminMenu::displayUsers()
/* /*
Function: confirmPayment Function: confirmPayment
Description: Confirms payment for a selected invoice. Validates invoice status, updates payment date, Description: Confirms payment for a selected invoice. Validates invoice status, updates payment date,
sets status to COMPLETED, and sends a notification to the customer. sets status to PAID, and sends a notification to the customer.
Parameters: Parameters:
- invoiceID: std::string, ID of the invoice to confirm - invoiceID: std::string, ID of the invoice to confirm
Returns: Returns:
@@ -520,19 +520,19 @@ void AdminMenu::confirmPayment()
util::pressEnter(); util::pressEnter();
return; return;
} }
bool hasConfirmableInvoice = false; bool hasPaidInvoice = false;
for (int index = 0; index < invoiceList.getSize(); ++index) for (int index = 0; index < invoiceList.getSize(); ++index)
{ {
const Invoice* invoice = invoiceList.getValueAt(index); const Invoice* invoice = invoiceList.getValueAt(index);
if (invoice && invoice->getStatus() == util::PaymentStatus::PAID) if (invoice && invoice->getStatus() == util::PaymentStatus::PAID)
{ {
hasConfirmableInvoice = true; hasPaidInvoice = true;
break; break;
} }
} }
if (!hasConfirmableInvoice) if (!hasPaidInvoice)
{ {
std::cout << "No invoices awaiting confirmation.\n"; std::cout << "No pending invoices available for payment.\n";
util::pressEnter(); util::pressEnter();
return; return;
} }
@@ -631,6 +631,7 @@ 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);
} }
} }
@@ -649,35 +650,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 || currentJobCard->getStatus() == util::ServiceJobStatus::IN_PROGRESS)) if (currentJobCard && currentJobCard->getStatus() == util::ServiceJobStatus::STARTED)
{
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<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); startedJobCards.insert(currentJobCard->getId(), currentJobCard);
} }
@@ -706,18 +679,16 @@ inline void displayAllJobs(util::Map<std::string, const JobCard*>& assignedJobCa
<< 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) << "Status"
<< 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 || currentJobCard->getStatus() == util::ServiceJobStatus::IN_PROGRESS)) if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED))
{ {
std::cout << std::left << std::setw(12) << currentJobCard->getBookingId() std::cout << std::left << std::setw(12) << currentJobCard->getBookingId()
<< std::setw(12) << currentJobCard->getId() << std::setw(12) << currentJobCard->getId()
<< std::setw(20) << util::truncateString(currentJobCard->getService()->getName(), 15) << std::setw(20) << currentJobCard->getService()->getName()
<< std::setw(12) << currentJobCard->getServiceId() << std::setw(12) << currentJobCard->getServiceId()
<< std::setw(12) << util::getServiceJobStatusString(currentJobCard->getStatus())
<< std::endl; << std::endl;
} }
} }
@@ -731,31 +702,16 @@ Parameters:
Returns: Returns:
- std::string: ID of the selected job card, or empty string if none selected - std::string: ID of the selected job card, or empty string if none selected
*/ */
inline std::string selectJobCardToUpdate(util::Map<std::string, const JobCard*>& assignedJobCards, util::ServiceJobStatus selectedJobStatusType) inline std::string selectJobCardToComplete(util::Map<std::string, const JobCard*>& assignedJobCards)
{ {
util::Map<int, const JobCard* > incompleteJobCards; util::Map<int, const JobCard* > incompleteJobCards;
if (assignedJobCards.getSize() == 0) if (assignedJobCards.getSize() == 0)
{ {
std::cout << "\nNo jobs available.\n\n"; std::cout << "No started jobs available to complete.\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 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::endl;
std::cout << std::left std::cout << std::left
<< std::setw(6) << "Index" << std::setw(6) << "Index"
@@ -763,24 +719,22 @@ inline std::string selectJobCardToUpdate(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() == selectedJobStatusType)) if (currentJobCard && (currentJobCard->getStatus() == util::ServiceJobStatus::STARTED))
{ {
std::cout << std::left << std::setw(6) << currentIndex std::cout << std::left << std::setw(6) << currentIndex
<< std::setw(12) << currentJobCard->getBookingId() << std::setw(12) << currentJobCard->getBookingId()
<< std::setw(12) << currentJobCard->getId() << std::setw(12) << currentJobCard->getId()
<< std::setw(20) << util::truncateString(currentJobCard->getService()->getName(), 15) << std::setw(20) << currentJobCard->getService()->getName()
<< 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 << "Enter the job index to update: "; std::cout << "Select the Job Card to complete (Index): ";
util::read(choice); util::read(choice);
int selectedJobCardIndex = incompleteJobCards.find(choice); int selectedJobCardIndex = incompleteJobCards.find(choice);
if (selectedJobCardIndex != -1) if (selectedJobCardIndex != -1)
@@ -791,7 +745,7 @@ inline std::string selectJobCardToUpdate(util::Map<std::string, const JobCard*>&
else else
{ {
std::cout << "Invalid index.\n"; std::cout << "Invalid index.\n";
std::cout << "Failed to update job.\n\n"; std::cout << "Failed to complete jobs.\n\n";
return ""; return "";
} }
} }
@@ -35,7 +35,7 @@ void TechnicianMenu::showMenu()
util::clear(); util::clear();
std::cout << "Technician Menu" std::cout << "Technician Menu"
<< "\n1. Display My Jobs" << "\n1. Display My Jobs"
<< "\n2. Update Job Status" << "\n2. Mark Job as Completed"
<< "\n3. View Notifications" << "\n3. View Notifications"
<< "\n4. Change Password" << "\n4. Change Password"
<< "\n5. Logout" << "\n5. Logout"
@@ -68,7 +68,7 @@ bool TechnicianMenu::handleOperation(int choice)
displayJobs(); displayJobs();
break; break;
case 2: case 2:
updateJobStatus(); completeJob();
break; break;
case 3: case 3:
viewNotifications(); viewNotifications();
@@ -99,50 +99,31 @@ void TechnicianMenu::displayJobs()
util::clear(); util::clear();
std::cout << "My Jobs\n"; std::cout << "My Jobs\n";
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*> jobCards = filterStartedJobCards(assignedJobCards); util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
displayAllJobs(jobCards); displayAllJobs(startedJobCards);
util::pressEnter(); util::pressEnter();
} }
/* /*
Function: updateJobStatus Function: completeJob
Description: Allows the technician to update a selected job card. Description: Allows the technician to mark a selected job card as completed.
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::updateJobStatus() void TechnicianMenu::completeJob()
{ {
util::clear(); util::clear();
std::cout << "Update Job Status\n"; std::cout << "Complete Job\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();
std::cout << "Select the type of job you want to update:\n1.Started\n2.In Progress\nChoice: "; util::Map<std::string, const JobCard*> startedJobCards = filterStartedJobCards(assignedJobCards);
util::read(choice); std::string selectedJobID = selectJobCardToComplete(startedJobCards);
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.updateJobStatus(selectedJobID); m_controller.completeJob(selectedJobID);
std::cout << "\nJob status updated.\n\n"; std::cout << "\nJob marked as completed.\n\n";
} }
util::pressEnter(); util::pressEnter();
} }
@@ -18,7 +18,7 @@ private:
public: public:
void showMenu(); void showMenu();
void displayJobs(); void displayJobs();
void updateJobStatus(); void completeJob();
void viewNotifications(); void viewNotifications();
void logout(); void logout();
void changePassword(); void changePassword();