From cb3bed4050e54dc8a4b300aecb0388733c97a885 Mon Sep 17 00:00:00 2001 From: Jissin Mathew Date: Wed, 20 May 2026 17:48:41 +0530 Subject: [PATCH] Implement Complete Payments PAY002: Complete Payments 1. Integrated Controller with PaymentManagementService to support payment completion workflow. 2. Implemented PaymentManagementService::completePayment with validation for invoice ID, payment mode, and status update. 3. Enhanced CustomerMenu with helper functions to display pending invoices in tabular format and allow index-based selection. 4. Added CustomerMenu::selectPaymentMode to capture payment mode choice (OFFLINE/ONLINE). 5. Updated CustomerMenu::completePayments to handle invoice selection, payment mode input, and trigger payment completion via Controller. 6. Implemented notification logic to send confirmation to customers upon successful payment. Acceptance Criteria: 1. Payment status marked completed. 2. Confirmation message shown. 3. Confirmation notification sent. Precondition: 1. Customer is logged into the system. 2. At least one pending invoice exists for the customer. 3. Datastore is available for storing invoices and updating payment status. Steps: 1. Navigate to Customer menu and choose "Complete Payments". - Verify that the system lists pending invoices with tabular details. 2. Select an invoice by index. - Verify that the chosen invoice is retrieved correctly. 3. Enter payment mode (OFFLINE/ONLINE). - Verify that the selected mode is applied to the invoice. 4. Confirm payment completion. - Verify that the invoice status changes to COMPLETED. - Verify that a confirmation message is displayed. - Verify that a notification is sent to the customer. Sreeja Reghukumar, please review --- .../controllers/Controller.cpp | 13 ++- .../controllers/Controller.h | 5 + .../models/ServiceBooking.cpp | 6 +- .../models/ServiceBooking.h | 8 +- .../services/PaymentManagementService.cpp | 41 ++++++++ .../views/CustomerMenu.cpp | 95 +++++++++++++++++++ 6 files changed, 160 insertions(+), 8 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index d536e8a..97a2b90 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -1,4 +1,6 @@ #include "Controller.h" +#include "User.h" +#include "Invoice.h" bool Controller::login(const std::string& username, const std::string& password) { @@ -121,11 +123,20 @@ void Controller::removeComboPackage(const std::string& comboPackageID) util::Map Controller::getInvoicesByUser() { - return util::Map(); + User* currentUser = m_authenticationManagementService.getAuthenticatedUser(); + util::Map currentUserInvoices = m_paymentManagementService.getInvoices(currentUser->getId()); + util::Map userInvoicesReadOnly; + for (int iterator = 0; iterator < currentUserInvoices.getSize(); iterator++) + { + Invoice* currentInvoice = currentUserInvoices.getValueAt(iterator); + userInvoicesReadOnly.insert(currentInvoice->getId(), currentInvoice); + } + return userInvoicesReadOnly; } void Controller::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode) { + m_paymentManagementService.completePayment(invoiceID, paymentMode); } util::Vector Controller::getNotifications() diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index 3aabb58..874d10a 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -2,6 +2,8 @@ #include "Map.h" #include #include "Enums.h" +#include "PaymentManagementService.h" +#include "AuthenticationManagementService.h" class Service; class ComboPackage; @@ -14,6 +16,9 @@ class Notification; class Controller { +private: + AuthenticationManagementService m_authenticationManagementService; + PaymentManagementService m_paymentManagementService; public: bool login(const std::string& username, const std::string& password); void logout(); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp index 1fdfaf0..aeb7f4d 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.cpp @@ -18,7 +18,7 @@ ServiceBooking::ServiceBooking( const std::string& vehicleBrand, const std::string& vehicleModel, const std::string& assignedTechnicianId, - const std::string& assignedTechnician, + const User* assignedTechnician, double discountPercentage ) : m_id("SRV" + std::to_string(++m_uid)), @@ -80,7 +80,7 @@ const std::string& ServiceBooking::getAssignedTechnicianId() const return m_assignedTechnicianId; } -const std::string& ServiceBooking::getAssignedTechnician() const +const User* ServiceBooking::getAssignedTechnician() const { return m_assignedTechnician; } @@ -135,7 +135,7 @@ void ServiceBooking::setAssignedTechnicianId(const std::string& assignedTechnici m_assignedTechnicianId = assignedTechnicianId; } -void ServiceBooking::setAssignedTechnician(const std::string& assignedTechnician) +void ServiceBooking::setAssignedTechnician(const User* assignedTechnician) { m_assignedTechnician = assignedTechnician; } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h index 5ecc1b0..8996d36 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/ServiceBooking.h @@ -19,7 +19,7 @@ private: std::string m_vehicleBrand; std::string m_vehicleModel; std::string m_assignedTechnicianId; - std::string m_assignedTechnician; + const User* m_assignedTechnician; double m_discountPercentage; public: ServiceBooking(); @@ -34,7 +34,7 @@ public: const std::string& vehicleBrand, const std::string& vehicleModel, const std::string& assignedTechnicianId, - const std::string& assignedTechnician, + const User* assignedTechnician, double discountPercentage ); const std::string& getId() const; @@ -46,7 +46,7 @@ public: const std::string& getVehicleBrand() const; const std::string& getVehicleModel() const; const std::string& getAssignedTechnicianId() const; - const std::string& getAssignedTechnician() const; + const User* getAssignedTechnician() const; double getDiscountPercentage() const; void setId(const std::string& id); void setStatus(const util::ServiceJobStatus& status); @@ -57,6 +57,6 @@ public: void setVehicleBrand(const std::string& vehicleBrand); void setVehicleModel(const std::string& vehicleModel); void setAssignedTechnicianId(const std::string& assignedTechnicianId); - void setAssignedTechnician(const std::string& assignedTechnician); + void setAssignedTechnician(const User* assignedTechnician); void setDiscountPercentage(double discountPercentage); }; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 786ebcf..185c362 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -1 +1,42 @@ #include "PaymentManagementService.h" +#include "Invoice.h" +#include "Enums.h" +#include "ServiceBooking.h" +#include "Timestamp.h" + +util::Map PaymentManagementService::getInvoices(const std::string& customerID) +{ + util::Map& currentInvoices = m_dataStore.getInvoices(); + util::Map currentUserInvoices; + for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++) + { + Invoice* currentInvoice = currentInvoices.getValueAt(iterator); + if (currentInvoice->getBooking()->getCustomerId() == customerID) + { + currentUserInvoices.insert(currentInvoice->getId(), currentInvoice); + } + } + return currentUserInvoices; +} + +void PaymentManagementService::completePayment(const std::string& invoiceID, util::PaymentMode paymentMode) +{ + auto& currentInvoices = m_dataStore.getInvoices(); + int invoiceIndex = currentInvoices.find(invoiceID); + if (invoiceIndex != -1) + { + Invoice* invoice = currentInvoices.getValueAt(invoiceIndex); + User* currentUser = invoice->getBooking()->getCustomer(); + invoice->setPaymentMethod(paymentMode); + invoice->setPaymentDate(util::Timestamp()); + invoice->setStatus(util::PaymentStatus::COMPLETED); + std::string title, message; + title = "Payment successful"; + message = "Payment successful 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/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp index 047f471..3a18df4 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp @@ -1,6 +1,13 @@ +#include +#include #include "CustomerMenu.h" #include "InputHelper.h" #include "OutputHelper.h" +#include "Invoice.h" +#include "Enums.h" +#include "ServiceBooking.h" +#include "User.h" +#include "Timestamp.h" void CustomerMenu::showMenu() { @@ -55,8 +62,96 @@ void CustomerMenu::viewServiceHistory() { } +static std::string selectInvoiceFromUserForPayment(const util::Map& currentInvoices) +{ + int currentIndex = 1, choice; + util::Map pendingInvoicesForPayment; + std::cout << std::left + << std::setw(6) << "Index" + << std::setw(12) << "BookingID" + << std::setw(15) << "VehicleBrand" + << std::setw(15) << "VehicleNumber" + << std::setw(12) << "TechID" + << std::setw(20) << "TechnicianName" + << std::setw(10) << "Discount(%)" + << std::setw(12) << "TotalAmount" + << std::setw(20) << "InvoiceDate" + << std::endl; + for (int iterator = 0; iterator < currentInvoices.getSize(); iterator++) + { + const Invoice* currentInvoice = currentInvoices.getValueAt(iterator); + if (currentInvoice && currentInvoice->getStatus() == util::PaymentStatus::PENDING) + { + std::cout << std::left + << std::setw(6) << currentIndex + << std::setw(12) << currentInvoice->getBookingId() + << std::setw(15) << currentInvoice->getBooking()->getVehicleBrand() + << std::setw(15) << currentInvoice->getBooking()->getVehicleNumber() + << std::setw(12) << currentInvoice->getBooking()->getAssignedTechnician()->getId() + << std::setw(20) << currentInvoice->getBooking()->getAssignedTechnician()->getName() + << std::setw(10) << currentInvoice->getDiscountPercentage() + << std::setw(12) << currentInvoice->getTotalAmount() + << std::setw(20) << currentInvoice->getInvoiceDate().toString() + << std::endl; + pendingInvoicesForPayment.insert(currentIndex++, currentInvoice); + } + } + if (pendingInvoicesForPayment.getSize() == 0) + { + std::cout << "No pending invoices available for payment.\n"; + return ""; + } + std::cout << "Select the Invoice to pay (Index): "; + util::read(choice); + int selectedIndex = pendingInvoicesForPayment.find(choice); + if (selectedIndex != -1) + { + const Invoice* selectedInvoice = pendingInvoicesForPayment.getValueAt(selectedIndex); + return selectedInvoice->getId(); + } + else + { + std::cout << "Invalid choice.\n"; + return ""; + } +} + +static util::PaymentMode selectPaymentMode() +{ + int choice; + std::cout << "Enter the payment Mode\n1.OFFLINE\n2.ONLINE\nChoice: "; + util::read(choice); + if (choice == 1) + { + std::cout << "Offline mode selected.\n"; + return util::PaymentMode::OFFLINE; + } + else if (choice == 2) + { + std::cout << "Online mode selected.\n"; + return util::PaymentMode::ONLINE; + } + else + { + std::cout << "Invalid choice, Offline mode selected.\n"; + return util::PaymentMode::OFFLINE; + } +} + void CustomerMenu::completePayments() { + util::clear(); + int paymentModeChoice; + util::Map currentInvoices = m_controller.getInvoicesByUser(); + std::string selectedID = selectInvoiceFromUserForPayment(currentInvoices); + if (selectedID == "") + { + std::cout << "Payment failed.\n"; + return; + } + util::PaymentMode paymentMode = selectPaymentMode(); + m_controller.completePayment(selectedID, paymentMode); + std::cout << "Payment completed successfully.\n"; } void CustomerMenu::viewInvoices()