<UserStory> 1954: Implement Service Refactoring </UserStory>
UserStory #1954
<Changes>
1. Refactored notification handling to persist notifications directly in the datastore instead of maintaining notification collections within User objects.
2. Removed recipient User pointer dependencies from Notification and retained recipient user identification through recipientUserId.
3. Implemented generic observer persistence support in DataStore with shared helper methods for loading and saving observer subscriptions.
4. Added datastore-backed observer management for ServiceManagementService, PaymentManagementService, and InventoryManagementService.
5. Updated attach() and detach() operations to load, modify, and persist observer subscriptions using shared memory mappings.
6. Refactored sendNotification() implementations to create and persist Notification records directly to the datastore for subscribed observers.
7. Updated UserManagementService notification retrieval and deletion logic to operate on datastore notification records filtered by recipient user ID.
8. Removed notification ownership and observer-specific notification APIs from User and Observer classes.
9. Added configurable shared memory growth factor support and updated mapping expansion logic to use centralized configuration values.
10. Removed obsolete NotificationManagementService implementation and updated project configuration references.
11. Added DataStoreLockGuard integration for observer and notification persistence operations to ensure synchronized datastore access.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1953: Model Refactoring </UserStory>
UserStory #1953
<Changes>
1. Replaced CSV-based Notification serialization and deserialization with SerializedNotification record-based serialization for shared memory storage.
2. Implemented Notification::serialize() to convert Notification objects into fixed-size SerializedNotification structures.
3. Implemented Notification::deserialize() to reconstruct Notification objects directly from SerializedNotification records.
4. Added Notification state persistence by introducing util::State support in constructors, serialization, and deserialization flows.
5. Updated Notification class interfaces to use SerializedNotification types instead of std::string serialization APIs.
6. Removed legacy CSV serialization support, including CSV parsing logic and header generation functionality.
7. Added SerializedNotification dependencies through SerializedRecords.h inclusion and forward declaration support.
8. Initialized Notification objects with ACTIVE state by default and added state getter/setter APIs.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1927: Implement Service Refactorings </UserStory>
UserStory #1927
<Changes>
1. Added DataStoreLockGuard integration across ServiceManagementService methods for thread-safe datastore operations.
2. Updated DataStore::getServices(), getComboPackages(), getServiceBookings(), and getJobCards() to enrich records with linked entities (inventory items, services, bookings, technicians).
3. Modified ServiceManagementService::purchaseService() and purchaseComboPackage() to use tracked records and persist bookings safely.
4. Enhanced restoreInventory() and processBookingCancellation() to handle tracked records, update record states, and restore inventory items correctly.
5. Refactored cancelCustomerServiceBookings() and cancelTechnicianJobs() to use tracked records, restore inventory, and persist changes.
6. Updated createComboPackage(), removeComboPackage(), and createJobCard() to use tracked records and save changes to datastore.
7. Updated createService() to validate inventory items with tracked records and persist new services safely.
8. Added required header dependencies for DataStoreLockGuard and shared memory support.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1958: Service Refactoring </UserStory>
UserStory #1958
<Changes>
1. Added DataStoreLockGuard.h include to project file and InventoryManagementService
for thread-safe datastore operations.
2. Enhanced DataStore::getUsers to load SerializedUser records, refresh cache,
and attach notifications with recipient validation.
3. Enhanced DataStore::getInventoryItems to load SerializedInventoryItem records
and refresh cache for tracked inventory items.
4. Refactored InventoryManagementService::sendLowStockAlerts to use tracked
inventory and user maps with DataStoreLockGuard, ensuring safe access.
5. Removed legacy observer management, load/save inventory items, and related
persistence functions from InventoryManagementService.
6. Updated InventoryManagementService::addInventoryItem to insert new records
into tracked inventory map and persist changes via saveInventoryItems.
7. Updated InventoryManagementService::addInventoryItemStock to validate item
existence, update quantity, mark record as MODIFIED, and persist changes.
8. Refactored InventoryManagementService::getInventoryItems to return object
map extracted from tracked records with DataStoreLockGuard.
9. Updated InventoryManagementService::removeInventoryItem to validate item ID,
mark state as INACTIVE, set record state to MODIFIED, and persist changes.
10. Updated InventoryManagementService::getInventoryItem to safely retrieve
inventory items from tracked records with error handling.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1957: Model Refactoring </UserStory>
UserStory #1957
<Changes>
1. Added SerializedRecords.h dependency and forward declaration for SerializedInventoryItem
to support fixed-size record storage.
2. Replaced CSV-based serialization in InventoryItem with serialize() method returning
SerializedInventoryItem structure.
3. Replaced CSV-based deserialization logic with deserialize() method that reconstructs
InventoryItem directly from SerializedInventoryItem record.
4. Removed legacy CSV parsing, header generation, and exception handling tied to string-based
serialization.
5. Updated InventoryItem class interface in InventoryItem.h to use SerializedInventoryItem
types instead of std::string serialization APIs.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1952: Service Refactoring </UserStory>
UserStory #1952
<Changes>
1. Enhanced DataStore::getUsers to load SerializedUser records, refresh cache,
and attach notifications to recipient users with validation for recipient IDs.
2. Updated DataStore::saveUsers to persist SerializedUser records and save
notifications alongside user data.
3. Refactored AuthenticationManagementService::login to use DataStoreLockGuard
and tracked user map with SerializedUser-backed records.
4. Modified AuthenticationManagementService::changePassword to ensure thread-safe
updates, mark user record as MODIFIED, and persist changes via DataStore::saveUsers.
5. Added dependencies for Utility.h and DataStoreLockGuard.h in
AuthenticationManagementService.cpp to support safe record handling.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1960: Service Refactoring </UserStory>
UserStory #1960
<Changes>
1. Replaced the Controller load/save workflow with initialize() and shutdown() methods.
2. Moved startup checks such as admin verification, low stock alerts, and payment reminders into Controller::initialize().
3. Updated UserInterface to use the new Controller initialization and shutdown flow.
4. Updated DataStore::getUsers() and DataStore::getNotifications() to load data directly from shared memory.
5. Added logic to rebuild user notification mappings when user data is loaded from shared memory.
6. Implemented user and notification persistence through DataStore::saveUsers() and DataStore::saveNotifications().
7. Updated UserManagementService to use TrackedRecord-based shared memory records.
8. Added DataStore locking and unlocking to user management operations for synchronization.
9. Updated createUser(), updateUserDetails(), removeUser(), and deleteNotification() to persist changes through shared memory.
10. Removed legacy loadUsers() and saveUsers() implementations from UserManagementService.
11. Added required header dependencies for shared memory support.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1951: Model Refactoring</UserStory>
UserStory #1951
<Changes>
1. Replaced CSV-based serialization and deserialization in ComboPackage,
JobCard, Service, and ServiceBooking models with fixed-size SerializedRecord
structures for shared memory storage.
2. Implemented serialize() methods to convert objects into SerializedComboPackage,
SerializedJobCard, SerializedService, and SerializedServiceBooking records.
3. Implemented deserialize() methods to reconstruct objects directly from
SerializedRecord types instead of parsing CSV strings.
4. Updated model class interfaces to use SerializedRecord types, removing
legacy CSV serialization APIs and header generation functions.
5. Added SerializedRecords.h dependencies and forward declarations for
Serialized structures across affected models.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1955: Model Refactoring</UserStory>
UserStory #1955
<Changes>
1. Replaced CSV-based serialization and deserialization in ComboPackage, JobCard, Service, and ServiceBooking models with fixed-size SerializedRecord structures for shared memory storage.
2. Implemented serialize() methods to convert objects into SerializedComboPackage, SerializedJobCard, SerializedService, and SerializedServiceBooking records.
3. Implemented deserialize() methods to reconstruct objects directly from SerializedRecord types instead of parsing CSV strings.
4. Updated model class interfaces to use SerializedRecord types, removing legacy CSV serialization APIs and header generation functions.
5. Added SerializedRecords.h dependencies and forward declarations for Serialized structures across affected models.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1959: Model Refactoring </UserStory>
UserStory #1959
<Changes>
1. Replaced CSV-based User serialization and deserialization with SerializedUser record-based serialization for shared memory storage.
2. Implemented User::serialize() to convert User objects into fixed-size SerializedUser structures containing user details and enum values.
3. Implemented User::deserialize() to reconstruct User objects directly from SerializedUser records.
4. Updated User class interfaces to use SerializedUser types instead of std::string serialization APIs.
5. Removed legacy CSV serialization support, including CSV parsing logic and header generation functionality.
6. Added SerializedUser dependencies through SerializedRecords.h inclusion and forward declaration support.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
Fix Duplicate Customer Notification Sent When Assigned Technician Is Removed
- Refactored processBookingCancellation to simplify parameters and remove redundant notification arguments.
- Added util::UserType parameter to differentiate cancellation flows for CUSTOMER vs TECHNICIAN.
- Updated cancelCustomerServiceBookings to use processBookingCancellation with util::UserType::CUSTOMER.
- Updated cancelTechnicianJobs to use processBookingCancellation with util::UserType::TECHNICIAN.
- Enhanced booking status handling by including IN_PROGRESS status in cancellation checks.
- Ensured job cards are consistently marked CANCELLED and inventory restored.
- Fixed duplicate notification issue where customers received multiple alerts when technician was removed.
Fixes#1807
Related work items: #1807
Fix Technician Job Status Update Screen UI and Formatting Issues
- Corrected inconsistent status label formatting: replaced "Inprogress" with "In Progress" in TechnicianMenu and MenuHelper.
- Updated headings in selectJobCardToUpdate to clearer phrasing:
- "Select a job to mark as In Progress"
- "Select a job to mark as Completed".
- Added spacing before and after the "No jobs available" message to improve readability and provide clear separation from headings.
- Replaced duplicated prompt "Select the Job Card to Update (Index):" with concise "Enter the job index to update:".
- Improved TechnicianMenu option display to show "In Progress" instead of "Inprogress".
Related work items: #1808
- Corrected inconsistent status label formatting: replaced "Inprogress" with "In Progress" in TechnicianMenu and MenuHelper.
- Updated headings in selectJobCardToUpdate to clearer phrasing:
- "Select a job to mark as In Progress"
- "Select a job to mark as Completed".
- Added spacing before and after the "No jobs available" message to improve readability and provide clear separation from headings.
- Replaced duplicated prompt "Select the Job Card to Update (Index):" with concise "Enter the job index to update:".
- Improved TechnicianMenu option display to show "In Progress" instead of "Inprogress".
Fixes#1808
- Refactored processBookingCancellation to simplify parameters and remove redundant notification arguments.
- Added util::UserType parameter to differentiate cancellation flows for CUSTOMER vs TECHNICIAN.
- Updated cancelCustomerServiceBookings to use processBookingCancellation with util::UserType::CUSTOMER.
- Updated cancelTechnicianJobs to use processBookingCancellation with util::UserType::TECHNICIAN.
- Enhanced booking status handling by including IN_PROGRESS status in cancellation checks.
- Ensured job cards are consistently marked CANCELLED and inventory restored.
- Fixed duplicate notification issue where customers received multiple alerts when technician was removed.
Fixes#1807
<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>
<UserStory> SER1798: Update Job Status </UserStory>
<Changes>
1. Renamed Controller and ServiceManagementService methods from completeJob to updateJobStatus for clarity and flexibility.
2. Enhanced ServiceManagementService::updateJobStatus to support transitions:
- STARTED → INPROGRESS
- INPROGRESS → COMPLETED (with invoice generation and customer notification).
3. Added INPROGRESS state to ServiceJobStatus enum and updated string conversion utilities.
4. Introduced filterJobCards helper to generalize job filtering by status.
5. Updated TechnicianMenu to allow technicians to select job type (Started/Inprogress) and update status accordingly.
6. Improved job display to show current status and truncated service names for readability.
</Changes>
<Test>
Acceptance Criteria:
1. Technician can select a job with status STARTED and update it to INPROGRESS.
2. Technician can select a job with status INPROGRESS and update it to COMPLETED.
3. Completed bookings automatically generate invoices and send notifications to customers.
4. Job status updates are reflected in the technician’s job list and customer view.
Precondition:
1. Technician is logged into the system.
2. Assigned job cards exist with valid statuses (STARTED or INPROGRESS).
3. Datastore and payment service are available.
Steps:
1. Navigate to Technician menu and choose "Update Job Status".
- Verify that the system prompts for job type selection (Started/Inprogress).
2. Select a job card from the filtered list.
- Verify that the job card details are displayed with status.
3. Confirm update.
- Verify that the job status changes correctly.
4. For jobs updated to COMPLETED:
- Verify that the booking status is updated, invoice is generated, and notification is sent.
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
#1798
Changes:
- Added display options for users, services, combo packages and technician jobs
- Updated admin and technician menu options and navigation
- Added reusable helper functions for displaying data in tabular format
- Improved user and combo package listing displays
- Fixed minor validation and error message formatting issues
Changes:
- Added support for PaymentMode::NOTSET in string-to-enum conversion
to prevent invoice deserialization failures during system startup
- Improved invoice table column labels and spacing for better readability
and alignment in invoice display screens
Fixes#1789
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 active user display to include Full Name column.
- Ensured both header and row output show full name alongside ID, username, and user type.
- Improved clarity of Remove User submenu by presenting complete user information.
Fixes#1788
- Added heading output to Remove Inventory Item submenu for clearer user 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)).
Fixes#1778
- Refactored customer and technician removal flow to ensure linked job cards and service bookings are properly cancelled.
- Added inventory restoration logic to avoid duplicate restocking when cancelling bookings.
- Introduced processBookingCancellation helper for consistent cancellation handling, notifications, and technician reassignment.
- Updated UserManagementService::removeUser to invoke appropriate cancellation routines based on user type.
- Ensured customer references and IDs are preserved correctly during booking cancellation.
Fixes#1781
- Added tabular invoice list for better navigation
- Enabled user to select an invoice before viewing full details
- Displayed Payment Mode in detailed invoice view
- Removed duplicate pressEnter() calls
- Improved console messages and formatting for clarity
Fixes#1784
- Changed combo package bookings to start with PENDING status
- Added filterComboPackages to list only active packages
- Improved CustomerMenu combo package selection with clearer messages and formatting
- Enhanced output with console clearing, spacing, and success feedback
- Added truncateString utility for consistent display of long names
- Updated filter functions to use reference parameters for efficiency
Fixes#1779
- Cleared console before displaying Complete Job screen
- Improved submenu header and formatting for clarity
- Prevented table headers from showing when no jobs exist
- Refined job completion flow with consistent messages
Fixes#1782
- change ServiceBooking ID prefix from `SRV` to `SBK`
- add customer notification when technician is assigned to booking
- fix typo in job completion exception message
- remove unnecessary newline characters from completion notifications
Fixes#1780
- Increased spacing between invoice table columns for better readability
- Updated invoice table headers with clearer labels
- Prevented screen clear before invoice listing display
- Changed payment mode selection to re-prompt on invalid input instead of defaulting to offline mode
- Removed unnecessary blank line before service listing display
Fixes#1786
- detach users from InventoryManagementService observers during removal
- detach users from PaymentManagementService observers during removal
- detach users from ServiceManagementService observers during removal
Fixes#1783
- Added ComboPackage dependency check in removeService; deactivates related packages when a service is removed.
- Added filterActiveServices helper to list only active services.
- Updated removeService and removeComboPackage with headings, empty-state checks, and consistent success/error messages.
- Enhanced createComboPackages:
- Uses active services only.
- Added cancel option and confirmation after first selection.
- Prevented duplicate selection and infinite loop when limited services exist.
- Improved feedback when all available services are selected.
- Updated selectServicesToRemove and selectComboPackage to handle empty states gracefully without exceptions.
Fixes#1749
- Assign Job to Technician:
- Added heading for clearer user guidance.
- Filtered only pending service bookings for assignment.
- Improved technician listing and selection with clearer prompts.
- Ensured booking status transitions correctly from PENDING to STARTED when job cards are created.
- Enhanced feedback messages for technician availability and job card creation.
- View Invoices:
- Added heading "View Invoices" for better UI consistency.
- Updated displayInvoices to take map by reference for efficiency.
- Improved formatting of invoice details with consistent spacing and line breaks.
- Added handling for empty invoice parts list (shows "No inventory items used").
- Enhanced error messages when encountering null invoices.
Fixes#1745Fixes#1752
- Added heading "Create Service" to submenu for clearer user guidance.
- Ensured console clears before service creation for consistent UI behavior.
- Filtered active inventory items before selection to avoid showing inactive items.
- Updated prompts with improved formatting and spacing (e.g., labour cost input, success message).
- Refactored selectInventoryItems:
- Added "Select Required Items" heading for clarity.
- Skipped null or inactive items during listing.
- Improved empty inventory message ("No Items Present, Inventory empty").
- Enhanced success and error messages with consistent line breaks.
- Simplified logic for item selection and exit handling.
Fixes#1747
- Updated AdminMenu::addTechnician:
- Added heading "Add Technician" for better user guidance.
- Removed setw formatting, replaced with simpler prompts.
- Ensured console clears before operation for consistency.
- Improved error messages for password, email, and phone validation with line breaks for readability.
- Enhanced success message with consistent spacing.
- Minor cleanup in TechnicianMenu.cpp by adding a blank line after file header for formatting consistency.
Fixed#1744
- Added heading "Add Inventory Item" to submenu for clearer user guidance.
- Updated option text from "Add Quantity" to "Restock Item".
- Ensured console clearing (util::clear) before add item and restock operations.
- Reformatted prompts with consistent spacing and line breaks (e.g., "Enter Item Details", "Select Item to Restock").
- Added default case handling in AdminMenu for invalid choices.
- Enhanced MenuHelper output:
- Extra line breaks for readability.
- Improved error messages ("Invalid index selected", "No active items available").
- Clearer success message when updating stock with new quantity.
Fixes#1740