From aee6356e6f54047db5cedc27721727867199f646 Mon Sep 17 00:00:00 2001 From: Avinash Rajesh Date: Fri, 29 May 2026 13:24:34 +0530 Subject: [PATCH] Implement Confirm Payment Functionality MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Complete Payments - 1797 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. 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. Sreeja Reghukumar --- .../controllers/Controller.cpp | 32 +++++++++++ .../controllers/Controller.h | 2 + .../services/PaymentManagementService.cpp | 52 ++++++++++++++++- .../services/PaymentManagementService.h | 2 + .../utilities/Enums.h | 5 +- .../views/AdminMenu.cpp | 56 ++++++++++++++++++- .../views/AdminMenu.h | 1 + .../views/CustomerMenu.cpp | 2 +- .../views/MenuHelper.h | 16 ++++-- 9 files changed, 156 insertions(+), 12 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index d27635e..5d35aa1 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -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.getAllInvoice(); + 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(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 a0a70bc..b045dec 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -64,6 +64,8 @@ public: 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(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..c28d31c 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,52 @@ 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::getAllInvoice() +{ + 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(std::string invoiceID) +{ + std::string title, message; + auto& currentInvoices = m_dataStore.getInvoices(); + int invoiceIndex = currentInvoices.find(invoiceID); + if (invoiceIndex != -1) + { + Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); + if (invoice && invoice->getStatus() != util::PaymentStatus::COMPLETED) + { + User* currentUser = invoice->getBooking()->getCustomer(); + invoice->setPaymentDate(util::Timestamp()); + invoice->setStatus(util::PaymentStatus::COMPLETED); + title = "Payment Confirmed"; + message = "Payment Confirmed for Invoice ID " + invoiceID; + sendNotification(currentUser, title, message); + } + } + else + { + throw std::runtime_error("Payment failed: invalid invoice ID."); + } } \ 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..79d525a 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& getAllInvoice(); + void confirmPayment(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/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h index c167b28..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 @@ -161,6 +162,8 @@ namespace util return "PENDING"; case PaymentStatus::COMPLETED: return "COMPLETED"; + case PaymentStatus::PAID: + return "PAID"; } throw std::invalid_argument("Invalid PaymentStatus"); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/AdminMenu.cpp index e7ee48a..85a890a 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 PAID, 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 hasPaidInvoice = false; + for (int index = 0; index < invoiceList.getSize(); ++index) + { + const Invoice* invoice = invoiceList.getValueAt(index); + if (invoice && invoice->getStatus() == util::PaymentStatus::PAID) + { + hasPaidInvoice = true; + break; + } + } + if (!hasPaidInvoice) + { + std::cout << "No pending invoices available for payment.\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 0a4136a..372b003 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