<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>
Changes:
- Refactored customer and technician removal flow:
- Ensured linked job cards and service bookings are properly cancelled.
- Centralized cancellation logic with processBookingCancellation helper for consistent notifications, technician reassignment, and inventory restoration.
- Prevented duplicate inventory restocking during customer removal.
- Preserved customer references and IDs correctly during booking cancellation.
- Admin inventory management improvements:
- Added heading output to Remove Inventory Item submenu for clearer context.
- Prevented service creation with empty inventory selection by adding validation and early return.
- Improved combo package creation by simplifying null checks with modern idioms.
- Enhanced inventory selection flow:
- Clear screen and context header for better UX.
- Prevent duplicate item selection by checking already chosen items.
- Changed exit option from -1 to 0 for consistency.
- Added pressEnter prompt after successful item addition.
- Simplified pointer checks using concise conditions (e.g., if (item)).
- User management UI fix:
- Updated active user display in Remove User menu to include Full Name column, ensuring administrators have complete visibility when managing users.
Fixes#1788Fixes#1778Fixes#1781
Related work items: #1778, #1781, #1788
- Updated sendNotification in InventoryManagementService, PaymentManagementService, and ServiceManagementService to use only the provided title instead of prefixing with service name.
- Added "View Service History" header in CustomerMenu::viewServiceHistory for clarity.
- Adjusted column widths in service history table for better alignment:
- Booking ID column widened to 15.
- Vehicle Brand, Vehicle Number, Vehicle Model, Discount %, and Status columns widened to 20.
- Updated output formatting in CustomerMenu::viewServiceHistory to match new widths.
- Added "View and Delete Notification" header in MenuHelper::viewAndDeleteNotification for clarity.
- Moved empty notification validation from selectNotification to viewAndDeleteNotification:
- Displays "No notifications available." message.
- Added util::pressEnter() prompt before returning when no notifications exist.
- Increased Notification title column width from 30 to 35 in selectNotification for improved readability.
Fixes#1748
Changes:
1. Added missing include for MenuHelper.h in project, AdminMenu, and CustomerMenu.
2. Updated PaymentManagementService::completePayment to guard against duplicate completion by checking status before updating.
3. Enhanced ServiceManagementService::createJobCard with null checks for inventory items and safe stock decrement logic.
4. Added null check for job card creation in ServiceManagementService and throw runtime error if creation fails.
5. Refactored ServiceManagementService::removeService to use m_dataStore.getServices() reference instead of getServices() copy.
6. Renamed helper function hasAllJobCardsinServiceBookingCompleted to hasCompletedAllJobs for clarity and updated usage in completeJob.
7. Fixed ServiceJobStatus string conversion in Enums.h to correctly return "PENDING" instead of "STARTED".
8. Added support for parsing "PENDING" string to ServiceJobStatus::PENDING in Enums.h.
9. Cleaned up AdminMenu.cpp by removing redundant static helper functions (listServiceBookings, selectPendingServiceBookings, listAvailableTechnicians, selectTechnician, selectInventoryItems, selectServicesToRemove).
10. Replaced removed helpers with shared MenuHelper usage and added util::pressEnter() calls for consistent user flow.
11. Simplified CustomerMenu.cpp by removing redundant static helpers (selectInvoiceFromUserForPayment, selectPaymentMode, displayInvoices) and moved logic to shared helpers.
12. General formatting and comment cleanup across AdminMenu.cpp and CustomerMenu.cpp for consistency.
Changes:
- Added name parameter to createTechnician for consistency
- Added function headers for notification-related methods in InventoryManagementService
- Used variables for notification title and message instead of passing strings directly
- Fixed payment reminder notification message formatting
- Moved common helper functions to MenuHelper.h
- Updated CustomerMenu to use shared helper functions instead of duplicate code
- Added missing includes in MenuHelper.h
- Removed redundant helper code from CustomerMenu.cpp
- Minor formatting and comment cleanup
- Add serialize/deserialize support for core models
- Add file-based load/save functions in management services
- Introduce FileManager, Config, Utility and helper utilities
- Persist observer IDs for notification services
- Resolve object relationships during load (services, bookings, invoices, job cards)
- Add controller-level loadSystemData/saveSystemData
- Load data at app startup and save on shutdown
<UserStory> PAY001: Generate Invoice </UserStory>
<Changes>
1. Added Utility.h to project configuration for supporting invoice generation utilities.
2. Updated Invoice model to use string-based keys for parts mapping instead of integer keys.
3. Implemented PaymentManagementService::generateInvoice to aggregate labour cost, parts cost, and apply discounts.
4. Integrated invoice creation with Factory to instantiate Invoice objects and persist them into datastore.
5. Enhanced Enums with PaymentMode::NOTSET to handle default invoice state.
</Changes>
<Test>
Acceptance Criteria:
1. Invoice auto-generates for each service booking once jobs are completed.
2. Invoice shows a clear breakdown of charges including labour cost, parts cost, discount, and total amount.
Precondition:
1. Service booking exists with at least one service and required inventory items.
2. Datastore is available for storing invoices.
3. Payment mode and status enums are properly configured.
Steps:
1. Complete all jobs in a service booking.
- Verify that PaymentManagementService::generateInvoice is triggered.
2. Check datastore for newly created invoice.
- Verify that invoice contains booking ID, labour cost, parts cost, discount, and total amount.
3. Inspect invoice details.
- Verify that breakdown of charges is accurate and discount is applied correctly.
4. Confirm invoice status.
- Verify that invoice is created with PaymentMode::NOTSET and PaymentStatus::PENDING.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> PAY002: Complete Payments </UserStory>
<Changes>
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.
</Changes>
<Test>
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.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory>
NOT005: Payment Reminder
</UserStory>
<Changes>
1. Added payment reminder check in Controller::runSystemChecks() to trigger reminder processing during system startup.
2. Implemented PaymentManagementService::sendPaymentReminders() to identify unpaid invoices that exceed the pending payment threshold and send reminder notifications to customers.
3. Added reminder notification logic to include invoice details and stop reminders once invoice payment status changes from Pending to Paid.
</Changes>
<Test>
Precondition:
1. Customer has an invoice with PaymentStatus::PENDING.
2. Invoice age exceeds the configured payment reminder threshold.
3. Application is started and system checks execute.
Steps:
1. Start the application.
2. Allow system checks to run during startup.
3. Navigate to View Notifications.
- Verify that a payment reminder notification is displayed.
4. Open the generated notification.
- Verify that the notification includes the invoice ID and due date.
5. Complete payment for the invoice and restart the application.
- Verify that no further reminder notifications are generated for the paid invoice.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> NOT006: Configure Notifications </UserStory>
<Changes>
1. Added notification subscription configuration in CustomerMenu to allow customers to enable or disable notifications for Payment Management Service and Service Management Service.
2. Updated Controller::configureNotifications() to attach or detach the authenticated user from service observers based on selected notification preferences.
3. Refactored Observer interface and User notification handling to support notification delivery through observer subscriptions.
4. Implemented observer attach, detach, and sendNotification logic in InventoryManagementService, PaymentManagementService, and ServiceManagementService to ensure notifications are sent only to subscribed users.
</Changes>
<Test>
Precondition:
1. Customer user is logged into the system.
2. Notification configuration option is available in Customer Menu.
3. Notification-triggering event exists for Payment Management Service or Service Management Service.
Steps:
1. Navigate to Configure Notification Preferences in Customer Menu.
2. Enable notifications for one service and disable notifications for the other.
3. Trigger a notification event for both services.
- Verify that notification is received only from the subscribed service.
4. Change preferences by disabling the subscribed service and enabling the other.
5. Trigger notification events again.
- Verify that notification is received only from the newly subscribed service.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>