Changes:
- Refactored ServiceManagementService::updateJobStatus() to use tracked
job card references instead of raw pointers, ensuring consistent state
updates.
- Added proper null checks and error handling for current job retrieval
to prevent unexpected termination.
- Updated logic to mark tracked job records as MODIFIED when status
transitions occur (STARTED → IN_PROGRESS, IN_PROGRESS → COMPLETED).
- Simplified control flow and indentation for better readability and
maintainability.
Fixes#2076
Changes:
- Added retrieval of tracked service bookings and inventory items in
ServiceManagementService::createJobCard().
- Validated service booking ID and inventory item indices before
proceeding with job card creation.
- Decremented inventory item quantities when job cards are created and
marked corresponding tracked inventory records as MODIFIED.
- Updated tracked service booking state to MODIFIED when technician is
assigned and job status changes.
- Persisted changes by saving job cards, service bookings, and inventory
items to the datastore.
Fixes#2075
Changes:
- Updated ServiceManagementService::purchaseService() to persist service
bookings immediately after creation using m_dataStore.saveServiceBookings().
- Updated ServiceManagementService::purchaseComboPackage() to persist
combo package bookings immediately after creation using
m_dataStore.saveServiceBookings().
- Changed DataStore::getJobCards() to use a reference for tracked bookings
to ensure consistent linkage and prevent overwriting.
Fixes#2074
Changes:
- Implements #2061
- Introduce EventManager for user-specific Windows event publishing/listening
- Add real-time notification and account-disabled event propagation
- Register authentication events through Controller and AuthenticationManagementService
- Trigger notification events from Inventory, Payment, and Service Management modules
- Trigger account-disabled events when users are deactivated
- Extract common menu event listener logic into Menu base class
- Add notification popup handling for Admin, Customer, and Technician menus
- Refactor shared memory components into core/sharedmemory
- Update project structure and include paths for events and shared memory modules
<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> 1950: Implement Service Refactorings </UserStory>
UserStory #1950
<Changes>
1. Added `DataStoreLockGuard` integration in `PaymentManagementService` methods (`sendPaymentReminders`, `generateInvoice`, `getInvoices`, `completePayment`, `getAllInvoices`, `confirmPayment`) to ensure thread-safe access to the datastore.
2. Implemented record enrichment logic in `DataStore::getInvoices()` to automatically link `Invoice` objects with their corresponding `ServiceBooking` and `InventoryItem` entities during loading, validating relationships and throwing exceptions for invalid references.
3. Refactored invoice persistence by implementing `saveInvoices()` using `saveRecords<Invoice, SerializedInvoice>` to write tracked records directly to shared memory.
4. Updated invoice creation and modification flows:
- `generateInvoice`: Uses `createNewRecord` to insert new invoices into the tracked cache and triggers immediate persistence.
- `completePayment` & `confirmPayment`: Marks records as `MODIFIED` in the `TrackedRecord` state before saving changes.
5. Updated data access patterns across `PaymentManagementService` to use `.data` pointers from `TrackedRecord` objects returned by the datastore, replacing direct pointer access to mapped objects.
6. Added necessary header dependencies including `DataStoreLockGuard.h`, `Invoice.h`, and `SerializedRecords.h` to support locking mechanisms and structured serialization.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1949: Model Refactoring</UserStory>
UserStory #1949
<Changes>
Replaced CSV-based serialization and deserialization in the Invoice model with fixed-size SerializedRecord structures for shared memory storage.
Implemented serialize() method to convert Invoice objects into SerializedInvoice records using direct struct field assignment and strcpy_s for string fields.
Implemented deserialize() method to reconstruct Invoice objects directly from SerializedInvoice types instead of parsing CSV strings.
Updated Invoice class interfaces to use SerializedInvoice types, removing legacy CSV serialization APIs including getHeaders() function.
Added SerializedRecords.h dependency and forward declarations for SerializedInvoice structure in Invoice header.
Minor formatting adjustments in DataStore.cpp (closing brace placement).
</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