# List of the Release Notes (2026)

# Version 9.1.227 (4 May 2026)

#### **People Management**

##### Link the Address section to the required field, and implement required address import validation (#148420 &amp; #148425)

**Problem**

- Address section (not on summary page), not yet linked to required field setup. Also, import validation doesn't fire for missing required address fields

**Solution**

- Link the Address section to the required field, and implement required address import validation

##### Improve people management search functionality and add ID and passport number to Materialised Users (#146799)

**Problem**

- People management search functionality needs improvements for score-based relevance searching, and to search on ID number and passport number

**Solution**

- Add ID and passport number to Job Profiler materialised user to enable searching, and improve all 4 people management SQL queries to include improved score-based searching

##### Fix Long username overflows to the side on a Person's User Card (#146219)

**Problem**

- Long username overflows to the side on a Person's User Card

**Solution**

- Ensure that long names do not overlap by introducing a popover with ellipses

##### Fix People linked to a role navigation not working to go back (#147781)

**Problem**

- People linked to a role navigation not working to go back

**Solution**

- Ensure that when clicking the back button from people linked to either product roles or people group that, it navigates you back

##### Resolve people group panes that do not clear correctly when navigating between them (#147818)

**Problem**

- When switching between "Included"/"Excluded" and "People"/"Grouped Conditions", the wrong information/tables are displayed

**Solution**

- Resolve people group panes that do not clear correctly when navigating between them
- Added hideChildPanes() to clear all child panes (fixes the original bug — grouped conditions content not clearing).
- Added $(targetPane).addClass('active show') immediately after to manually re-show the clicked tab's target pane, since MDB's pill listener fires first and we override it.
- Reused the targetPane variable in the #v-pills-query-conditions check to avoid calling attr('href') twice.

##### Resolve issue where non-people administrators received errors when updating users to whom they have access via custom people group permissions (#146966)

**Problem**

- When a user has been given people edit permissions via a custom people group, the editing of the user's details only partially succeeds.
- The authorisation on Identity is checking whether the acting user has the people management administrator role and is not taking the PG permissions into account.

**Solution**

- Added authorisation check on Identity service to perform an auth check that determines whether the user is editing their own profile, whether a people administrator or whether allowed to edit based on supplied permission type.
- For this also necessary to ensure that the logged-in user's permissions are always set in the cache and not just in the session, when the gRPC context is made to identify the HTTP context's session, which is no longer available to retrieve the permissions from, so it must rely on the cached value.

##### Resolve duplicate loads of the default child menu when clicking on the parent menu under people management admin (#147833)

**Problem**

- Long loading times with certain menu items under the people management admin page

**Solution**

- Resolve duplicate loads of the default child menu when clicking on the parent menu under the People Management admin

---

#### **Event Scheduler**

##### Fix scroll drag on event list view (#148222)

**Problem**

- When a user scrolls on the page, the system drags and has a delayed response

**Solution**

- Fix the styling on the page so that the elements on the list view page fill it better, so that only the list view scrolls instead of the entire page

##### Ensure facilitators can view events they are facilitating and also update attendance (#148265)

**Problem**

- Facilitators could not view events they were facilitating, and as a result, could also not update attendance.

**Solution**

- Ensure facilitators can view events they are facilitating and also update attendance

---

#### **Report Builder**

##### Fix drop-down spills over the accordion and activates a scroll bar (#147795)

**Problem**

- Drop-down spills over the accordion and activates a scroll bar

**Solution**

- Ensure the drop-downs do not spill over the accordion

---

#### **ChatBots**

##### Ensure selected person details are available in JS for the bot - specifically for Replacements via bot (#142989)

**Problem**

- Replacements via the bot do not expose the user selected for replacement

**Solution**

- Ensure selected person details are available in JS for the bot - specifically for Replacements via bot

---

#### **People Groups**

##### Resolve issues on org unit and custom people group treeview selections (#148080)

**Problem**

- Indicators and tooltips on the org structure treeview displaying whether Org PG exists weren't displaying.
- Nothing happened when clicking on either of the icons to create the org unit
- Org unit selection when adding org to Custom PG's Grouped Conditions was not working correctly, due to a functionality collision between the Org Type PG treeview functionality and the Custom PG org grouped condition functionality.

**Solution**

- Recent changes to retrieve org nodes per level did not return the required single/multi-node pg classes needed to display colour and tooltips on relevant icons. Added this calculation to the query.
- Confirmation modal was missing from the page that requests the user to confirm the creation/linking of a node to PG. Tooltip triggers were not triggering on the icon, so I moved them to the wrapping span of the icon.
- Modifications to the JS handlers to correctly send through the Custom PG ID to which org must be linked or create a new ORG PG if applicable, and take no action when already linked/created.
- Changes to the Grouped Condition for Org units query to calculate positions depending on whether to include sub-nodes or only have the main node.
- Additional correction on query to allow adding org unit again, depending on whether it should include child org nodes, also corrected to display "(Excl. sub org units") on those that do not include sub org nodes.

##### Fix bug on icon highlight on org unit pg. (#148080)

**Problem**

- On the previous fix, the org unit PG is reflecting the custom PG node if selected.

**Solution**

- Resolve the issue to have the org unit PG only show when the org unit is the actual PG.

---

#### **Identity and Authorisation**

##### Fixed styling of registration page (#147892)

**Problem**

- There are no margins on the registration page breaks when some elements are not displayed.
- The width of the main container changes when some fields are not displayed.

**Solution**

- Adding margin where needed on the page and ensuring the container does not resize when making changes.

##### Fixed styling of registration page (#147892)

**Problem**

- There is no margin between the Job Profile Disclaimer and the Captcha. The 'Location in Organisation' and 'Job Title' fields do not scale with horizontal page size.

**Solution**

- Adding margin after the Job Profile Disclaimer field and ensuring the 'Location in Organisation' and 'Job Title' fields scale with horizontal page size.

---

#### **Job Management**

##### Resolve the positions footer that disappears when navigating to other tabs (#147804)

**Problem**

- The “+ New Position” button at the bottom disappears after navigation, and refreshing the page brings the button back

**Solution**

- Resolve the positions footer that disappears when navigating to other tabs

##### Update recruitment HR process post approval default URL (#147843)

**Problem**

- The additional service API URL already contains 'api'

**Solution**

- Remove 'api' from recruitment relative URL

##### Fixing date ordering of appointment tables (#147134)

**Problem**

- When the date format used for the appointment start and end dates in the appointments tables is lexicographically unsortable (dd/mm/yyyy), the appointments are not sorted correctly.

**Solution**

- Ensure the date values used to sort the appointment rows are lexicographically sortable (yyyy/mm/dd) even though the culture uses lexicographically unsortable dates (dd/mm/yyyy or yyyy/dd/mm).

---

#### **Imports**

##### Corrected User Import field length validation (#148173)

**Problem**

- Field length validations on the user import were not correct for all the import fields.

**Solution**

- Corrected the length validations.

##### Ensuring that the link to download the User Validation Report is shown for PowerShell imports as well (#146598)

**Problem**

- The link to download the User Validation Report is not shown for PowerShell imports.

**Solution**

- Adding PowerShell imports to the list of reports that should show the User Validation Report button.

---

#### **Notifications**

##### Skip to-be-sent records when there are no valid recipients (#147877)

- Ensure that we do not add "empty" to-be-sent records when there are no recipients. This was done for auditing purposes, but it causes a very large growth in the table. Rather, just log it instead.

---

#### **Tenant Management**

##### Adding togglable pagination session store and restore (#142318)

**Problem**

- On the Tenants page, pagination is not retained after editing a tenant. When returning to the list, all filters and paging are reset.

**Solution**

- Added session storage support to the global search control, allowing filters to be preserved where required.
- This feature can be enabled per data table and is disabled by default. It has been enabled for the Tenants page, ensuring that filters(search terms) are restored when navigating back to the list.

---

#### **Dashboards**

##### Adding refresh on Banner Modal open (#146695)

**Problem**

- When a user updates selected images and then either saves or cancels, the modal closes as expected.
- However, when the modal is reopened, the image list is not refreshed.
- This can result in outdated or incorrect data being displayed, including unsaved changes after cancelling or incorrect image order after saving.

**Solution**

- Ensure the image list is refreshed every time the modal is opened, so it always reflects the latest saved state from the database.
- This prevents stale or incorrect data from being displayed after cancel or save actions.

##### Replace all TinyMCE implementations with Sync Fusion rich text boxes (#146565)

**Problem**

- TinyMCE WYSIWIG (rich text boxes) is not free anymore. Replace all components with Sync Fusion WYSIWIG

**Solution**

- Create a reusable JavaScript component for Sync Fusion rich text boxes, and replace all existing TinyMCE components on Razor pages, and 1 page on React.
- Affected pages: 
    - Ruleset | Dashboard Widgets | Add custom - 1 component
    - Ruleset | System Access | 3 components (1 is only available on Ruleset 1)
    - Ruleset | Communications | Add template - 2 components
    - Ruleset | Communications | Email Setup - 2 components
    - Job Management | Select Job | Disclaimer - 1 component
    - System help page (V8) | Edit help page information - 1 component
    - System help page (V8) | Edit virtual tours - 1 component
    - Learning Management | Open subject | Class/Group | Attendance Register | Send email notification (Mark as absent) -1 component

---

#### **Data Warehouse**

##### Updated script C\_03585\_99999\_monDatawarehouseJobResultsReport.sql (#142737)

**Problem**

- The newly added SSIS Packages are not included in the DWH Job Results email

**Solution**

- Added the new SSIS Packages within the DWH Job Results email

---

#### **API**

##### Default attendance register to absent (#147668)

**Problem**

- A request has been submitted that attendance registers be defaulted to absent

**Solution**

- Update the SQL script to default to absent

##### Ensure font configs register at build time (#147982)

**Problem**

- Docx to PDF conversion still failing when charts and maths equations are in the docx

**Solution**

- Ensure font configs register at build time by adding a command to Docker

---

# Version 9.1.226 (4 May 2026)

#### **Communication Portal**

##### Resolved Master Data deletion relation being slow (#147642)

**Problem**

- SQL cursor performance issue checks every FK relation before attempting to delete the master data item

**Solution**

- SQL improvement to minimise the cursor and a single select to determine any relations

##### Resolved red-dot appears after reading messages (#147066)

**Problem**

- When a message is sent, the end user receives it, and there are local-storage checks to keep track so as not to always hit the database to refresh. But never reset when opening the modal to set the local key, even if the server/database side has been updated to read

**Solution**

- Corrected logic to update values when opening the modal

##### Resolved notification not being sent out (#147971)

**Problem**

- RecipientUserId is needed in the notification service, which the communication portal is not passing through

**Solution**

- Added a change to send through the userId for the recipientUserId

---

#### **API**

##### Ensure font fallbacks work on file conversion (#147982)

**Problem**

- The Docker file is missing some dependencies needed for font fallbacks.

**Solution**

- Add dependencies needed for font fallbacks to the Docker file. Also, improve the code for the fallback to be more robust.

##### Add embedded fonts for sync fusion to use on the Linux server for docx to PDF conversion (#147982)

**Problem**

- Word (docx) files don't display content when converted to PDFs

**Solution**

- Add embedded font types to the Linux server for Sync Fusion to use in conversion. Also, remove previously added debug logs

##### Fix successful logins logged as failed attempts (#147675)

**Problem**

- When logging in successfully multiple times in quick succession, logins are blocked (successful logins marked as unsuccessful attempts)

**Solution**

- Do a check to see if the login was successful, or if the successful login is being routed to the disclaimer required before logging the attempt

---

#### **Imports**

##### Serve PaySpace user export as a stream (#146311)

**Problem**

- Large payspace clients experience the following issue: StatusCode="ResourceExhausted", Detail=" Received message exceeds the maximum configured message size.") Multiple pull requests are also processed using unnecessary resources.

**Solution**

- Change ListUsersExportPerDatePayspaceAnonymous to a server-streaming RPC and update server/client code to stream users in batches.
- The ExportData proto and ExportDataServiceV1 now stream UserExport responses (batched at 1000) and write each batch to the response stream.
- The Import API handler was updated to consume the async server stream from JobProfiler, aggregate users, and adapt logging to per-user transactions.
- Also injected IImportQueries and added a check to prevent concurrent PaySpace pull imports (logs a fatal error and aborts if an active import exists).
- Miscellaneous fixes: improved null-safety and mappings when building UserExport payloads and adjusted log messages.

##### Improve Payspace performance when fetching employee positions and extend logging in Payspace implementation (#146311)

**Problem**

- When pulling a large number of positions from PaySpace, it takes a very long time and fails. Logging is limited to debugging the PaySpace API calls and results

**Solution**

- Introduce several improvements and refactorings to the PaySpace user details import flow, focusing on simplifying data handling, improving logging, and enhancing error/warning reporting.
- The changes include updates to proto files, removal of unnecessary dependencies, streamlining of collection operations, and improved logging for better traceability and maintainability.
- Reduce the fields selected from the position call and implement parallel tasks to speed up processing by 5

---

#### **People Groups**

##### Correct problem with user people group fetch excluding appointments that end on the current day (#147959)

**Problem**

- When a user's appointment ends on the current day, then no people groups are returned on which the user is a part of, resulting in no menu items being displayed.

**Solution**

- Correct the filter condition on the query to consider the end date of the appointment as inclusive.

---

#### **Dashboards**

##### Adding filter info and refreshing image list on upload and delete (#146695)

**Problem**

- Users are not aware that older banners still exist and can be accessed via the search field, as the list is now limited to 21 banners and older items are no longer shown by default.
- When new images are uploaded, they are automatically selected, which can result in more than the maximum of 5 banners being selected.
- In addition, uploads can cause the displayed list to exceed the 21-item limit.
- When images are deleted, the list may drop below 21 items, but older banners are not automatically loaded to fill the available space (where available).

**Solution**

- Added an information section at the bottom of the modal to inform users that older banners can be accessed via the search field.
- Uploads will continue to auto-select new images, but the oldest selected image will now be automatically deselected to enforce the 5-banner limit.
- Uploading and deleting images now trigger a refresh from the database, ensuring the displayed list remains accurate and up to date.

---

#### **Job Management**

##### Update default required fields for requisition HR process level actions (#142989)

**Problem**

- HRPRactitionerId should not be required for the post approval actions

**Solution**

- Remove HRPractionerId as required

---

#### **Data Warehouse**

##### Updated AbsentAttendance for lmTermResults (#147669)

**Problem**

- AbsentWithExcuse needs to be excluded from the absent calculation

**Solution**

- Updated the Attendances calculation step to only select Attendances where they are equal to "Absent"
- Added a step to only fetch attendance records for the current year

##### Adjustments made within lmEmployeeTrainingRequirementsMatrix (#146700)

**Problem**

- The data is not refreshing as expected within the lmEmployeeTrainingRequirementsMatrix when using the date filter

**Solution**

- Adjusted the lmEmployeeTrainingRequirementsMatrix DWH Step to do a full refresh only in the morning, and skipping the staging table step

##### Corrected the Update step for jpAppointments (#144482)

**Problem**

- The Appointments did not update correctly due to how joins were implemented

**Solution**

- Corrected the join to ensure that the existing Appointments are updated correctly

##### Adjustments made within accPAYU tables (#147540)

**Problem**

- RulesetID, RulesetName and SchemaID need to be added and populated within accPAYUSummary
- The accPAYE tables need to be run and populated on the 21st of each month

**Solution**

- Added new fields RulesetID, RulesetName and SchemaID within accPAYUSummary
- Adjusted Container package to execute on the 21st of each month
- Adjusted the Cursor that it runs per DBName and SchemaID
- Added fields DateFrom and DateTo
- Resolved issue where #Totals needs to be done by using #TempOutputWithRowNumber
- Corrected ActivityStart

---

#### **Master Data**

##### Resolve template propagation for prior partial copies (#147828)

**Problem**

- Some email templates are not copied to the newly created ruleset.

**Solution**

- Resolve the problem with partial job runs where templates were not copied, preventing templates from being copied in subsequent job runs.
- Root cause: 
    - newEvents, newRecipients, and newSchedules only contain items added in the current job run. If a prior run was partially completed (e.g. events/recipients were saved, but templates weren't), these lists are empty, and the existing fallback (existingEvent from template navigations) is also empty since there are no existing templates yet.
- Fix — both CopyRecipientsAsync and CopyTemplatesAsync: 
    - Fetch all target-ruleset entities directly from the DB (allTargetEvents, allTargetRecipients, allTargetSchedules) at the start of each method.
    - Merge those with newEvents/newRecipients/newSchedules into allAvailable\* lists, deduplicating by Id to avoid double-entries.
    - Resolve linked entities from allAvailable\* first by PropagatedFromId, then fall back to a code/name match — this handles the partial-run scenario where PropagatedFromId lookup would have been the only path before.

---

#### **Ruleset Management**

##### Remove Google country api (#147832)

**Problem**

- When opening the general table, a call is made to select the current user's country and then set the rulesets

**Solution**

- Remove the Google location API feature; the user must select the country themselves.

##### Default decryption for clientSecret on the payroll model (#147782)

**Problem**

- Connector execution fails due to failing decrypting of ClientSecrets

**Solution**

- Default decryption for clientSecret on the model itself, so it doesn't need to be manually decrypted

##### Correct theme generation due to flatdatepicker styles (#147900)

**Problem**

- The theme selected cannot be generated due to the flatpicker CSS in the site's Sass file.

**Solution**

- Add support for the Flatpickr date picker library by including its CSS in the project. The main changes involve updating resource management and layout files to ensure the Flatpickr styles are available throughout the application.

##### Add the dropdown-toggle class to the dropdown button and hide the caret that is automatically added (#146588)

**Problem**

- The click event on the kebab (Actions) menu icon is no longer firing

**Solution**

- Add the dropdown-toggle class to the dropdown button and hide the caret that it adds automatically

---

#### **Organisational Structure**

##### Fix import creating duplicates (#147839)

**Problem**

- When importing org nodes, blank intermediate org levels are incorrectly replaced with the root node name while building the org path. That produces paths like `Client0001 | Client0001 | Packaged Gases | Sales`, prevents matching the existing node, and can lead to duplicate org nodes being created.

**Solution**

- Only fall back to the root node name for the first org level. Blank intermediate levels are skipped when building the org path, so the generated path matches the existing hierarchy, and the importer can reuse the correct node instead of creating a duplicate.

---

#### **Notifications**

##### As a user receiving a notification, I want the URL to have my Theme URL (#145940)

Ensured that the following notifications take the current theme key from the user acting, which results in the notification:

- Welcome Notification
- Reset Password
- New Person Registered
- Approve Registration Request
- Registration Request has been approved

---

#### **Learning Management**

##### Fix marksheet save and continue navigation (#147137)

**Problem**

- When a user had unsaved marks and chose Save and Continue, the page sometimes tried to reload the current marksheet and move to the next page at the same time. That clash caused the screen to go blank, and the user lost navigation.

**Solution**

- The save process was changed so that, when the user clicks Save and Continue, the system now saves the work and then moves on directly instead of trying to reload the current page first. This prevents the blank screen and keeps navigation working properly.

##### Fix translation for marks save error (#147342)

**Problem**

- When someone tried to save marks, and a duplicate mark already existed, the system showed a confusing technical error message instead of a clear explanation.

**Solution**

- Updated the system so it now shows a proper user-friendly message for that save error, making it clear what went wrong instead of exposing technical text.

---

#### **People Management**

##### Adding optional close on backdrop click to ManagePersonModal (#147824)

**Problem**

- Remove the static backdrop and allow the user to close the modal by simply clicking away from it.

**Solution**

- Adding a boolean to give us the ability to toggle this functionality on and off, since this component is used on multiple different pages. Toggling it on for the People Management page.

##### Ensure user session timeout can be set via configuration (#147837)

**Problem**

- User session timeout is hard-coded to 20 minutes.

**Solution**

- Get session timeout value from configuration/appsettings and also increase the default to 60 minutes

---

#### **Performance Management**

##### Resolved master data searching Perspective (#147640)

**Problem**

- When searching perspective, it results in data, but within the mapping, it fails due to the first check instead of returning a default value.
- Enum value being forced and throws.

**Solution**

- Corrected returning type of tuple null, null

##### Resolved check-in dial phases (#147902)

**Problem**

- On the overall summary check-in dial can not be opened unless ratings have been confirmed, discussion resulted in removing the requirement that ratings should be completed. When a dial is clicked to view the ratings, even if the rating phase is no longer active, it can still be edited

**Solution**

- Removed ratings completed requirement. Added Check-Ins phase active check to pass through that ensures if the edit modal can be opened or not

---

#### **Event Scheduler**

##### Adding a badge to show your booking Reference number (#146254)

**Problem**

- The system should show “Your Booking Reference Number” somewhere when clicking on an upcoming event

**Solution**

- Adding a badge with “Your Booking Reference Number” next to the event heading/title

##### Add more default booking reasons plus seed to other rulesets (#146251)

**Problem**

- Limited booking reasons and master data are not seeded

**Solution**

- Add more default booking reasons, plus seed to other rulesets

---

# Version 9.1.225 (4 May 2026)

#### **People Management**

##### Catching and handling error occurring when terminating inactive person (#146377)

**Problem**

- When attempting to terminate a user without an active appointment, a “We’re Sorry” page is displayed.

**Solution**

- A message is now shown instead, clearly explaining the issue without redirecting to the “We’re Sorry” page

##### Implement a unique field configuration on the ESS settings (#144890)

**Problem**

- Cannot define Username, Id Number, Passport Number, Employee Code, and Email as unique for the ruleset using ESS settings

**Solution**

- Introduce enhanced uniqueness validation for user-related operations, ensuring that users cannot be created or updated with duplicate key identifiers (such as username, employee code, ID number, passport number, or email) within the same ruleset, according to the ESS setup's unique field configuration. The changes span updates to the data model, gRPC contracts, and command handlers to support this feature.

##### Resolved transfer user data validation bug (#147063)

**Problem**

- When the termination date is before the appointment date when transferring a user to another ruleset, the validation happens, but no message is displayed. The validation was appearing, but instantly hiding itself again.

**Solution**

- Just ensured that the validation message is not hidden directly after being displayed.

##### Limit My Department users to only active appointments (#147835)

**Problem**

- Users are duplicated per appointment on the My Department page. The duplicated user is also added as a phantom user when switching tabs on people management, like view/edit people.

**Solution**

- Limit My Department users to only active appointments. Duplicate user IDs break the key attribute on React components, causing it not to clear the list properly when switching tabs

---

#### **Data Warehouse**

##### Updated manual step for lmTermResults (#147814)

**Problem**

- Currently, the DWH will remove any entries within TermResults if the Average is equal to 0

**Solution**

- Updated manual step for TermResults by removing the delete step where the average is equal to 0

##### Added step to update existing fields within Data Dictionary (#142732)

**Problem**

- Fields Selectable and Searchable are not available to select within ReportBuilder for Job Positions

**Solution**

- Update fields to be Selectable and Searchable for JobPositions within ReportBuilder

##### Added step to remove duplicate entries within pdmContractPeriodActionPlans (#142737)

**Problem**

- The DWH table pdmContractPeriodActionPlans does contain duplicate entries based on how the source query is structured

**Solution**

- Added a step to remove duplicate entries within pdmContractPeriodActionPlans if the fields ContractPeriodActionPlanID, ContractID and ContractPeriodID are the same

---

#### **Job Profiler**

##### Future and past subordinates being returned (#146082)

**Problem**

- Subordinates are being returned for ListManagerSubordinatesAsync who are not active employees.

**Solution**

- They still had the CurrentPosition = 1 flag. Added the EndDate check for an appointment to filter on present appointments.

---

#### **Dashboards**

##### Updating Main Dashboard banner search functionality on Banner Modal (#146695)

**Problem**

- On the banner selection pop-up, having many banners causes the buttons to move off-screen. When scrolling to reach the buttons, the search bar is no longer visible. Large images can also make the page slow and unresponsive.

**Solution**

- Updated the layout so the banner list is scrollable, keeping the search bar and buttons visible at all times.
- Search results are now limited to 21 banners for better performance.
- Selected banners will always be included in the results, along with any that match the search term.
- Results are ordered with selected banners first, followed by the most recently uploaded banners

##### Adding a clear button to the search field (#146522)

**Problem**

- The search field does not have a clear button.

**Solution**

- Add an eraser icon to clear the search field

---

#### **Event Scheduler**

##### Changed ScheduleComponent event handlers to useCallback to prevent re-render errors (#146447)

**Problem**

- A blank calendar page appears after opening the "Multiple Event Booking" modal and then cancelling/closing it again.

**Solution**

- Improved how the calendar handles updates when opening and closing popups. This ensures the calendar stays visible and continues to display events correctly instead of disappearing or showing a blank screen.

---

#### **Tenant Management**

##### Adding session storage and restore functionality to global search (#142318)

**Problem**

- On the Tenants page, search filters are not retained after editing a tenant. When returning to the list, all filters and paging are reset.

**Solution**

- Added session storage support to the global search control, allowing filter to be preserved where required. This feature can be enabled per data table and is disabled by default. It has been enabled for the Tenants page, ensuring that filters(search terms) are restored when navigating back to the list.

---

#### **Content Management**

##### Add functionality to convert HTML to Word and replace placeholders in a PowerPoint presentation (#145071)

**Problem**

- Functionality required to update a PowerPoint presentation.

**Solution**

- Added functionality to replace placeholders on a PowerPoint presentation. Also added a function to convert HTML to a Word document.

##### Fix typos in document placeholder descriptions (#147637)

**Problem**

- Some of the placeholders had typos in the translation description.

**Solution**

- Fix translation descriptions in placeholders

---

#### **Imports**

##### Add additional unique field validation to pre-import validation (#144890)

**Problem**

- Correct creation and update of unique user fields in import

**Solution**

- Refine the error messages for user creation and update failures in the `ImportUsersCommandHandler` to provide clearer and more accurate information about conflicts due to existing users. The changes clarify that the conflict is with another user and improve the details shown for matching fields.

##### Implemented immediate employee sync (#143194)

**Problem**

- When a new user is created, it is not immediately imported into V8 unless an entire import is kicked off

**Solution**

- Added a change after a new user creation happens, create a user import for that username to V8

##### Add additional unique field validation to pre-import validation (#144890)

**Problem**

- When importing users with the same fields, that is still unique, it is still allowed

**Solution**

- Introduce a Unique flag on SelfServiceSetting and wire it through the validation pipeline to support uniqueness checks for Email, ID Number, Passport Number and Employee Code. Precompute per-field value counts and a uniqueFields map in UserDetailsValidationService, and add duplicate-value checks that emit validation errors when a field marked unique is duplicated. Update all SelfServiceSetting construction sites to pass the new Unique flag and adjust related method signatures. Add unit tests covering unique-field scenarios and update existing tests accordingly.

---

#### **Notifications**

##### Adjusted character count for masking rule (#147452)

**Problem**

- Development was done to do character masking with 1 character count, request to do a 2-character count display

**Solution**

- Added new rules to do character counts, should there be enough characters, 2 prefix shown, masked in between, and the last 2 characters are displayed

---

#### **Performance Management**

##### Change score when review setup and item not in use (#145198)

**Problem**

- When a user has added a rating scale, they can not change the score, as there are business rules defined for this

**Solution**

- Allow a user to only change the score on an item if the review setup has not been used within a contract, and add a safety check within the command to check that the review item has also not been used yet

##### Resolve sanitisation problem by handling newlines properly for data table and textarea (#147709)

**Problem**

- Break tags shown on the add/edit modal of KPI, KC review section items

**Solution**

- Resolve sanitisation problem by handling newlines properly for the data table and the textarea. Items saved from the modal are saved with new line chars \\r\\n. The sanitiser converts these to break tags that display correctly on the data table. When opening this in the modal again, the breaks are shown in the text area. Added helper functions to replace breaks with newlines when opening the modal and vice versa when saving from the modal

---

#### **Workplace Assessment App**

##### Implemented new endpoint for Observation app to upload stream file content (#143882)

**Problem**

- Endpoints created to allow the observation app to stream files, large files to service, due to http2 endpoints not being able to make public, normal http1 api transcoding takes place. But with large files, this causes timeouts and stream errors, for example, 60mb to be converted to a base64 string fails

**Solution**

- Added a new endpoint and proto to accept a streamed body file and use that to then send for the next method. Add a new app setting to allow/regulate the upload max file size

---

#### **Master Data**

##### Resolved master data items being searched (#147640)

**Problem**

- When searching for a master data item, the global search text is not passed through, resulting in no value sent to the master data service. This results in the top 50 records, where after those server results are returned to the page, it only filters client side from the 50, hence why not all records are returned

**Solution**

- Add a correction to also search for the query string, as those values are not part of form data when posted from the jQuery table

---

#### **Learning Management**

##### Log mark audit failures and incorrect audit table names (#147362)

**Problem**

- Users could accidentally save duplicate marks on the Marksheet by clicking the Save or Inherit Marks buttons multiple times before the request is completed. This caused errors that were either silently swallowed or shown as a confusing technical message with no guidance on what to do next.

**Solution**

- Duplicate prevention (frontend) 
    - The Save and Inherit Marks buttons are now disabled while a request is in flight, preventing the user from submitting the same marks more than once.
- Duplicate prevention (database) 
    - Two partial unique indexes have been added to the `Marks` table to enforce that a learner can only have one mark per assessment per cycle at the database level — a safety net even if multiple requests arrive simultaneously.
    - Existing duplicate rows are cleaned up as part of the migration (keeping the most recently edited entry). A backup of the `Marks` table is taken before any changes are made.
- Meaningful error messages 
    - When a duplicate mark is detected, the user now sees a clear message: \_"A mark for this user already exists. Please reload the page to see the latest marks."\_
    - All other save/inherit failures show the server's error details (if available), followed by "Please reload the page and try again."\_ so the user always knows the next step.
    - If there is no specific error detail, only the reload instruction is shown — no empty or generic filler text.

##### Add idle auto-save and unsaved changes warning to Marksheet (#147137 &amp; #147138)

**Problem**

- When teachers or administrators are entering marks on the Marksheet, their work can be lost if they: 
    - Step away from their computer without saving
    - Accidentally navigate away from the page or close the browser tab
    - Get distracted and forget to click Save
- There was no safety net to protect unsaved mark entries, which could result in having to re-enter all the data again

**Solution**

- Idle Auto-Save 
    - The system now automatically saves mark changes after a period of inactivity (defaulting to 5 minutes). If a user steps away or gets distracted, their progress is saved in the background without any action required. This behaviour can be configured or disabled via application settings.
- Unsaved Changes Warning 
    - If a user tries to navigate away from the Marksheet while there are unsaved changes, a clear warning message is shown asking whether they want to save, discard, or stay on the page - giving them full control and preventing accidental data loss.

---

#### **Communication Portal**

##### Resolved member count (#147597)

**Problem**

- User count not returned for group discussions

**Solution**

- Re-added count, and show loading indicator for internal use as well.

---

# Version 9.1.224.1 (Support Release - 20 April 2026)

#### **People Management**

##### Resolved transfer user data validation bug (#147063)

**Problem**

- When the termination date is before the appointment date when transferring a user to another ruleset, the validation happens, but no message is displayed. The validation appeared but instantly hid itself again.

**Solution**

- Just ensured that the validation message is not hidden directly after being displayed.

---

#### **Learning Management**

##### Fix translation for marks save error (#147342)

**Problem**

- When someone tried to save marks, and a duplicate mark already existed, the system showed a confusing technical error message instead of a clear explanation.

**Solution**

- Updated the system so it now shows a proper user-friendly message for that save error, making it clear what went wrong instead of exposing technical text.

##### Log mark audit failures and incorrect audit table names (#147362)

**Problem**

- Users could accidentally save duplicate marks on the Marksheet by clicking the Save or Inherit Marks buttons multiple times before the request is completed. This caused errors that were either silently swallowed or shown as a confusing technical message with no guidance on what to do next.

**Solution**

- Duplicate prevention (frontend) 
    - The Save and Inherit Marks buttons are now disabled while a request is in flight, preventing the user from submitting the same marks more than once.
- Duplicate prevention (database) 
    - Two partial unique indexes have been added to the `Marks` table to enforce that a learner can only have one mark per assessment per cycle at the database level — a safety net even if multiple requests arrive simultaneously.
    - Existing duplicate rows are cleaned up as part of the migration (keeping the most recently edited entry). A backup of the `Marks` table is taken before any changes are made.
- Meaningful error messages 
    - When a duplicate mark is detected, the user now sees a clear message: \_"A mark for this user already exists. Please reload the page to see the latest marks."\_
    - All other save/inherit failures show the server's error details (if available), followed by "Please reload the page and try again."\_ so the user always knows the next step.
    - If there is no specific error detail, only the reload instruction is shown — no empty or generic filler text.

##### Add idle auto-save and unsaved changes warning to Marksheet (#147137 &amp; #147138)

**Problem**

- When teachers or administrators are entering marks on the Marksheet, their work can be lost if they: 
    - Step away from their computer without saving
    - Accidentally navigate away from the page or close the browser tab
    - Get distracted and forget to click Save
- There was no safety net to protect unsaved mark entries, which could result in having to re-enter all the data again

**Solution**

- Idle Auto-Save 
    - The system now automatically saves mark changes after a period of inactivity (defaulting to 5 minutes). If a user steps away or gets distracted, their progress is saved in the background without any action required. This behaviour can be configured or disabled via application settings.
- Unsaved Changes Warning 
    - If a user tries to navigate away from the Marksheet while there are unsaved changes, a clear warning message is shown asking whether they want to save, discard, or stay on the page - giving them full control and preventing accidental data loss.

---

#### **Imports**

##### Improve Payspace performance when fetching employee positions and extend logging in Payspace implementation (#146311)

**Problem**

- When pulling a large number of positions from PaySpace, it takes a very long time and fails. Logging is limited to debugging the PaySpace API calls and results

**Solution**

- Introduce several improvements and refactorings to the PaySpace user details import flow, focusing on simplifying data handling, improving logging, and enhancing error/warning reporting.
- The changes include updates to proto files, removal of unnecessary dependencies, streamlining of collection operations, and improved logging for better traceability and maintainability. Reduce the fields selected from the position call and implement parallel tasks to speed up processing by 5

##### Add additional unique field validation to pre-import validation (#144890)

**Problem**

- Correct creation and update of unique users' fields in import

**Solution**

- Refine the error messages for user creation and update failures in the `ImportUsersCommandHandler` to provide clearer and more accurate information about conflicts due to existing users. The changes clarify that the conflict is with another user and improve the details shown for matching fields.

##### Add additional unique field validation to pre-import validation (#144890)

**Problem**

- When importing users with the same fields, that is still unique, it is still allowed

**Solution**

- Introduce a Unique flag on SelfServiceSetting and wire it through the validation pipeline to support uniqueness checks for Email, ID Number, Passport Number and Employee Code. Precompute per-field value counts and a uniqueFields map in UserDetailsValidationService, and add duplicate-value checks that emit validation errors when a field marked unique is duplicated. Update all SelfServiceSetting construction sites to pass the new Unique flag and adjust related method signatures. Add unit tests covering unique-field scenarios and update existing tests accordingly.

---

#### **People Management**

##### Implement a unique field configuration on the ESS settings (#144890)

**Problem**

- Cannot define Username, Id Number, Passport Number, Employee Code, and Email as unique for the ruleset using ESS settings

**Solution**

- Introduce enhanced uniqueness validation for user-related operations, ensuring that users cannot be created or updated with duplicate key identifiers (such as username, employee code, ID number, passport number, or email) within the same ruleset, according to the ESS setup's unique field configuration. The changes span updates to the data model, gRPC contracts, and command handlers to support this feature.

---

#### **Performance Management**

##### Resolved check-in dial phases (#147902)

**Problem**

- On the overall summary check-in dial can not be opened unless ratings has been confirmed, discussion resulted in removing the requirement that ratings should be completed
- When a dial is clicked to view the ratings, even if the rating phase is no longer active, it can still be edited

**Solution**

- Removed ratings completed requirement
- Added Check-Ins phase active check to pass through that ensures if the edit modal can be opened or not

---

#### **Workplace Assessment App**

##### Implemented new endpoint for Observation app to upload stream file content (#143882)

**Problem**

- Endpoints created to allow the observation app to stream files, large files to service, due to http2 endpoints not being able to make public, normal http1 api transcoding takes place. But with large files, this causes timeouts and stream errors, for example, 60mb to be converted to a base64 string fails

**Solution**

- Added a new endpoint and proto to accept a streamed body file and use that to then send for the next method
- Add a new app setting to allow/regulate the upload max file size

---

# Version 9.1.224 (13 April 2026)

#### **Ruleset Management**

##### Fix the save button incorrectly disabled when changing the disclaimer acceptance message (#147508)

**Problem**

- When the display disclaimer toggle is inactive, and you change the acceptance message, the save button is incorrectly disabled.
- It should allow saving when the toggle is inactive and changing the disclaimer or acceptance message.
- Only when the toggle is active must the disclaimer/acceptance messages be required, and the save button be disabled when they have no value.

**Solution**

- Correct the onchange condition of the acceptance message to only disable the save button when the show disclaimer toggle is active, and no text is provided.

---

#### **Communication Portal**

##### Resolved discussions name not being searched on (#147601)

**Problem**

- When searching for discussions, the search for the discussion name is not implemented

**Solution**

- Added a change to search on the discussion name

---

#### **Performance Management**

##### Fix styling on User Banner for long usernames (#147662)

**Problem**

- With the current banner layout, when the user has a long username, collapsing the banner pushes the username down to fit into the container, causing the other elements to overflow the parent container's bounds.
- Slight misalignment issue on the expanded banner.

**Solution**

- Changed the layout of user information on the banner to be in line with the people management user details banner, to have the username always displayed on its own line below the name and surname.
- Adjusted styling accordingly to ensure proper alignment and no overflows when collapsed or expanded.

##### Fix issue where the perspectives list is not searchable (#147622)

**Problem**

- When adding a Perspective to a contract, the perspective list on the modal is not searchable.

**Solution**

- Added a callback to filter out the perspectives list when the search input is changed.

---

#### **Notifications**

##### Resolve anniversary emails being sent to terminated employees (#147374)

**Problem**

- Anniversary emails are being sent to inactive employees

**Solution**

- Resolve anniversary emails being sent to terminated employees

---

# Version 9.1.223 (13 April 2026)

#### **Imports**

##### Make grading types anonymous when running the Payspace connector on a schedule (#146311)

**Problem**

- When pulling grading types during the payspace import that runs on a schedule, an unauthenticated request is received

**Solution**

- This pull request introduces a minor change to the JobProfilerServiceV1 gRPC service by allowing anonymous access to the ListGradingTypes method.
- This update makes the endpoint accessible without authentication.

---

#### **Communication Portal**

##### Recipient and Owner incorrectly displayed (#147067)

**Problem**

- The results being returned are sorted by unread messages. Still, a rule exists that an entry occurs only when the user first opens this, causing NULL values, and that, when sorting this, it takes priority over 1 unread message, for example.
- When a user creates a discussion with another user, the owner sees the recipient's name when opening the discussion, but the recipient sees their name as well, instead of the owner's name

**Solution**

- Corrected order clause to match the same as wproperty
- Added a check to correctly retrieve the needed details depending on the owner-recipient.

##### Resolved the "save and add a new" issue (#147474)

**Problem**

- When a user opens a modal to add a new record, it gets the default values rendered for the colour picker and icon selection. Once they save and add a new one, the form gets cleared, but the default values are not initialised, causing an issue on save

**Solution**

- Add a correction to JavaScript to initialise the fields

---

#### **Performance Management**

##### Change popover display on contract to have all information combined into a single scrollable popover (#146587)

**Problem**

- Because of the new popover component and the fact that on a contract, there are multiple items that each have individual popovers, when you hover over each item quickly, it does not look great with all the popovers opening.

**Solution**

- Combined the popovers for all the L3 items into a single scrollable popover.
- Additionally, added a toggle on the contract footer that allows the user to disable the popovers from showing.

---

#### **Data Warehouse**

##### Resolved error with Audit\_ETLSSIS Package (#147404)

**Problem**

- The package failed for the Audit\_ETLSSIS Package due to a staging table that is not being used anymore, which causes a SQL Syntax error
- AuditID field is missing within the V9 DWHPackage creation of audUserAccess

**Solution**

- Removed Join within Insert of #AuditResults as the Staging Table is not being used anymore
- Added field AuditID within audUserAccess

---

#### **Main Dashboard**

##### Ensured the Kudos of large size can be read in the tooltip (#147381)

**Problem**

- When a large kudo message is sent, the entire message can not be read in the tooltip.

**Solution**

- Extended height and width params of SyncFusionPopover to SyncFusionPopoverWithEllipseText so the tooltip is scrollable.
- Increase the size of the maxPopOverLength parameter to ensure the entire message can be read.

---

#### **People Management**

##### Updating conditional data to match the current business rule (#147175)

**Problem**

- When updating the Start Date in Group/ Start Date in Company to another date (e.g., 2023) and then updating the Current Position start date, the updated Start Date in Group / Start Date in Company resets to the date that it was before the initial update.

**Solution**

- Applying the current business rule, the Start Date in Group / Start Date in Company should only be reset to the oldest appointment start date in appointment history if it is unset or if it is a more recent date than the oldest appointment start date

##### Updating datatable hidden field handling (#146324)

**Problem**

- Tables are not correctly centred within the card, causing layout and alignment issues.

**Solution**

- Updated how table columns are hidden to align with standard DataTables behaviour.
- This prevents hidden columns from affecting the layout and ensures the tables are properly centred

---

# Version 9.1.221 & 9.1.222 (13 April 2026)

#### **Data Warehouse**

##### Adjustments made within jpAppointments, jpJobPositions and jpReportingLines (#146998, #144482, #147178)

**Problem**

- New Status and Currency fields need to be added within jpJobPositions
- Currently, the Appointments are only being fetched and stored for active users
- The new field CurrentPosition needs to be implemented within jpAppointments
- The latest Appointments are being removed if the StartDates are the same

**Solution**

- Added fields PositionStatus, CurrencyName, MaxBudget, MinBudget, ValidFrom and ValidTo into JobPositions
- Adjusted the Insert script for Appointments to include inactive users
- Updated the IsLatestAppointment field to rather use CurrentPosition rather than manual calculation
- Updated step for Appointments to also check for the latest EndDates to ensure that the latest Appointment is not being deleted within the DWH
- Changed Update jpReportingLines\_Staging\_V9 to jpReportingLines to ensure that the latest user details are being captured from accUsers

##### Adjustments made within LearningManagementReport\_ETL (#144417, #147128)

**Problem**

- A step needs to be added for TermResults to fail learners if there are 2 or more subjects marked as absent
- Manual adjustments need to be made within StudentSubjects and TermResults

**Solution**

- Added a step to fail learners if there are 2 or more subjects marked as absent within TermResults
- Added manual tasks to update/delete entries within StudentSubjects and TermResults
- Removed step where marks are updated as NULL if captured as 0

---

#### **Master Data**

##### Resolved styling on tables (#145109)

**Problem**

- The master data tables were rendering with inconsistent row heights depending on whether they had an ORDER column.
- Tables with the ORDER column (like Communication Categories) displayed uniform row heights, while tables without it (like Communication Priorities) showed noticeably taller, uneven rows despite using the same underlying table structure and markup.

**Solution**

- Modified the initialisation logic to always initialise the DataTable regardless of whether the ORDER column exists, ensuring consistent styling across all master data tables.
- The rowReorder feature is now conditionally added to the configuration only when displayOrderExists is true, maintaining drag-and-drop functionality where needed while providing consistent visual presentation everywhere.

##### Resolved global search on items (#144639)

**Problem**

- Search is incorrect, wrong code in the file for master data

**Solution**

- Removed incorrect code and added a global search to the table

##### Fix Like and NotLike operators for conditions (#147155)

**Problem**

- Unable to filter on Operator 6 and 7 (like and not like) using master data conditions from the generic master data api call.

**Solution**

- Prepend and append filter value with '%' when using LIKE operator types

##### Resolved styling on colour-pickers (#145109)

**Problem**

- Styling for colour pickers-incorrect
- When opening the modal, it does not render the colour, or when changing

**Solution**

- Added styling updates after the upgrade; styling changed.
- Remove the colour-picker class, new styling on that class broke this, as it is only used for an identifier, changed safely

---

#### **System Access**

##### Resolved release history not updating (#147064)

**Problem**

- When clicking on the release history on the users profile, it loads and fails.
- When updating the release history and then saving, it fails on the save as it tries to retrieve EditedUser for auditing, but the entity has no fields relating to this

**Solution**

- Added an interface to not audit the release history view for a user

---

#### **Communication Portal**

##### Resolved Materialised Users not receiving updates (#147364)

**Problem**

- Using statements for contracts to be received from RabbitMQ events are referencing incorrect using statements, which caused no events to be consumed. So no users are updated for materialised users

**Solution**

- Corrected using statements

##### Resolved incorrect recipient information for new discussion (#147070)

**Problem**

- When starting a new discussion, incorrect details are shown on the recipient's existing channels
- When the user logs in and is not the owner, it shows its own details as if it were discussing with itself

**Solution**

- Correct SQL query
- Add a check to show the owner or recipient details

##### Adding additional styling (#146725)

**Problem**

- The table overlaps the card in the background.

**Solution**

- Added styling to ensure the card grows with the table

---

#### **Performance Management**

##### Resolve edge case where modifying objectives after approval and adding and/or removing items causes item weights to not sum to 100 (#147159)

**Problem**

- There are specific conditions where a user may modify previously approved objectives, and then proceed to add/remove perspectives, kpas and/or kpis.
- This manipulation after the fact messes with the previously calculated weights, and adding a new item results in the new weight calculated being either less than 0 or greater than 100 for the relevant item's KPA / Level2.
- This is mostly applicable to contracts where the Weighted over Section setting is enabled.
- This leads to a further edge case where, due to the mixture of high and low percentages on the weights, the calculated weighted averages of the KPAs end up as large decimal values with +10 precision, which all sum to 1 (100%).
- However, DB only permits decimals up to 4, implicit truncation happens and causes the calculation to gou out by 0.0002.
- This will create outliers during rating, where the item score may be off by a range of 0.001 - 0.01 when calculated.

**Solution**

- When the level2weight in this instance is less than zero, make it zero.
- This is done only when the weighted over-section setting is in use, and can be set to zero since the approval function will redistribute the weights accordingly.
- When the redistribution happens during the objectives approval, do a check to see if, from that perspective, the total kpa weight is not 100 (exceeds margin of error), and if so, redistribute the missing margin to the last kpa - &gt; kpi item.
- Eg, Last KPI goes from weight 0.0745 to 0.0747. Low enough difference in score to not have a major effect.

##### Removed duplicate icons on picker (#136654)

**Problem**

- Duplicate icons

**Solution**

- Removed duplicate icons

---

#### **Notifications**

##### Ensure invalid bcc and cc email addresses do not break the notification (#144960)

**Problem**

- Email processing fails when a template contains an invalid cc or bcc email address.

**Solution**

- When a template contains an invalid bcc or cc emails address, rather than throw an exception, clear it instead of breaking the entire process.
- Also, process templates within a try catch, so that if one template fails, it does not fail for other templates of the same event too.

---

#### **Translation**

##### Update French &amp; German translations (#145436)

**Problem**

- Missing translations and translated fields with incorrect context for French and German.

**Solution**

- Update all French and German translations with correct context based on en-GB

---

#### **Organisational Structure**

##### Resolved List Org Nodes check (#147309)

**Problem**

- In the List Org Nodes, there is a calculation done to see if the org node has any children, but it does not exclude deleted nodes, hence why that node can not be deleted

**Solution**

- Fix query to include a deleted check for the has children calculation

##### Resolved after adding new org node (#144475)

**Problem**

- After adding a new org path and then clicking on positions, the path is not populated on the right

**Solution**

- Corrected jQuery to the correct value to set the path

---

#### **People Management**

##### Add missing helpetext and drop down values (#146973, #146976, #146978, #146980, #147043, #147045, #147048)

**Problem**

- Add missing translations
- Add disabled master data

**Solution**

- This pull request introduces enhancements to the Job Profiler feature, focusing on better handling and display of future-dated positions, improved accessibility and guidance in the UI, and expanded localisation support.
- The changes include backend logic updates, frontend improvements for user experience, and the addition of new translation strings across multiple languages.

##### Request Replacement button not displaying (#146594)

**Problem**

- The "Request Requisition" button does not display when the Appoint New People group permission is disabled.

**Solution**

- Modified the logic so the Request Requisition button is independent of the Appoint New People permission

##### Add IsDefault switch back for banners when uploading and add translations (#147044)

**Problem**

- Not able to set banners as the default when uploading

**Solution**

- Add IsDefault switch back for banners when uploading and add translations

---

#### **Theme Management** 

##### Add stable version stamp to theme background URL to ensure it is cleaned from cache when changed (#147274)

**Problem**

- When you change the default login background image for a theme, it does not reflect on the login page.
- Because the browser/server caches the image, it never reloads the latest from the persistent volume on the pod.

**Solution**

- Added a stable version stamp to the background image.
- When it changes on the theme setup, it creates a new version tick; this value is retrieved by the login page and appended to the image URL.
- If no stamp, then we will fetch fresh from the volume.

##### Fixing styling issues (#146724)

**Problem**

- When editing a theme, some content does not fit within the layout on the left of the page.
- This causes a horizontal scrollbar to appear.
- Certain fields and buttons are also misaligned or extend beyond the visible area.

**Solution**

- Updated the layout and styling to ensure all content fits correctly and displays as expected.

---

#### **Job Management**

##### Added new Job to recalculate future appointments (#147134)

**Problem**

- New development uses an on-action calculation for the current position, meaning any interaction done on an appointment calculates which appointment is the active one, but for cases where a future appointment start date is set, once that date arrives at the current date, it does not move over unless a user does an interaction on the profile appointment

**Solution**

- Add a new job to use the recalculation service on the user IDs that have a future appointment date set that has arrived

---

#### **Ruleset Management**

##### Fix Change Icon button on System Menu tab not working (#147268)

**Problem**

- When setting up a Ruleset's System Menu, clicking the **Change Icon** button on any menu item had no effect — the icon picker dropdown never opened, making it impossible to change the icon for a menu item.

**Solution**

- Fixed the dropdown so it opens and works correctly.
- When an item is clicked, the icon preview updates immediately and the selection is saved when the form is submitted.
- The original curated list of available icons is preserved.

##### Added Global admin role as well (#146338)

**Problem**

- Oversight that did not add the Global admin role as well

**Solution**

- Added Global Admin

---

#### Identity and Authorisation

##### Allow http to https redirect to be forced on multiple domains (#147214)

**Problem**

- Current HTTP to HTTPS redirect is only allowed on one domain, but clients who have more than one domain behind a load balancer, where this is required

**Solution**

- Rather use a list of domains to verify against

##### Resolved autofill in details overlapping (#145431)

**Problem**

- Changes added to toggle on focus for autofill events on a browser tab that does not interact with the control to move the label, but in some cases, it does not always trigger, and every browser has different handling effects

**Solution**

- Added changes to more event handlers and timeouts to take into effect all browsers

---

#### **Event Scheduling**

##### Removing text-white from the important information section (#146502)

**Problem**

- The system opens the side modal with a section of the Important Information being very difficult to read.

**Solution**

- Updated the font colour so that the text becomes clearly visible and legible.

---

#### **Learning Management**

##### Add logging for SyncFusion registration on app initialisation and fallback function on marksheet to check for and register licence (#146996)

**Problem**

- Syncfusion invalid license is displayed on the Marksheet page.
- Cannot reproduce locally, the app init appears to not fire on production but happens on Master and local, hence why on prod it shows the invalid licence.
- Suspicion is that on prod due to environment setup or other factor, the app init never happens when marksheet is loaded (since loaded from external link and loads spa-minimal), and due to that the licence is never loaded.

**Solution**

- Added additional logging to assist with checking when the licence registration fires.
- Changed the Syncfusion setup component to keep tab on and expose IsLicenceRegistered to allow checking for that on the marksheet page.
- On Marksheet check if the licence is valid and register if not.

---

# Version 9.1.220 (13 April 2026)

#### **Event Scheduling**

##### Make the loading indicator smoother (#145136)

**Problem**

- On the Event Scheduling Calendar view, clicking an Event flashes the right-side modal. This was due to the loading indicator abruptly displaying and hiding instead of transitioning.

**Solution**

- Add a transition effect to the indicator, making its hiding and showing appear much smoother

##### Make event detail event clicking smoother (#145136)

**Problem**

- When events are open on the right side of the calendar, and you click on other events, the screen flashes.

**Solution**

- Cache event details so that they do not empty when loading the new details, which causes the empty details to be briefly rendered before rendering the new details, which results in the flashing.

---

#### **Data Warehouse**

##### Adjustments made within LearningManagementReport\_ETL (#144417)

**Problem**

- The Calculation for Pass or Fail did not calculate 100% for grades 10-12 due to missing subjects within the calculation
- The latest ModeratedMarks were not updated within lmStudentSubjects

**Solution**

- Updated Step to calculate Pass or Fail for Grade 10-12 within lmTermResults by including two new subjects
- Resolved issue where the 7 hours ago latest Moderated or Calculated Marks were not used within step "Update fields CalculatedMark and ModeratedMark within #ResultsTI" for StudentSubjects

##### Added the latest V9 DWH Package to the repo (#143176)

**Problem**

- The latest V9 DWH Package needs to be added to the repo as backup after Live deployment

**Solution**

- Added the latest V9 DWH Package to the repo

##### Removed Previous SQL Scripts that are not part of the Code Review Folder Structure (#145986)

**Problem**

- There are previous SQL files that were used for the Code Review process before the new folder structure was added

**Solution**

- Removed Previous SQL Scripts that are not part of the Code Review Folder Structure

##### Added field Completed within pdmContractPeriodActionPlans (#146665)

**Problem**

- Field Completed is required within pdmContractPeriodActionPlans

**Solution**

- Added field Completed within pdmContractPeriodActionPlans

##### Updated Existing DataSourceFields (#146665)

**Problem**

- Field Progress needs to be renamed to Milestones within ContractPeriodActionPlans

**Solution**

- Update FieldAlias "Progress" to "Milestones" for DataSource ContractPeriodActionPlans

##### Added field "CustomField" within lmStudentSubjects (#144417)

**Problem**

- Field CustomField is required within lmStudentSubjects

**Solution**

- Added field "CustomField" within lmStudentSubjects

---

#### **Communication Portal**

##### Resolved extra column on file attachment (#146678)

**Problem**

- Extra icon on the left-hand side when sending an attachment

**Solution**

- Remove column

##### Resolved New discussions not shown first (#147067)

**Problem**

- Discussions with new messages are not prioritised at the top

**Solution**

- Add an order clause to correct the new message shown at the top

##### Removed Flags (#146682)

**Problem**

- Flag Icons render within the library differently and return Unicode when the text is extracted

**Solution**

- Removed Flag Category of Emojis

##### Remove inappropriate icons (#146683)

**Problem**

- Certain icons are references in the library that can be used, which is not ideal for children who have access to the icon picker

**Solution**

- Remove the few icons that could be identified

##### Added new Reload icon button (#146674)

**Problem**

- V8 does not allow signal-R updates currently, so no way to refresh the views or indicate when the user is on a page

**Solution**

- Add a new reload button to refresh the discussions

##### Added loading indicator for external clients using package (#146681)

**Problem**

- When within external service, there is no loading indicator that gets triggered, as this is the V9 reference loaders.

**Solution**

- Add a loading component to be used for external clients using the package(v8)

##### Corrected business rule on subject type ignores global setting for discussions disabled (#146739)

**Problem**

- When the global setting of discussions is disabled, a user can not open or create any discussion

**Solution**

- Add a business rule that if it is of a certain subject type, it is allowed to continue

##### Resolved Text overlapping tone colours on emojionearea (#146680)

**Problem**

- In the Emojione area, the tone colours and the first heading overlap one another

**Solution**

- Added override styling to add margin to the tones to push content down

##### Resolved Icon Search Background Colour (#146674)

**Problem**

- V9 colour is calculated from the site CSS with the current background colour lightened. Which V8 does not have

**Solution**

- Add a new Model check if step type is of type topic, add the v8 background colour

---

#### **Ruleset Management**

##### Nullify client secret in payroll connector (#146732)

**Problem**

- Client secret available in plain text on inspection of payroll connectors

**Solution**

- Nullify client secret

##### Correct actions and delete on the payroll connector list (#146588)

**Problem**

- Cannot open the kebab menu on the payroll connector list
- Cannot delete a payroll connector
- PowerShell scripts are too lengthy in the list

**Solution**

- This pull request improves the user interface and user experience for the Ruleset integration management page in both the backend view and the frontend JavaScript. The changes focus on enhancing usability, accessibility, and code maintainability, particularly around dropdown menus, script display, and modal confirmation behaviour.

##### Themes drop-down not loading for system menu items (#146750)

**Problem**

- When a menu item is selected, the page content is loaded dynamically. The themes dropdown was not being initialised as part of that process, so clicking it had no effect.

**Solution**

- Added code to explicitly initialise the themes dropdown each time the page content is loaded, so it responds correctly when clicked.

---

#### **Job Management**

##### Resolved people group org unit selection in tree view modal (#145942)

**Problem**

- Org Unit on tree view modal not rendering, and incorrect nodes are shown; no implementation done for the nodes, incorrect logic on the page

**Solution**

- Added new logic and handler events to handle the different selections

##### Resolved ordering on appointment history (#145442)

**Problem**

- When no order has been identified by defaults it is ordered by the first column, which overrides the foreach on initial data order

**Solution**

- Add the calculation to order by the correct start data

##### Duplicate subordinates returning (#146924)

**Problem**

- The API endpoint ListManagerSubordinatesSimplified returns duplicate subordinates

**Solution**

- Added a distinct keyword to ensure unique subordinates are returning.

##### Add position activation functionality and future planning (#139481)

**Problem**

- A position cannot be reactivated from the front-end. Future planning cannot be captured

**Solution**

- Add active switches to the position list page
- Add a future planning section to position creation
- As a People Management Administrator, I want to be able to set the status of each position (e.g., Planned, Budgeted, Unapproved, Approved), so that I can generate categorised reports for better workforce planning.
- As a People Management Administrator, I want to be able to define the validity period of each position (e.g., Valid From and Valid To), so that I can track position timelines.
- Helper text must show that it is for future use as well.
- As a People Management Administrator, I want to be able to specify the Minimum and Maximum Budget for each position, so that I can analyse and report on budget allocations across positions.
- As a People Management Administrator, I want to see the newly entered data on the Job Management page, where all the positions are summarised.
- Custom styles for the date filter have been added to the position HTML so as not to override the global CSS, which seems to be an issue only on these pages

##### ListOrgUsers endpoint returns future and terminated employees (#146921)

**Problem**

- The ListOrgUsers endpoint returns terminated or future appointments

**Solution**

- Added the new IsCurrentPosition check to filter out terminated and future appointments.

---

#### **Identity and Authorisation**

##### Resolved Disclaimers (#145552)

**Problem**

- An incorrect logic check existed for the ruleset disclaimer before pulling the job profile disclaimer details. Redirect occurring from disclaimers back to the login screen

**Solution**

- Resolved if check, Changed logic checks to ensure context items are added if accepted and not based on their render mode from Razor if conditions
- Added a redirect check to redirect to the disclaimer page again instead of all the way back to login

##### Cleanup expired ID tokens (#144999)

**Problem**

- Expired tokens in OpenIddictTokens will become a performance problem as an index was removed during the .NET 10 upgrade

**Solution**

- Create a quartz job to remove expired tokens at 4 am every day

---

#### **Content Management**

##### Centralise decryption of NextCloud credentials (#147083)

**Problem**

- The decryption feature is missing in the OCI Share link development
- The integration setup is confusing because it sometimes includes an encrypted client secret while at other times it does not.

**Solution**

- Implemented the missing decryption feature
- Ensured that the encrypted data is always stored in a secret and that a public method is used for decryption.

##### Next cloud not working due to missing config (#146727)

**Problem**

- The missing configuration is causing the next cloud to break

**Solution**

- Add encryption keys to the Content management appsettings

##### Upload of and handling of evidence using the workplace assessment app (#143882)

**Problem**

- There is currently no way to upload evidence on a question, e.g., a short video or photo

**Solution**

- If you are online, sync starts in the background and will even continue when the app is closed
- Compress evidence using the V9 compression service, and store compressed evidence in the local entity
- Sync back to V8 once compressed evidence is ready, prompt the user to Submit
- Send compressed content to the content service and store the ContentId against answers
- On V8, when the submit method is called, send ContentId in AssessmentAttemptDTO with the Questions object - one to many
- If the user has an access token for V9, use this to access the content; else, use stored credentials for api user to upload content
- On People Management &gt; Assessment List, if evidence is available to attempt per question, make the "Download evidence" link available

---

#### **People Management**

##### Use StartDateInCompany to calculate work anniversary (#146800)

**Problem**

- On the people management dashboard, the work anniversary query currently uses the user's current position to determine the date, rather than the user's start date with the company

**Solution**

- Return StartDateInCompany to PeopleController and use it for work anniversary mapping

##### Reporting Lines on Summary Page not underlined as a link (#145925)

**Problem**

- Reporting lines have no on-hover effect (underline)

**Solution**

- Move hover class anchor tag

##### When moving an org node to another parent node, correct the update of the calculated org flat path (#146379)

**Problem**

- When moving an org node, the calculated org flat path is not updated

**Solution**

- This pull request updates the UpdateOrgStructureParentCommandHandler to improve how changes to the organisational structure are handled. The main change is the addition of logic to update the flattened organisational path after a parent update, ensuring data consistency across related structures.

---

#### **Notifications**

##### Newly appointed users are getting work anniversary notifications by only returning records of tenure greater than 0 (#146919)

**Problem**

- Work Anniversaries email is being sent on the appointment date to new users

**Solution**

- Resolve the problem of newly appointed users getting work anniversary notifications by only returning records of tenure greater than 0

##### Add a line break before the V9 footer to allow space between the email body (#146666)

**Problem**

- The V9 build in the footer sometimes touches the normal email body

**Solution**

- Add a line break before the V9 footer to allow space between the email body and the footer.

---

#### **Imports**

##### Ruleset Culture never sent to v8 for schema setup (#134516)

**Problem**

- The ruleset's culture is never sent to the v8 schema setup endpoint; this results in en-GB always being set in V8.

**Solution**

- Added the culture to the API request for v8.

##### Correct the delta check for optional staging for the import data (#145548)

**Problem**

- When the appointment details have not changed, but the other personal details have changed, the user data is not staged for import

**Solution**

- Move the appointment to a conditional OR with the other personal details.

##### Ensuring that the link to download the User Validation Report is only shown for User imports and PaySpace Pull imports. (#146598)

**Problem**

- The link to download the User Validation Report is shown for reports for which it does not work.

**Solution**

- Hiding the User Validation Report download link for all reports except the select few reports for which it works.

---

#### **Tenant Management**

##### Use the system Close Date to change the colour to Red (#146313)

**Problem**

- The system does not use the system's Close Date to change the colour to Red

**Solution**

- Update expiry colour display condition to only display on the close date within 1 month

##### As a Consultant or Tenant Admin, I want the Expiry Date to be set at the end of the following month by default (#144228)

**Problem**

- When creating a tenant, the expiry and system close date are not defaulted to the end of next month, and boolean values for lock system and display expiry messages are not defaulted to disabled. Page also not ordered by expiry date ascending.

**Solution**

- Tenant creation defaults expiry and close date to the end of next month. Lock system and expiry messages display defaulted to disabled, and the page is ordered by expiry date ascending by default.

##### As a Tenant Administrator on R1, I want to have updates to the Update Expiry Date modal (#144227)

**Problem**

- New expiry date should be the same as the current expiry date; buttons need to be added to quickly set dates (for end of this week, end of next week, etc); and a new toggle to be added to enable and disable subscription expiry and system close notifications

**Solution**

- New expiry date defaulted to current expiry date; 4 buttons added to quickly set the dates; new toggle added which persists in the database against the subscription, and displays value; and then added logic to ensure when disabled, no system expiry or close notifications are sent

---

#### **Performance Management**

##### Inform user buttons are to create agreement for the selected period (#142925)

**Problem**

- When you move past the review setup tabs at the top, the narrator will simply read the names of the buttons, which will be the same as the names of the tabs. This can be confusing.

**Solution**

- Include the review setup component as a tab index

##### Inform the user that the page is loading when creating an agreement (#142928)

**Problem**

- Loading is not verbally indicated by NVDA

**Solution**

- Indicate loading when creating contract

##### Narrator mentions heading types and sizes (#142929)

**Problem**

- NVDA reads heading levels (h4, h6)

**Solution**

- Suppress the heading levels where possible

##### Unable to interact with my own agreement (#142931)

**Problem**

- Tab navigation is not complete when tabbed past timelines

**Solution**

- Update tab order and inclusion

##### Investigate the possibility of adding pauses between phrases (#142918)

**Problem**

- It is sometimes a bit difficult to follow what the narrator is saying because they ramble off sentences without pausing. Please investigate if it is possible to add some pauses so that you can more easily distinguish between different concepts.

**Solution**

- Create tab-list and add aria improvements to improve flow and readability. Also added accessibility sentence to translations.

##### Review setup container not selected (#142933)

**Problem**

- The tablist forces you to tab through all items to progress.

**Solution**

- Create an index for the entire tab list, and allow the user to press enter to tab through the list, or tab over the list

##### Screen flickers when moving the mouse pointer over the period label (#144966)

**Problem**

- When hovering over some elements that have a popover, it continues to re-render and the popover flickers, as if its visibility state is constantly changed.

**Solution**

- Memoised the popover properties so that it does not re-render when anything else on the dashboard changes.
- Found an additional issue where for a fraction of a second, the popover is shown topleft of the viewport before it positions where it's supposed to. Enforced additional CSS onto the popover to attempt to prevent that from happening.

---

#### **System Access**

##### Encrypt secrets, passwords and tokens (#144974)

**Problem**

- Secrets, passwords and tokens used in V9 are stored in clear text

**Solution**

- Encrypt and decrypt secrets, passwords and tokens when records are stored and fetched from the database by means of changes to OnModelCreating

---

#### **Technical**

##### Syncfusion license key is visible in dev tools (#144510)

**Problem**

- SyncFusion license key is available in clear text in the local storage view in dev tools.

**Solution**

- Remove the license key from local storage; instead, make the lightweight api call. Also, encode the response, and decode it in code

##### Media compression process (#140481)

**Problem**

- Currently media is uploaded in its original size to the system without being compressed or optimised

**Solution**

- Implement a PowerShell script to
- Compress uploaded media
- Remove original large media
- Keep track of what was compressed to compress once

---

# Version 9.1.219.7 (Support Release - 22 April 2026)

#### **People Groups**

##### Correct problem with user people group fetch excluding appointments that end on the current day (#147959)

**Problem**

- When a user's appointment ends on the current day, then no people groups are returned on which the user is a part of, resulting in no menu items being displayed.

**Solution**

- Correct the filter condition on the query to consider the end date of the appointment as inclusive.

---

# Version 9.1.219.6 (Support Release - 9 April 2026)

#### **Imports**

##### Make grading types anonymous when running Payspace connector on a schedule (#146311)

**Problem**

- When pulling grading types during the payspace import that runs on a schedule, an unauthenticated request is received

**Solution**

- This pull request introduces a minor change to the JobProfilerServiceV1 gRPC service by allowing anonymous access to the ListGradingTypes method. This update makes the endpoint accessible without authentication.

---

# Version 9.1.219.5 (Support Release - 2 April 2026)

#### **Communication Portal**

##### Resolved Incorrect object null message (#147387)

**Problem**

- The problem with the Dapper query binding to the record was fixed on master, but on release, this issue arose. Could nit-pick over the base on a large development change

**Solution**

- Change from the init constructor to properties

---

#### **Performance Management**

##### Resolve edge case where modifying objectives after approval and adding and/or removing items causes item weights to not sum to 100 (#147159)

**Problem**

- There are specific conditions where a user may modify previously approved objectives, and then proceed to add/remove perspectives, kpas and/or kpis.
- This manipulation after the fact messes with the previously calculated weights, and adding a new item results in the new weight calculated being either less than 0 or greater than 100 for the relevant item's KPA / Level2.
- This is mostly applicable to contracts where the Weighted over Section setting is enabled.
- This leads to a further edge case where, due to the mixture of high and low percentages on the weights, the calculated weighted averages of the KPAs end up as large decimal values with +10 precision, which all sum to 1 (100%).
- However, DB only permits decimals up to 4, and implicit truncation happens and causes the calculation to go out by 0.0002.
- This will create outliers during rating, where the item score may be out by a range of 0.001 - 0.01 when calculated.

**Solution**

- When the level2weight in this instance is less than zero, make it zero.
- This is done only when the weighted over-section setting is in use, and can be set to zero since the approval function will redistribute the weights accordingly.
- When the redistribution happens during the objectives approval, do a check to see if, from that perspective, the total kpa weight is not 100 (exceeds margin of error), and if so, redistribute the missing margin to the last kpa - &gt; kpi item.
- Eg, Last KPI goes from weight 0.0745 to 0.0747. Low enough difference in score to not have a major effect.

---

# Version 9.1.219.4 (Support Release - 3 March 2026)

#### **Theme Management**

##### Add stable version stamp to theme background URL to ensure it is cleaned from cache when changed (#147274)

**Problem**

- When you change the default login background image for a theme, it does not reflect on the login page.
- Because the browser/server caches the image, it never reloads the latest from the persistent volume on the pod.

**Solution**

- Added a stable version stamp to the background image.
- When it changes on the theme setup, it creates a new version tick; this value is retrieved by the login page and appended to the image URL. If no stamp, then we will fetch fresh from the volume.

##### Themes drop-down not loading for system menu items (#146750)

**Problem**

- When a menu item is selected, the page content is loaded dynamically.
- The themes dropdown was not being initialised as part of that process, so clicking it had no effect.

**Solution**

- Added code to explicitly initialise the themes dropdown each time the page content is loaded, so it responds correctly when clicked.

---

#### **Ruleset Management**

##### Change Icon button on System Menu tab not working (#147268)

**Problem**

- When setting up a Ruleset's System Menu, clicking the **Change Icon** button on any menu item had no effect — the icon picker dropdown never opened, making it impossible to change the icon for a menu item.

**Solution**

- Fixed the dropdown so it opens and works correctly. When an item is clicked, the icon preview updates immediately and the selection is saved when the form is submitted. The original curated list of available icons is preserved.

---

# Version 9.1.219.3 (Support Release - 30 March 2026)

#### **Identity and Authorisation**

##### Allow http to https redirect to be forced on multiple domains (#147214)

**Problem**

- Current HTTP to HTTPS redirect is only allowed on one domain, but clients with more than one domain behind a load balancer require this

**Solution**

- Rather use a list of domains to verify against

---

#### **Imports**

##### Improve performance of user validation report (#145548)

**Problem**

- Compare map data between the current data and the new data sources, a lot of memory
- The data is fetched from the account, and the job profiler is slow for a large number of users
- When the generated file is more than 30MB, it cannot be sent to the content management for storage

**Solution**

- Implement Hash sets in the compare data method
- Implement streaming of Data from the account and job profiler for comparison
- The dictionary of results to MVC
- The Excel document for content management

---

# Version 9.1.219.2 (Support Release - 27 March 2026)

#### **Identity and Authorisation**

##### Resolved autofill in details overlapping (#145431)

**Problem**

- Changes added to toggle on focus for autofill events on a browser tab that does not interact with the control to move the label, but in some cases, it does not always trigger, and every browser has different handling effects

**Solution**

- Added changes to more event handlers and timeouts to take into effect all browsers

---

# Version 9.1.219.1 (Support Release - 26 March 2026)

#### **Imports**

##### PaySpace API | Not returning Job Grades (#146224)

**Problem**

- Grades are not uniquely imported for job profiles from Payspace
- A setting is not available per the payroll connector to define the grading type
- When synchronisation is automatically disabled, but the schedule is still active, the PowerShell and PaySpace connectors still run regardless.
- Unable to edit and save a Payspace connector without providing the secret again

**Solution**

- This change introduces support for associating a "Grading Type" with payroll connectors, including database, domain, API, and gRPC/protobuf changes.
- It also removes several unused payroll providers and makes minor improvements to import command handling and logging.
- Correct schedules so that they do not import automatically when auto sync is disabled, even though the schedule is still active.

---

#### **Ruleset Management**

##### Resolved incorrect role on Upsert virtual tours (#146338)

**Problem**

- The incorrect role is being authorised to save virtual tours

**Solution**

- Corrected role to RulesetAdmin

---

#### **Identity and Authorisation**

##### Resolved Disclaimers (#145552)

**Problem**

- An incorrect logic check existed for the ruleset disclaimer before pulling job profile disclaimer details
- Redirect occurring from disclaimers back to the login screen

**Solution**

- Resolved if check
- Changed logic checks to ensure context items are added if accepted and not based on their render mode from Razor if conditions
- Added a redirect check to redirect to the disclaimer page again instead of all the way back to login

---

#### **Learning Management**

##### Add logging for SyncFusion registration on app initialisation and fallback function on marksheet to check for and register licence (#146996)

**Problem**

- Syncfusion invalid license is displayed on the Marksheet page.
- Cannot reproduce locally, the app init appears not to fire on production, but happens on Master and local, hence why on prod it shows the invalid licence.
- Suspicion is that on prod due to environment setup or other factor, the app init never happens when marksheet is loaded (since loaded from external link and loads spa-minimal), and due to that the licence is never loaded.

**Solution**

- Added additional logging to assist with checking when the licence registration fires.
- Changed the Syncfusion setup component to keep tab on and expose IsLicenceRegistered to allow checking for that on the marksheet page.
- On the Marksheet, check if the licence is valid and register if not.

---

#### **Performance Management**

##### The section weight labels overlap other weight labels (#147088)

**Problem**

The section weight label is overlapping onto the perspective or kpa label, especially visibly when the weighted over section setting is on.

**Solution**

Resolve styling issue causing section weight to overlap onto other labels

---

# Version 9.1.219 (23 March 2026)

#### **HR Processes**

##### Ensure file table cannot be filtered (#146728)

**Problem**

- When using global search on HR processes, it also filters the files table (which is incorrect) and results in no files being displayed.

**Solution**

- Remove the filter/search capability from the files table so that it is not affected by the global search

---

#### **Performance Management**

##### Updated Export button's look and feel (#146586)

**Problem**

- The "Export" button on the View/Print page does not have the same style as other similar buttons on the system.

**Solution**

- Changed export button text to export icon. Updated the button style so that it looks the same as the print button.

---

#### **People Management**

##### Adding missing text to display on "Not finding the person" modal (#146696)

**Problem**

- There is some information missing on the "Not finding the person" modal.

**Solution**

- An additional bullet point was added to the "Not finding the person" modal.

---

#### **Ruleset Management**

##### Ensure that when no new payroll secret is set on update, to reuse the secret (#146425)

**Problem**

- Empty secrets sent from payroll connectors cause persistence errors

**Solution**

- Ensure that when no secret is sent, reuse the existing secret

##### Trimmed leading space from theme (#146654)

**Problem**

- When creating a new theme, leading spaces are not removed if a user adds them

**Solution**

- Trim the space on the Name and code before saving

---

#### **Imports**

##### Auto-populate the reporting line for the PDP manager based on the line manager (#146225)

- Added a custom step to auto-populate the PDP reporting lines with the Line Manager's details (PaySpace import: the reporting lines must be updated automatically)

---

# Version 9.1.218 (23 March 2026)

#### **Report Builder**

##### Resolved SubReport can not be exported (#146574)

**Problem**

- Missing NPM package. Incorrect logic for building the pivot report details, no header values, and incorrect counts starting
- On the building of the subreport dropdown buttons, not being initialised after being dynamically built

**Solution**

- Added npm package
- Corrected logic for rebuilding the output to the Excel file export
- Initialised the MDB dropdowns after being built

##### Implemented Excel Type replace for Pivot Table reports (#141028)

**Problem**

- When adding multiple columns to pivot on, the back-end runs into a SQL limitation of the length of column name of 128 characters

**Solution**

- When generating the script to execute and formulate columns to pivot, create a new mapping table to reference each column name to an Excel-type column 'A, B .. AA, AB' to allow several columns, and before returning, remap to keep the code and logic as needed.

##### Avoid intermittent Export Errors (#146243)

**Problem**

- Intermittent errors happen because we don't wait for the file to be exported

**Solution**

- Wait for the file to be exported, and don't go out of scope

---

#### **Identity**

##### Ensure v8 fallback is only used when v9 password is not set (#146607)

**Problem**

- Users are still able to authenticate using the v8 password after the v9 password was set.

**Solution**

- Ensure v8 fallback is only used when v9 password is not set

##### V8 password fallback on login (#146398)

**Problem**

- When migrating to V10, a user needs to reset their password to log in and cannot continue using their V8 password until the V9 expiry is reached.

**Solution**

- Introduce support for validating legacy ("v8") password hashes as a fallback authentication mechanism in the identity service.
- The changes span the application, database schema, and data access layers to enable seamless login for users with older password hashes.
- The most important changes are grouped below.
- These changes ensure backward compatibility for users with older password hashes while maintaining the integrity of the authentication process.

##### Added UI validation check on confirm password and space for recaptcha (#146286)

**Problem**

- Submission can be done, which then results in an error from the backend that the password and the confirmation password do not match

**Solution**

- Add a UI check to restrict and show a validation error message from the frontend side

---

#### **Event Scheduler**

##### Added event name and ref nr on the confirmation modal (#146253)

**Problem**

- After booking yourself onto an event, the booking confirmation pop-up does not show the event reference number.

**Solution**

- Updated the booking confirmation pop-up to show the event name and its reference number.

##### Changing button font colour (#146255)

**Problem**

- The system displays the Booking confirmation modal with the "Modify Booking" button not being easily readable due to the Font Color.

**Solution**

- Update font colour to white to make the "Modify Booking" button easily readable.

##### Added logic to save when whoCanBook is changed with a confirmation Modal (#145624)

**Problem**

- When you change Who Can Book from Everyone to one of the other options, you can’t add people groups until you save first.

**Solution**

- Switching between Who Can Book options now saves automatically.
- A confirmation pop-up appears when switching to Everyone to prevent accidental changes.
- This helps avoid losing any people groups that were already added.

##### When marking attendance, and there is only one session, default the drop-down to that session (#146256)

**Problem**

- The default does not show the session if there are no multiples

**Solution**

- When marking attendance, and there is only one session, default the drop-down to that session

##### No master data for Motivation for booking default values (#146251)

<div id="bkmrk-problem-10">**Problem**</div><div id="bkmrk-no-master-data-for-m-1">- No master data for Motivation for booking default values.

   
**Solution**</div><div id="bkmrk-ensure-master-data-f">- Ensure master data for learning management is copied over.

</div>##### Event Scheduling: Selecting an event/day on the calendar view opens a modal instead of the side view (#145136)

**Problem**

- Selecting an event/day on the calendar view opens a modal instead of the side view

**Solution**

- When clicking on an event on the calendar, do not open a modal; open the side menu.

---

#### **People Management**

##### Updated styling on the data tables (#146324)

**Problem**

- Paging controls are displayed even when there are not enough items to require paging.
- They should only appear when the number of items exceeds the paging limit.
- The delete icon is also not aligned correctly
- It should appear against the right edge of the table, but there is currently extra spacing.

**Solution**

- Updated the layout and styling so that paging controls only appear when needed.
- Adjusted the spacing to correctly align the delete icon with the right edge of the table.

---

#### **Performance Management**

##### Changed DateTime Picker to Date picker (#146543)

**Problem**

- The new date picker that has been added to the due date field when adding action plans now has a button to select the time as well.

**Solution**

- Removed the time picker.

##### Updating Score Label Mapping cards to white background (#146352)

**Problem**

- On the Score Label Mapping page (under Performance Years → Review Setups), the mapping header and options are not displayed within the card with the scoring criteria, making the section harder to read.

**Solution**

- Updated the styling so that the mapping header and options are displayed within the card, improving clarity and layout.

#### **No date picker on Action plans (#146349)**

**Problem**

- Date time picker not rendering on action plans when using dayjs

**Solution**

- Changed to make use of Syncfusion's picker

##### Add change to calculate running score when copying manager score to final rating score (#146110)

**Problem**

**Solution**

- Added a new change to calculate the running score when copying the manager rating to the final rating

---

#### **Master Data**

##### Fix ListMasterData filter by properly parsing values (#146258)

**Problem**

- Filtering for ListMasterData in JobProfiler/ExportDataService did not work due to the value being improperly parsed as a string.

**Solution**

- Handle different GRPC value types to properly convert the value to the primitive type before calling.ToString()

---

#### **General**

##### Replace broken popover component with new custom SyncFusion Popover component (#144966)

**Problem**

- Popover on React pages is misaligned and does not behave correctly anymore due to the recent package upgrades. Previous attempts to fix it were unsuccessful, so we decided to replace it with a new popover component.

**Solution**

- Replaced usages of Popover with the new SyncFusionPopover component, a custom component built on the SyncFusion library that works correctly and provides more options for interactability.

---

#### **Data Warehouse**

##### Adjusted StudentSubjects to include records with ModeratedMark (#144417)

**Problem**

- The DWH currently removes the subjects if all the marks are -1, regardless of whether it has a moderated mark within StudentSubjects

**Solution**

- Added step within StudentSubjects to keep records for scenarios where either all the marks are -1 or where all the marks are -1, but it also has a Moderated Mark

##### Updated Delete steps for LearningManagement\_ETL SSIS Package (#142737)

**Problem**

- The package can fail if LearningManagement is set to false within PackageSettings, which is caused by the delete step for each Data Source within LearningManagement\_ETL SSIS Package

**Solution**

- Added IF EXISTS check to prevent deletes when LearningManagement is set to false in PackageSettings for SSIS Package LearningManagement\_ETL

##### Added updates for Data Dictionary (#146242)

**Problem**

- By default, the People Data Source is named as Users - ID Number, which is set by default not to be selectable

**Solution**

- Added Step to rename Data Source Users to People - Added Step to set field ID Number as selectable and searchable

##### Corrected step for cmFileTypeContents (#143697)

**Problem**

- The package failed on step "Delete cmFileTypeContents" due to an incorrect field name.

**Solution**

- Updated script to use the correct date name field within step "Delete cmFileTypeContents"

##### Created new Folders for DWH Code Review Process (#145986)

**Problem**

- It is currently difficult to review the DWH scripts due to how SSIS packages work

**Solution**

- Created folders and aligned the container steps that will assist in making code reviews easier using GitHub

##### Adjusted step within pdmContracts for OverallFinalScore calculations (#146110)

**Problem**

- Currently, the OverallFinalScore are not being updated correctly due to the reference data that is being used

**Solution**

- Updated step by removing @ReferenceDate and added a check if Script is being executed between 12 and 2 am within IF EXISTS to ensure that the OverallFinalScore are being updated correctly within pdmContracts

---

#### **Tenant Management**

##### Resolve select2 positioning issue (#146533)

**Problem**

- The search box was working, but was not rendering relative to its position after scrolling.

**Solution**

- Ensure the search box appears relative to the clicked spot after scrolling, and clear out any previously opened search boxes

---

#### **Imports**

##### Add JobProfiler pre-import procedure to remove overlapping appointments (#144266)

**Problem**

- When importing data, all overlapping appointments that may cause a rejection should be removed to prevent rejection.

**Solution**

- Add a custom pre-import script to remove overlapping breaking positions for the user and position.

---

#### **Learning Management**

##### Resolve the success message not showing on the marksheet and allow the moderated mark to be removed (#146077)

**Problem**

- Success snackbar not showing when saving, also not able to remove the moderated mark.

**Solution**

- Resolve the success message not showing on the marksheet and allow the moderated mark to be removed.
- Snackbar is not properly loaded in the SPA minimal page.
- Created a helper snack to re-use in spa-mimimal pages.

---

# Version 9.1.217 (23 March 2026)

#### **People Management**

##### Fix adding Employment History opens blank modal (#146276)

**Problem**

- Adding Employment History opens a blank modal

**Solution**

- Hook the button click event on the document to ensure the event is always bound

##### Resolved Dashboard work anniversary date (#143995)

**Problem**

- On the dashboard, the work anniversary is using a custom calculation and not the same method as the people dashboard uses

**Solution**

- Updated method being used, as well as including the start date in the company as requested to be used, should it have a value

##### Resolve the issue where you cannot add an appointment for a user when the appointment history is viewed from the summary page (#146062)

**Problem**

- When trying to add an appointment, the '+ Appointment' button does nothing; you have to click on another submenu item within the appointment section and then back to appointment history before the button works.

**Solution**

- Changed the click event to bind on a class and not the Id of the button, the button does not seem to be immediately available when the partial is being rendered and the event cannot be bound. Also removed an incorrect id on the Transfer person button that caused duplicate element IDs to exist in the markup.

##### Add materialise people group users tooling and extend the limited API to allow partial refresh (#146057)

**Problem**

- The people group materialisation queue is flooded with queue requests, causing the materialisation process to take excessively long. The distribution to other services also causes extreme delay.

**Solution**

- Add SQL and orchestration tooling to materialise/sync people group users across environments and wire through API flags.
- Add stored procedures and types: 
    - JobProfiler.GetRulesetPeopleGroupsForMaterialisation
    - JobProfiler.PeopleGroupIdList (TVP)
    - JobProfiler.SyncMaterialisedPeopleGroupUsers to select, prepare and merge materialised people group users.
- Add RecalculateMaterialisedPeopleGroupUsers.ps1 and task XML to orchestrate fetching people-group users via the JobProfiler API, batch processing, and calling the sync proc (supports preview mode, batching and logging).
- Update gRPC proto (people\_groups.v1.proto) to include always\_recalculate and bust\_cache request fields and pass them through in PeopleGroupsServiceV1.
- These changes enable controlled synchronisation of materialised people-group users, with options to force recalculation and bust cache, plus a PowerShell orchestrator to run the process and preview changes before committing.
- PowerShell script: Fetch the people groups to process for all rulesets or a specific ruleset.
- Choose all active people groups or only the people groups that have an unprocessed log in the materialised data log queue.
- Using the limited people group users API, refresh the calculated people group user.
- Bust the Redis cache.
- Process the people groups in batches of 150 to keep the CPU and memory used limited.
- Materialise each ruleset's users at the end using a merge statement

---

#### **Report Builder**

##### Added authorisation checks when running reports to ensure that the user has report permission (#146156)

**Problem**

- Although the report permissions are enforced on the front end and only display the available reports that the user has access to, should the user have the URL or report ID for any other report, they can still run and view the report.

**Solution**

- Cache user report access and perform validation when running a report to ensure that the user has the required access.

---

#### **System Access**

##### System Menu target audience not being able to select any values (#146218)

**Problem**

- When linking people groups in the System Menu, existing (previously saved) items were not displaying as checked checkboxes after reload. Instead, they appeared as either

**Solution**

- Always render the checkboxes, as the existing linked target audiences can not be interacted with.

---

#### **Performance Management**

##### KPI and KPA tooltips causing styling issues (#146000)

**Problem**

- KPIs and KPAs tooltips are currently causing incorrect styling for Review Setup Templates

**Solution**

- Removed jQuery tooltips, added, as they conflict with MDB tooltips, also added a title tag to the KPIs to ensure the tooltips are displayed.

##### Ensure Bulk Recalculation Errors are properly logged, and the batch status is correctly updated (144245)

**Problem**

- When bulk recalculations fail due to an unhandled exception, the batch status remains unprocessed, and the items don't indicate the failure.

**Solution**

- Ensure bulk recalculation failures are properly logged and status updated. Also had to change how the datatables are destroyed/cleared, which has changed with the latest versions.

##### Template tooltips display as text and cause incorrect page styling (KPAs) (#146000)

**Problem**

- When editing a review setup template and providing a KPA with a very long name, the tooltips display without hovering over the text, causing incorrect page styling.

**Solution**

- Added the on-hover tag to the HTML element to ensure it only shows when the user hovers over the ellipses.

##### Template tooltips display as text and cause incorrect page styling (#146000)

**Problem**

- When editing a review setup template and providing a KPI with a very long name, the tooltips display without hovering over the text, causing incorrect page styling.

**Solution**

- Added the on-hover tag to the HTML element to ensure it only shows when the user hovers over the ellipses.

---

#### **Data Warehouse**

##### Adjusted PowerShell scripts for ContentManagement (#143697)

**Problem**

- The PowerShell scripts did not run successfully on the file server due to authentication errors

**Solution**

- Adjusted PowerShell scripts to use SQL Auth so that they can be run within SQL Job instead

##### Renamed the DataSource name from "User Access" to "Invalid User Access" (#136620)

**Problem**

- The data source name User Access for audit is not efficient

**Solution**

- Renamed the DataSource name from "User Access" to "Invalid User Access" within the Data Dictionary

##### Added RulesetID within lmReportCards (#144417)

**Problem**

- Field RulesetID is required within lmReportCards

**Solution**

- Added field RulesetID within lmReportCards

##### Created DWH Package backup folder (#143175)

**Problem**

- Currently, there is no DWH backup of the package for the case of rollback

**Solution**

- Created DWH Package Backup folder
- Added the current DWH package to the newly created folder

##### Added fields ProfileName and LineManagerProfileName (#144930)

**Problem**

- Fields ProfileName and LineManagerProfileName are required within accUsers and jpReportingLines

**Solution**

- Added field ProfileName within accUsers
- Added field LineManagerProfileName within jpReportingLines

##### Added fields YearName, GradeName and CycleName within lmReportCards (#144417)

**Problem**

- Fields YearName, GradeName and CycleName are required within lmReportCards

**Solution**

- Added fields YearName, GradeName and CycleName within lmReportCards

---

#### **Job Management**

##### API Endpoint returning inactive employees (#146082)

**Problem**

- API Endpoint returns terminated employees.

**Solution**

- Modify logic to ensure only employees with active appointments are being returned.

##### ListOrgUser endpoint returns Children Org users (#145915)

**Problem**

- The ListOrgUser Endpoint returns the children of the searched org as well.

**Solution**

- This is not the intended behaviour of this endpoint, corrected the logic so it only lists the org which was searched for and not levels below this org.

---

#### **Learning Management**

##### Resolve TinyMCE warning displayed and editor disabled on absent notification email modal (#146211)

**Problem**

- When attempting to send absent notifications, a warning is displayed, and the tinymce editor opens.

**Solution**

- Explicitly state the GPL licence key usage on the React editor component.

---

#### **Imports**

##### Correct the retrieval of all users' roles when doing a bulk user role import (146187)

**Problem**

- The api returns no roles when the user list is empty. For the bulk import, the list of usernames is always empty, and so no roles are imported. Blanks in the list are also incorrectly considered as users

**Solution**

- Exclude empty or whitespace usernames before building ruleset-prefixed usernames for ListUserRolesAsync, preventing invalid/empty entries from being queried. Also, build the response from rolesByUsername.Keys (instead of the original request list) and ensure users without roles get an empty role list, keeping the returned user-role mapping consistent with the queried results.

---

#### **Communication Portal**

##### Resolved Notification message still referencing old table (#146107)

**Problem**

- Changed mad to rename tables and structure, but the notification query was not updated to reference the new tables

**Solution**

- Updated the reference tables to correctly call the new tables

---

#### **Notifications**

##### Update example data for anniversary notification, resolve problem with tinymce editor injecting current address before placeholder, Show "No placeholder" message when placeholder table is empty (#145927)

**Problem**

- TinyMCE editor injects the correct relative path into the Source of image, example data for images are not correct, and when the list of anniversaries is empty, the placeholder is still shown in email instead of replacing it with No Birthday list.

**Solution**

- Update example data for anniversary notification, resolve problem with tinymce editor injecting current address before placeholder, Show "No placeholder" message when placeholder table is empty

---

#### **Translations**

##### Updated translations (#145685)

**Problem**

- Tenant Setup | Hover over any of the Product icons on the list page. The message at the bottom of the pop-up should be changed.

**Solution**

- Updated the message to the desired text: "Licences not displayed inherit from the CORE Licences". Used AI to translate the updated message to all available languages.

---

#### **Event Scheduling**

##### Add translations for error:learningManagement.eventScheduleIncorrectWhoCanBookType (#145966)

**Problem**

- No translation existed for error:learningManagement.eventScheduleIncorrectWhoCanBookType

**Solution**

- Add translations for error:learningManagement.eventScheduleIncorrectWhoCanBookType Also, add .cursor-pointer style globally and explicitly

---

# Version 9.1.216 (23 March 2026)

#### **Performance Management**

##### Remove required asterisk from review survey import options on review year setup configuration (#144151)

**Problem**

- Value survey import options are shown as required when configuring review year setup period options.

**Solution**

- Remove the required attribute from dropdowns.

##### Further styling adjustment for create contract modal (#145634)

**Problem**

- Create performance agreement modal options that have additional padding at the bottom of each option.  
    Found that the default 'option' class has recently gotten a specific height set (potentially due to package upgrades).

**Solution**

- Enforce a max-height on the options section of the create performance agreement modal.

##### Resolved Subordinate count (#145732)

**Problem**

- Subordinate counts are done, but only a join from contracts is done, which causes users without a contract not to display the subordinate button if there are any

**Solution**

- Adjusted query logic to have a table with users and subordinate count

##### Fixed updating of check-in comments for admins (#145530)

**Problem**

- The updating of check-in comments for admins was not working.

**Solution**

- Fixed the update functionality. The serverUrl did not match the controller method; an additional parameter was needed.

##### Resolved Subordinates not being shown and user agreements when impersonating a subordinate (#145732)

**Problem**

- When a user does not have a contract yet, no calculation can be done to see if the user has any subordinates. When impersonating a subordinate to see their subordinates, you can access their incorrect agreement

**Solution**

- Correct the SQL query to join from users to ensure the count is done on users identified. Parse the param and handle the first selection when impersonating a subordinate

##### Resolve styling issue on performance agreement create modal (#145634)

**Problem**

- Create performance agreement modal options that have additional padding at the bottom of each option.

**Solution**

- Enforce the correct height for options on the create performance agreement modal. Consolidated styling

##### Resolve styling issue on performance agreement create modal (#145628)

**Problem**

- Icons on the dashboard timeline are misaligned and no longer display center of the timeline bar.

**Solution**

- Fix the alignment of icons on the timeline phase bars

---

#### **People Management**

##### When the user does not have a name, surname or profile image, use the first three digits of the username for the avatar (#145610)

**Problem**

- When the name, surname, initials and known as are not supplied and the user does not have a profile picture, the avatar displays empty or with a question mark.

**Solution**

- Use the first three digits of the username on the avatar.

##### Resolved text being displayed on tab open (#145614)

**Problem**

- Change made to show text when the menu tab opens, but it shows immediately before the tab starts to open

**Solution**

- Add a delay to start showing text when the tab opens

---

#### **Organisational Structure**

##### Resolved org structure not expanding on roles (#145942)

**Problem**

- Missing logic on the tree view and node expanding within the people group modal

**Solution**

- Added implementation and missing events and structure to match that of the org structure, to allow expanding events and data to be loaded

---

#### **Job Management**

##### Duplicate Appointments returning with API endpoint (#145514)

**Problem**

- Duplicate Appointments are returning for the ListManagerSubordinates endpoint.

**Solution**

- Modified the Endpoint to only return active appointments.

---

#### **Master Data**

##### Resolved DateTime Format issues on Master Data (#145790)

**Problem**

- When using a datetime, it gets converted to a string, referencing a value as "2026-01-01T00:00", when the SQL is built up this is an invalid parameter and throws converstion errors

**Solution**

- Add a change to check for the type when it is of type string and DateTime, or DateTimeOffset, try to parse this value to then insert from a valid DateTime value

---

#### **Event Scheduling**

##### Fix event name size on calendar view (#145626)

**Problem**

- Seems that the default height of events on the Syncfusion calendar view has decreased, which results in the event name not properly fitting inside the event.

**Solution**

- Decrease the line height and make the font a little bit smaller

##### Fix Learning Management Empty who can book a large dataset (#145146)

**Problem**

- If a user has no subordinates, but tries to book an event for others, the system attempts to return all users in a ruleset, causing the system to hang

**Solution**

- Return no results if there are no subordinates to book for

---

#### **Learning Management**

##### Resolve issue where snack message is not displayed when saving attendance (#145804)

**Problem**

- The snack message to indicate that the attendance save was successful or failed is never displayed, leading to confusion on the user side as there is no indication that anything happened.
- Also, the reload fails because the snack is not being displayed/errored.
- Appears that the global snack function is not getting injected into the spa-minimal page when the page is called directly; other global references like axios work fine.

**Solution**

- Added a safe handler to check if the global snack function exists and use it; if not then it falls back to the SnackBar, which is injected on the minimal layout and is available to use.

---

#### **Imports**

##### Correct username changes based on id numbers. Correct the creation of new country master data (#145663)

**Problem**

- The usernames are not updated from idnumbers and new users are created. New country and province master data fails to create

**Solution**

- Correct the logic to query the users with matching id numbers for updates. Correct the contructor creating new master data for province and country.

---

#### **Data Warehouse**

##### Added PAYU Tables (#144877)

**Problem**

- Tables accPAYUSummary and accPAYUDetail are required within the V9 DWH

**Solution**

- Added tables accPAYUSummary and accPAYUDetail

##### Resolved errors for ContentManagement\_ETL (#143697)

**Problem**

- SQL Errors occurred for cmFileTypeContents due to not referencing the staging table correctly
- The IF check for creating tables for cmFileTypeContents also generated SQL Errors

**Solution**

- Resolved the errors for cmFileTypeContents within ContentManagement\_ETL.dtsx and CreateTables.dtsx

---

#### **Dashboards**

##### Replace Highcharts with chart.js in V8 (#143430)

**Problem**

- Highcharts is outdated, and the renewal is too high

**Solution**

- Chart.js is already used in V8; replace Highcharts with Chart.js
- First, determine the impact and provide a more accurate effort before continuing with changes

---

#### **New Functionality**

##### Requisitions via the ChatBot (#135118)

- New People Admin Permission, Request Requisitions/Replacements 
    - Added a new permission for the additional section of People Management, and displayed this new permission in the frontend

- As a People Admin/Manager, I want to initiate new requisitions from the People Management module 
    - Add new logic to determine if the logged-in user has the Request Requisitions permission. If they do, then the corresponding button with the redirect (User Story 4) will appear in the People Management module Next to the + Person Button

- As a People Admin/Manager, I want to initiate a replacement from the People Management module 
    - Added additional functionality to determine if the logged-in user has the Request Requisitions permission and then display the button, which will redirect the user to the Chatbot

- As a System Owner, I want a New API End-Point: List of Users in Specified Org Units 
    - Add a new API endpoint which returns a list of users in a specific org unit and only returns the requested columns

- As a System Owner, I want a New API End-Point: People Reporting to 
    - Add a new Endpoint which uses managerUsername to get the ID of the manager in the system, then gets a list of subordinates of that manager

- As a System Owner, I want a New API End-Point: Users with Specified Jobs 
    - Add a new API endpoint which returns user information based on multiple search criteria.

##### Job Management: Re-activate positions marked as Inactive (#139481)

- As a People Management Administrator, I want to be able to re-activate a previously marked inactive position so that I can re-use it for future appointments.
- As a People Management Administrator, I want to be able to set the status of each position (e.g., Planned, Budgeted, Unapproved, Approved), so that I can generate categorized reports for better workforce planning.
- As a People Management Administrator, I want to be able to define the validity period of each position (e.g., Valid From and Valid To), so that I can track position timelines.  
    
    - Helper text must show that it is for future use as well.
- As a People Management Administrator, I want to be able to specify the Minimum and Maximum Budget for each position, so that I can analyze and report on budget allocations across positions.
- As a People Management Administrator, I want to see the newly entered data on the Job Management page where all the positions are summarized.

---

# Version 9.1.215.6 (Support Release - 17 March 2026)

#### **Performance Management**

##### No date picker on Action plans (#146349)

**Problem**

- Date time picker not rendering on action plans when using dayjs

**Solution**

- Changed to make use of Syncfusion's picker

##### KPI and KPA tooltips causing styling issues (#146000)

**Problem**

- KPIs and KPAs tooltips are currently causing incorrect styling for Review Setup Templates

**Solution**

- Removed Jquery tooltips, added them, as they conflict with MDB tooltips, also added a title tag to the KPIs to ensure the tooltips are displayed.

##### Template tooltips display as text and cause incorrect page styling (KPAs) (#146000)

**Problem**

- When editing a review setup template and assigning a KPA a very long name, the tooltips appear without hovering over the text, causing incorrect page styling.

**Solution**

- Added the on-hover tag to the HTML element to ensure it only shows when the user hovers over the ellipses.

##### Template tooltips display as text and cause incorrect page styling (#146000)

**Problem**

- When editing a review setup template and providing a KPI with a very long name, the tooltips display without hovering over the text, causing incorrect page styling.

**Solution**

- Added the on-hover tag to the HTML element to ensure it only shows when the user hovers over the ellipses.

---

# Version 9.1.215.5 (Support Release - 13 March 2026)

#### **Performance Management**

##### Add change to calculate running score when copying manager score to final rating score (#146110)

**Problem**

- There is no running score when copying the manager's score to the final score

**Solution**

- Added a new change to calculate the running score when copying the manager rating to the final rating

---

# Version 9.1.215.4 (Support Release - 13 March 2026)

#### **Report Builder**

##### Added authorisation checks when running reports (#146156)

**Problem**

- Although the report permissions are enforced on the front end and only display the available reports that the user has access to, should the user have the URL or report ID for any other report, they can still run and view the report.

**Solution**

- Cache user report access and perform validation when running a report to ensure that the user has the required access.

---

#### **System Access**

##### System Menu target audience not being able to select any values (#146218)

**Problem**

- When linking people groups in the System Menu, existing (previously saved) items were not displaying as checked checkboxes after reload. Instead, they appeared as either

**Solution**

- Always render the checkboxes as the existing linked target audiences can not be interacted with.

---

#### **People Management**

##### Fix adding Employment History opens blank modal (#146276)

**Problem**

- Adding Employment History opens a blank modal

**Solution**

- Hook the button click event on the document to ensure the event is always bound

---

# Version 9.1.215.3 (Support Release - 11 March 2026)

#### **Performance Management**

##### Ensure Bulk Recalculation Errors are properly logged, and the batch status is correctly updated (#144245)

**Problem**

- When bulk recalculations fail due to an unhandled exception, the batch status remains unprocessed, and the items don't indicate the failure.

**Solution**

- Ensure bulk recalculation failures are properly logged and status updated.
- Also had to change how the datatables are destroyed/cleared, which has changed with the latest versions.

---

#### **Learning Management**

##### Resolve TinyMCE warning displayed and editor disabled on absent notification email modal (#146211)

**Problem**

- When trying to send absent notifications, a warning is displayed, and the tinymce editor is displayed.

**Solution**

- Explicitly state the GPL licence key usage on the React editor component.

---

# Version 9.1.215.2 (Support Release - 10 March 2026)

#### **Imports**

##### Correct the retrieval of all users' roles when doing a bulk user role import (#146187)

**Problem**

- The api returns no roles when the user list is empty. For the bulk import, the list of usernames is always empty, and so no roles are imported. Blanks in the list are also incorrectly considered as users

**Solution**

- Exclude empty or whitespace usernames before building ruleset-prefixed usernames for ListUserRolesAsync, preventing invalid/empty entries from being queried. Also, build the response from rolesByUsername.Keys (instead of the original request list) and ensure users without roles get an empty role list, keeping the returned user-role mapping consistent with the queried results.

---

#### **People Management**

##### Resolve the issue where you cannot add an appointment for a user when the appointment history is viewed from the summary page (#146062)

**Problem**

- When trying to add an appointment, the '+ Appointment' button does nothing; you have to click on another submenu item within the appointment section and then back to appointment history before the button works.

**Solution**

- Changed the click event to bind to a class and not the Id of the button. The button does not seem to be immediately available when the partial is being rendered, and the event cannot be bound.
- Also removed an incorrect id on the Transfer person button that caused duplicate element ids to exist in the markup.

##### Add materialise people group users tooling and extend the limited API to allow partial refresh (#146057)

**Problem**

- The people group materialisation queue is flooded with queue requests, causing the materialisation process to take excessively long. The distribution to other services also causes extreme delay.

**Solution**

- Add SQL and orchestration tooling to materialise/sync people group users across environments and wire through API flags.
- Add stored procedures and types: JobProfiler.GetRulesetPeopleGroupsForMaterialisation, JobProfiler.PeopleGroupIdList (TVP), and JobProfiler.SyncMaterialisedPeopleGroupUsers to select, prepare and merge materialised people group users.
- Add RecalculateMaterialisedPeopleGroupUsers.ps1 and task XML to orchestrate fetching people-group users via the JobProfiler API, batch processing, and calling the sync proc (supports preview mode, batching and logging).
- Update gRPC proto (people\_groups.v1.proto) to include always\_recalculate and bust\_cache request fields and pass them through in PeopleGroupsServiceV1.
- These changes enable controlled synchronisation of materialised people-group users, with options to force recalculation and bust cache, plus a PowerShell orchestrator to run the process and preview changes before committing.
- Powershell script 
    - Fetch the people groups to process for all rulesets or a specific ruleset.
    - Choose all active people groups or only the people groups that have an unprocessed log in the materialised data log queue.
    - Using the limited people group users API, refresh the calculated people group user. Bust the Redis cache
    - Process the people groups in batches of 150 to keep the CPU and memory used limited
    - Materialise each ruleset's users at the end using a merge statement

---

#### **Organisational Structure**

##### Resolved org structure not expanding on roles (#145942)

**Problem**

- Missing logic on the tree view and node expanding within the people group modal

**Solution**

- Added implementation and missing events and structure to match that of the org structure, to allow expanding events and data to be loaded

---

# Version 9.1.215.1 (Support Release - 4 March 2026)

#### **Performance Management**

##### Fixed updating of check-in comments for admins (#145530)

**Problem**

- The updating of check-in comments for admins was not working.

**Solution**

- Fixed the update functionality.
- The serverUrl did not match the controller method; an additional parameter was needed.

---

#### **Imports**

##### Correct username changes based on id numbers. Correct the creation of new country master data (#145663)

**Problem**

- The usernames are not updated from ID numbers, and new users are created. New country and province master data fails to create

**Solution**

- Correct the logic to query the users with matching id numbers for updates. Correct the contructor creating new master data for province and country.

---

#### **Learning Management**

##### Resolve issue where snack message is not displayed when saving attendance (#145804)

**Problem**

- The snack message to indicate that the attendance save was successful or failed is never displayed, leading to confusion on the user side as there is no indication that anything happened. Also, the reload fails because the snack is not being displayed/errored. Appears that the global snack function is not getting injected into the spa-minimal page when the page is called directly; other global references like axios works fine.

**Solution**

- Added a safe handler to check if the global snack function exists and use it; if not, then it falls back to the SnackBar, which is injected on the minimal layout and is available to use.

---

# Version 9.1.215 (4 March 2026)

#### **Performance Management**

##### Resolved PM contract not being shown (#145475)

**Problem**

- SQL query column name is incorrect, not being able to map, and also a wrong check for having any mappings

**Solution**

- Corrected column name, and corrected logic check

##### Resolved check-ins dial active on Dashboard within PM Widget (#145475)

**Problem**

- Check-In Dial is being displayed on the dashboard widget even if the phase is set as inactive

**Solution**

- Adjusted the query to include the check and updated the dashboard to parse the value

---

#### **People Management**

##### Corrected function call on row to replace placeholders for document preview (#145642)

**Problem**

- Cannot continue to preview the template document. Cannot continue when creating a document for a user
- Cannot continue after signing a document

**Solution**

- This pull request includes several updates focused on improving user interface accessibility, permission handling, and code modernisation for modal dialogues and table iteration in the People Management and Document Creation modules

##### Fixed KnownAs and Name displaying for LineManagers/Primary and Secondary Guardians (#145448)

**Problem**

- The Name and KnownAs is displayed for the LineManager's (OR Guardian's) name on a person's profile.

**Solution**

- Changed the logic so it displays the Known As if it is populated, else the Name, also removes surname if surname is already added to KnownAs field (some clients have it set up like that)...

---

#### **Ruleset Management**

##### Resolve issue where tenant details do not list ruleset details (#145689)

**Problem**

- When creating a new tenant/ruleset, the default theme is copied from the source ruleset and is linked to the source theme's tenant ID.

**Solution**

- When a ruleset is created, and a new tenant ID is provided, ensure that the ID is used, not the source ruleset's tenant ID.

##### Resolved text only visible after menu fully expanded (#145614)

**Problem**

- The span text within the side menu is only shown after the side menu is fully expanded

**Solution**

- Added a change to set the opacity of the span once it starts to expand, as well as no transition, so that the text is visible immediately

##### Resolved Page Help not being able to create new page files (#145680)

**Problem**

- When creating a brand new user guide on a page that has no guide, a case can exist where only section 1 is filled in and not all the other sections. With the logic check, this then fails

**Solution**

- The additional empty string check is not needed as the new id is already null, so need to create a new guide

---

#### **Event Scheduler**

##### Handle null LocationInOrg in OrganisationalUnit field (#145023)

**Problem**

- Request fails if the OrganisationalUnit is null in the query

**Solution**

- Ensure OrganisationalUnit is never null by using the null-coalescing operator to default to an empty string when x.LocationInOrg is null.
- This prevents potential null reference issues.

##### Resolved Learner records not being created (#145571)

**Problem**

- When learner records need to be created, no endpoint is hit

**Solution**

- Corrected the URL build to include the slash, as the base URL is without the forward

##### Resolved case where attendees could not be removed (#145593)

**Problem**

- There is a min and max number of attendees that can be set. This validation is used for adding and removing users, but when you want to only remove a user this still gets validated

**Solution**

- Add a validation check to ensure the rule is only applied if the number of attendees to add is not 0

##### Resolved delete modal being able to delete with no reason filled in (#145594)

**Problem**

- When deleting a group on Who Can Book, you can interact with the delete even if there is no reason filled in

**Solution**

- Corrected the logic to pass the value check if there is a reason filled in

---

#### **Job Management**

##### Resolved Org Unit people group role additions/removes (#145664)

**Problem**

- When removing an org unit people group role, it works as expected. If we want to re-add a role to an org people group, this people group already exists, which throws the method and can not proceed to then create the link

**Solution**

- Adjusted/corrected logic to only create the people group if it does not exist, else proceed to create the link with the people group identified

##### Resolved Appointment history active position not on top (#145442)

**Problem**

- Default data-sort properties are overriding the code filter to show the correct display order

**Solution**

- Remove the data-sort properties, as that is user interaction afterwards

---

#### **Learning Management**

##### Removed height that causes large cards (#145714)

**Problem**

- Style added of h-100, which causes the card to grow to a certain height.

**Solution**

- Removed h-100 so that the card can grow as the content expands, and not force the height

##### Resolve height issue on Syncfusion grid toolbox control (#145434)

**Problem**

- The training matrix grid controls' toolbox height is too big.

**Solution**

- Resolve height issue on the Syncfusion grid toolbox control by adjusting height styling for the toolbox

##### Fixed Attendance History duplication (#145571)

**Problem**

- Duplicated records on attendance history

**Solution**

- Resolved the issue by paging by user instead of attendance records

---

#### **Imports**

##### Reverted one endpoint for Last Sync (#145052)

**Problem**

- Development was done for the last sync changes. V8 development is still within Victrix, on V9, this causes the import of the one does fail

**Solution**

- Added an additional endpoint to allow for backwards compatibility

---

#### **Identity and Authorisation**

##### Resolved autocomplete input fields labels overlap text (#145431)

**Problem**

- When the form is auto-complete, the textbox label is still overlapping the input text; only after focusing on the textbox does it trigger the label to move

**Solution**

- Added event after dom content loaded to load and apply the needed styling on the element to move the label, should there be content

---

#### **Content Management**

##### Handle 404 on upload by creating missing folders (#145218)

**Problem**

- Users were experiencing issues uploading files to NextCloud, receiving a 404 error. This indicated that the system could not find the necessary folder to complete the upload

**Solution**

- Implemented a new catch that will automatically create any missing folders when a 404 error occurs.

---

# Version 9.1.214 (4 March 2026)

#### **Data Warehouse**

##### Updated PowerShell scripts for ContentManagement (#143697)

**Problem**

- FetchFileTypes.ps1 requires TrustServerCertificate
- FetchZippedFolders.ps1 needs to be adjusted to calculate the folder size for zip folder contents

**Solution**

- Updated FetchFileTypes.ps1 by adding TrustServerCertificate
- Adjusted FetchZippedFolders.ps1 to calculate the folder size for zip folder contents

##### Adjusted container for jpPeopleGroupRoles to rather do a full refresh with each run (#143862)

**Problem**

- The entries for jpPeopleGroupRoles are not being updated correctly when using EditedDate logic

**Solution**

- Adjusted container for jpPeopleGroupRoles to rather do a full refresh with each run

---

#### **Event Scheduler**

##### Changed templates to be editable (#145572)

**Problem**

- Templates can not be edited as they are set to read-only true

**Solution**

- Change/update the template values to be read-only false

##### Change to make templates active by default (#145580)

**Problem**

- When a new event is created, it creates the notifications active links with a default value of inactive

**Solution**

- Change to be active instead

---

#### **Imports**

##### Change custom process to stage data to V9 for import from V8 - refactor transaction logic and remove unnecessary logic (#145163)

**Problem**

- Single transaction across all steps is causing locks on import.imports table

**Solution**

- Create smaller transactions around import.imports and import.importuserstagings
- Remove unnecessary logic to backup data to sysemployeeimport\_backupdata
- Remove delete from sysemployeeimport as data can be imported ultiple times, the data difference check with will filter already imported data out.

##### Remove maxlength from Payroll PowerShell textarea to allow more complex scripts to be saved (#145135)

**Problem**

- Large custom PowerShell scripts saved on the front-end are truncated

**Solution**

- Remove the maxlength="@MaxLengths.TextAreaScript" attribute from the Payroll.PowershellScript textarea in Areas/Administration/Views/Ruleset/\_Integration.cshtml. This allows longer PowerShell scripts to be entered without client-side truncation while keeping existing rows, classes, and whitespace handling.

---

#### **People Management**

##### Fix intl-tel-input flags not rendering (#145147)

**Problem**

- intl-tel-input (Phone number inputs), did not render flags

**Solution**

- The component now requires you to set the flags image path and the images that were copied from node modules using gulp, which corrupted the images. Fixed gulp copy in both identity and webmvc to not corrupt images by setting encoding: false

---

#### **Learning Management**

##### Resolve missing Syncfusion scripts that are needed for the Grid control in MVC pages. Also modified ToSignifyDateTime extension to handle date strings that have a time component (#145434)

**Problem**

- The training requirement matrix does not load. Also, learning manage product setup crashes when YearDTO master data has dates with a time component.

**Solution**

- Resolve missing Syncfusion scripts that are needed for the Grid control in MVC pages. Also modified ToSignifyDateTime extension to handle date strings that have a time component.

---

#### **Tenant Management**

##### Tenant creation date and boolean defaults + order by expiry date (#144228)

**Problem**

- When creating a tenant, expiry and system close date is not defaulted to the end of next month, and boolean values for lock system and display expiry messages not defaulted to disabled. Page also not ordered by expiry date ascending.

**Solution**

- Tenant creation defaults expiry and close date to the end of next month. Lock system and expiry messages display defaulted to disabled, and the page is ordered by expiry date ascending by default

---

#### **Identity and Authorisation**

##### Resolved support user claim being added when it should not (#145443)

**Problem**

- A support user claim is checked within DBCOntextBehaviour to change the editeduser property when it is not empty. There is a case that regenerates the claims, which adds the support claim, and then is not correctly removed if it is not the support flow because of the default value being seen as true

**Solution**

- Revert logic, to always see the default value as false, and keep it as true

---

#### **Job Management**

##### Resolved parent tab being opened but no content shown (#145439)

**Problem**

- When selecting the first parent element, it opens the dropdown list for app child items, but you have to select the child item to see any content

**Solution**

- Add a change to select the first element if it exists, which triggers the click event to load the content

##### Resolved Appointment history view not taking new column (#145442)

**Problem**

- A new development has been added for calculation on the current position, but the appointment history is not taking the new column into account

**Solution**

- Added a new column, resolved logic checks, also updated the current/active text being displayed in the termination column, added a visual effect to the row, as well as a hover effect with the label

---

#### **Organisational Structure**

##### Resolved newly added org node item once clicked shows null (#144475)

**Problem**

- Once a new org node has been created, JSON returns the newly added element. Should you immediately click on the positions, it retrieves the org path to set as a header, but it is NULL

**Solution**

- Add JavaScript to set the element's value after creation

---

# Version 9.1.213 (4 March 2026)

#### **Imports**

##### De-duplicate users on User ID (#143370)

**Problem**

- Imports have multiple IDs, and this can cause a user to be added multiple times, causing import failures

**Solution**

- De-duplicate users by user ID to avoid trying to update the same user multiple times in a bulk upsert

##### Reverted one endpoint for Last Sync (#145052)

**Problem**

- Development was done for the last sync changes. V8 development is still within Victrix. On V9, this causes the import of the one to fail

**Solution**

- Reverted the one endpoint, so when this goes live, it will not break the import. Revert once V8 goes Live

##### Resolved order display for push integration imports (#145172)

**Problem**

- Display order is incorrect for indented imports

**Solution**

- Add a change to the order according to the display order wanted

##### Resolved styling change for push imports (#144975)

**Problem**

- The new development implemented makes the buttons very long as they are stacked next to each other, which grows the entire row

**Solution**

- Add a change to rather display the 2 buttons below each other

##### Preserve CreatedDate when updating users when importing (#144208)

**Problem**

- The created date of the user is overridden when the user is updated by the user import.

**Solution**

- Passes createdDate: existingUser.CreatedDate into the user update/create call in ImportUsersCommandHandler so the original CreatedDate is preserved during import/update. This prevents the import flow from overwriting the user's original creation timestamp when an existing user is updated.

---

#### **Content Management**

##### Resolved Avatar selection (#145074)

**Problem**

- When selecting a default image, it fails on the user profile

**Solution**

- Corrected the path URL to first check in the new folder path of avatar-defaults

---

#### **Performance Management**

##### Resolved My Agreement pill item tab not present when multiple setup selections (#142417)

**Problem**

- When a user is linked to multiple setups, a selection comes up to select the review setup should there be no existing contract, but there is no link button in the selections to navigate back to should they have other subordinate view items

**Solution**

- Add a change to render a button on conditions, should there be even though a contract does not exists. Implement a change to handle the tab selection correctly after a review setup has been selected

##### Custom binding handler for decimal to cater for both ',' and '.' as decimal separators (#145167)

**Problem**

- When the user's regional settings have ',' as the decimal seperator and the frontend sends through decimal as '.' then the value is lost during the model binding and results in \_null\_ value.

**Solution**

- Added a custom decimal model binder provider that can be attached to a property/action parameter as an attribute, which then, in turn, performs custom binding of the value and converts the value to '.' so it binds correctly on the controller.

##### Fixed html tag not showing and removed whitespace (#144980)

**Problem**

- One of the translations showed the tag on the ui and had whitespace beneath it.

**Solution**

- Correctly apply the HTML tag and remove the whitespace.

##### Allow capturing rating scales with two decimal values (#145167)

**Problem**

- Can't add rating scales with values that have two decimal places, e.g., 1.25 or 1.02

**Solution**

- Allow adding rating scales with upto two decimal places

---

#### **Report Builder**

##### Added clause when no tenantId exists (#143579)

**Problem**

- In cases where a table does not have a tenantId present, it fails.

**Solution**

- Add a case to have the same logic, should it fail, fallback to query without tenantId

---

#### **Data Warehouse**

##### Created new SSIS Package Audit\_ETL (#136619 &amp; #136620)

**Problem**

- New Datasource UserAccess is required

**Solution**

- Created new SSIS Package "Audit\_ETL.dtsx"
- Created new ConnectionManager "V9\_Master\_Audit"
- Created new Datasource "UserAccess"
- Adjusted DataDictionary Scripts to include Audit

##### Updated step for accUserLoginStats to insert new field UniquePersonLoggingDays (#144473)

**Problem**

- The insert step for accUserLoginStats does not include the new field UniquePersonLoggingDays

**Solution**

- Updated insert step for accUserLoginStats to include the new field UniquePersonLoggingDays

##### Resolved issue for accUserLogins to only return successful Logins (#144473)

**Problem**

- The accUserLoginStats calculation for V10 only returned failed logins, which is incorrect

**Solution**

- Corrected the accUserLoginStats calculation for V10 to only return successful logins

---

#### **People Management**

##### Cleanup failed profile creations, identity user (#145199)

**Problem**

- A user appointment process failed due to a duplication/overlapping error. During cleanup, the user account was removed, but the associated identity record remained. A later import updated the username of an existing account, but the identity could not be updated due to a conflicting existing username. This resulted in the identity being linked to a different account. When the user attempted to log in with the updated username, no matching account could be resolved, causing the application to become unresponsive.

**Solution**

- When a new person's appointment fails, be sure to delete the identity user also. This ensure futher username changes and re-adding of the same user will occur correctly

##### Clear tab pane when switching between tabs (#145173)

**Problem**

- After viewing a tab, then moving to another tab, the previously visited tab remains on the screen while viewing the new tab

**Solution**

- Clear tab pane when switching between tabs

##### Fix "We're Sorry" error appears when navigating to Positions from Appoint User Screen (#144487)

**Problem**

- The system displays a "We're Sorry" error when navigating to Positions from the Appoint User Screen

**Solution**

- When navigating to Positions from the Appoint User Screen, change the breadcrumb to refer the user to where they came from.

##### Fix Summary, Timetable &amp; Attendance Views not showing when in learning mode (#145057)

**Problem**

- Summary, Timetable &amp; Attendance Views not showing content when in learning mode

**Solution**

- Fix Summary, Timetable &amp; Attendance Views not showing content when in learning mode

---

#### **Job Management**

##### Close the tab when navigating back from positions when it was opened from adding a position on people management (#144487)

**Problem**

- The user adds a new position from the appointment screen, which opens the job management positions in a new tab. Navigating the breadcrumb back results in taking the user back to the appointment screen of the tab they are on. It should rather close the tab which reflects the same action that saving the form does.

**Solution**

- Close the tab when the user navigates back. Still need to keep the `useRefererBreadcrumb` so that only one breadcrumb is added.

##### Refactor appointments active calculation (#144278)

**Solution**

- Add a new change to calculate appointments within commands and imports instead of recalculating within each query.
- Adjust queries to make use of the new column instead of calculating each time

##### + Inherent Requirements" button appears on all the Job Requirement Tabs (#144476)

**Problem**

- "+ Inherent Requirements" footer button appears on all the Job Requirement Tabs

**Solution**

- Ensure the "+ Inherent Requirements" footer button only appears on all the "Inherent Requirements" tab

---

#### **Tenant Management**

##### Send notifications subscription toggle and date quick select buttons (#144227)

**Problem**

- New expiry date should be the same as the current expiry date; buttons need to be added to quickly set dates (for end of this week, end of next week, etc); and a new toggle to be added to enable and disable subscription expiry and system close notifications

**Solution**

- New expiry date defaulted to current expiry date; 4 buttons added to quickly set the dates; new toggle added which persists in the database against the subscription, and displays value; and then added logic to ensure when disabled, no system expiry or close notifications are sent

---

#### **Communication Portal**

##### Resolved add button not being rendered correctly (#144928)

**Problem**

- When being rendered within the footer, the Bootstrap footer styling affects the position relative of the add new container which hides the menu dropdown

**Solution**

- Moved the add to the modal header, and adjusted the icon's background to look the same as the Nav.

---

#### **Learning Management**

##### Remove username from coordinator name on events calendar view (#145139)

**Problem**

- When a coordinator's username is their id number, then it raises POPI concerns when displayed.

**Solution**

- Hide the username and only show the first and last name.

---

# Version 9.1.212 (4 March 2026)

#### **People Management**

##### Resolve issue with ESS settings not correctly reflecting (#145003)

**Problem**

- Self Service settings are not correctly displaying, everything shows as disabled. When viewing user profile indicates that no self service settings have been configured.

**Solution**

- Admin / Ess view and edit values are not correctly retrieved leading everything to default to false. Corrected the fetch so that it correctly maps the view and edit options from the database. Additionally moved the selfservicesetup cachepattern to the shared location. Also on the BustAllRulesetCachekeys it was only looking at patterns that start with 'RS{0}\_CacheKey', but for self service setup the pattern starts as 'sss' so it never gets removed from cache, unless you physically update the cache settings. Now when cache is fully busted will also refresh ESS.

##### Resolved user not being able to edit his own details (#144785)

**Problem**

- Logged in user could not edit his own details Particulars and Biographical shared same checks

**Solution**

- Added LoggedInUser check Split out particulars and Biographical

##### Implemented update to also take into account self service id validation (#143993)

**Problem**

- When an id number is updated within personal details it is not taking into account the validation settings Duplicate methods on self service and misleading method name on the one call

**Solution**

- Add new implementation to take into account id validation refactor duplicate calls and correct the duplicate models

---

#### **Job Management**

##### "Do basic self-assessment" icon not clickable (#144469) 

**Problem**

- Event listener was never triggered

**Solution**

- Move to only instantiate directly after the data has been loaded

##### Manager cannot view subordinates Competencies (#144468)

**Problem**

- No development exists to trigger on click event

**Solution**

- Added new event listener to be triggered when row click to navigate to users analysis

##### Resolved evidence being cleared when deleting content (#144784)

**Problem**

- When deleting an evidence file, the modal reloads but with an empty list. Missing Competency Inherent Requirement id

**Solution**

- Add missing id value - pass through to reload evidence

---

#### **Performance Management**

##### Updated some of the translations (#144980)

**Problem**

- Received a request to update some of the PM translations.

**Solution**

- Updated the translations to the requested wording.

##### Modification to Popover rendering as attempt to resolve screen flickering when popover is triggered with hover/focus (#144966)

**Problem**

- When hovering over some elements that have a popover, it continuesly re-renders and the popover flickers, as if it's visibility state is constantly changed. This does not happen locally only on Master and on UAT.

**Solution**

- Memorized the popover properties so that it does not re-render when anything else on the dashboard changes. Found additional issue where for a fraction of a second the popover is shown topleft of the viewport before it positions where it's supposed to. Enforced additional css onto the popover to attempt to prevent that from happening.

##### Fix rendering of dashboard buttons (#144937)

**Problem**

- The dashboard buttons display both the start text as well as the accessibility text.

**Solution**

- Fix the rendering of the buttons to not show the accessibility text

##### Resolve issue with additional agreement button displaying when user does not have primary agreement (#140461)

**Problem**

- Add additional agreement button shows when impersonating user and user does not yet have a primary contact, and user is only on a single review setup.

**Solution**

- Ensure additional agreement button is correctly hidden when user does not yet have primary contract.

##### Resolved redistribute of weight when VB section removed (#144781)

**Problem**

- When a user is not a manager it removes the VB section and redistribute the weight, on some values this cause a total of 1.0001 which throws the exception

**Solution**

- Add a tolerance to skip exception and navigate within the existing recalculate case

##### Ensure only one import is logged per ruleset when importing surveys from v8 (#142910)

**Problem**

- When importing surveys from V8, an import was logged for each contract instead of one per ruleset.

**Solution**

- Ensure only one import is logged per ruleset when importing surveys from v8

---

#### **System Access**

##### Hide kebab menu for non-admin users (#144389)

**Problem**

- Kebab menu shows for non-admin users

**Solution**

- Hide kebab menu for non-admin users

---

#### **Notifications**

##### Updates to query getting subscription notifications (#144635)

**Problem**

- When the expiry date and close date are the same, the system sends notifications after the close date, and in some cases two mails on the same day.

**Solution**

- Move the "2-day prior to expiry" check to a "3-day prior to expiry", and ensure no mails are sent after the system close date. This way 2 mails will never be sent on the same day

---

#### **Ruleset Management**

##### Can't change icon of dashboard widget (#145007)

**Problem**

- Can't change icon of dashboard widget

**Solution**

- Drop down button did not have a 'dropdown-toggle' class

##### Paging Styling (#145006)

**Problem**

- Pagination buttons did not make use of the secondary color, but rather the primary color

**Solution**

- Ensure pagination buttons makes use of secondary colors

##### White background on Search bar (#144998)

**Problem**

- White background on Search bar when autocompleting

**Solution**

- Override autocomplete styles so that it fits original style

##### White backgrounds on Text input fields (#144997)

**Problem**

- White backgrounds on Text input fields

**Solution**

- Override autocomplete styles so that it fits original style

##### Back Button styling issue (#144905)

**Problem**

- Back button text in certain instances were not white

**Solution**

- Ensure that the text is white (when using tertiary button)

##### Styling issues on People Admin page (#144815)

**Problem**

- Pagination displayed underneath tables even if there are not enough items for paging to apply

**Solution**

- Global conditional pagination helper made use of outdated mdb table classes, ensure the new class selectors are used.

##### Correct first selection not being set on image resources (#143713)

**Problem**

- New change implemented in account to not set first selection but not added within image resources Suggestion to clear tags after file change

**Solution**

- Pass true value Add clear Keywords

---

#### **Data Warehouse**

##### Adjusted script C\_03707\_99999\_monReportBuilderDataIntegrityResults to only return error messages (#142737)

**Problem**

- The ReportBuilder IntegrityResults results return for all the reports which can take time to go through report

**Solution**

- Adjusted script C\_03707\_99999\_monReportBuilderDataIntegrityResults to only return error messages

##### Added field UniquePersonLoggingDays within accUserLoginStats (#144473)

**Problem**

- Field UniquePersonLoggingDays is required within accUserLoginStats

**Solution**

- Added field UniquePersonLoggingDays within accUserLoginStats
- Implemented Performance Improvements with V8 and V10 calculation Scripts for accUserLoginStats

##### Added step to exclude any cm tables from Data Dictionary (#143697)

**Problem**

- Currently any cm tables are added to the Data Dictionary

**Solution**

- Added step to archive any cm% data sources and their fields in ReportBuilder tables

##### Created new DataSource cmZipFolderContents (#143697)

**Problem**

- New Datasource is required to store the movies and zip folder information

**Solution**

- Created new DataSource cmZipFolderContents

---

#### **Learning Management**

##### Adjust dropdown sizes and exclude start and end date from year dropdown (#144958)

**Problem**

- The Year dropdown has regressed into the Date Range of the Master data item rather than the associated label and the size has been adjusted and is no longer legible.

**Solution**

- Adjust dropdown sizes and exclude start and end date from year dropdown.

---

#### **Imports**

##### Resolved performance issue with the export of users via the API (#144570)

**Problem**

- When ListUserExport is called during the V9-to-V8 user import, it sends all user IDs to a batched Dapper query. This is a query that becomes heavy and slow on a large group of people to export (60k+)

**Solution**

- Replace dapper batched logic with SQL bulk copy to a temp table for efficiency.

---

#### **Report Builder**

##### Resolved Filter values showing Incorrect Date (#144246)

**Problem**

- Development was added to have dropdown values of like 'Today' 'Next week' but when viewing the report that is marked as an invalid date

**Solution**

- Add FilterValue to be converted based on this data to the correct values

---

#### **Event Scheduler**

##### Fix the event calendar from either going blank or disappearing when a reason is selected, or an event details are viewed (#144947)

**Problem**

- The event calendar is going blank/disappearing when a reason is selected, or an event details are viewed.

**Solution**

- The event calendar is going blank/disappearing when a reason is selected, or an event details are viewed. Note: The peopleManagement translation wasn't loaded into memory yet, so it only loaded when the BookOthersModal component mounted, after the event details was clicked. It then goes into suspense mode, and throws a promise while it's busy loading the translation, react suspends rendering and looks for the nearest Suspense component. It wasn't finding the higher level Suspense components for some reason, so adding a React.Suspense component around where the BookOthersModal component is loaded, fixes the issue.

---

#### Content Management

##### Resolved Data Annotation for Online Marking (#141344)

**Problem**

- Online marking stamps not behaving correctly when trying to move, or when moving across page, creating ghost elements

**Solution**

- Refactor logic and code after syncfusion upgrade, corrected behavior and page move

---

# Version 9.1.211 (4 March 2026)

#### **People Management**

##### Add handling to not do PG update with rowlock when no data to update (#144529)

**Problem**

- Situation where if the current activity is on materialised PeopleGroupUsers, but there is no data in the table for the PG, then the rowlock causes performance issues.

**Solution**

- Wrapped the table update with the row lock in an if to only run if there is data to update.

##### Refactor People Management tab queries to increase performance (#144529)

**Problem**

- In some instances, the queries to fetch MyTeam / MyDepartment / MyCompany / PeopleGroupUsers times out or takes an excessive amount of time to complete.
- 2 calls are made as subqueries to determine 
    - 1) The number of subordinates for the user
    - 2) Whether the user is my manager.

**Solution**

- Changed the 'My Manager' check by fetching the user's manager beforehand into a variable and then comparing the result userid against that variable.
- Moved the subordinate count outside of the main cte query by first selecting everything into a temp table and then calculating and updating the subordinate count after the fact as a batch update.
- Some minor changes to React for mapped key uniqueness.

##### Correct people group materialisation clearance when the list of people group's users is fetched (#143861)

**Problem**

- When V8 request the people group users from V9, and some PGs have been materialised, and some have not been materialised, it causes the materialised people groups to be cleared. Only the unmaterialised PGs are to be returned.

**Solution**

- Ensure only the calculated people groups are included when deleting the materialised people group users

##### Hover on Profile picture displays incorrect tooltip text (#144474)

**Problem**

- Hovering on the profile picture displays incorrect tooltip text

**Solution**

- Fix incorrect casing used for the translation key, causing it not to find the correct value

##### Extended compression type selection on User Edit Profile (#143713)

**Problem**

- New change implemented in the account to not set the first selection, but not added withinthe image resources
- Suggestion to clear tags after file change

**Solution**

- Pass true value
- Add clear Keywords

##### When a front-end user appointment fails to create, revert user creation (#144275)

**Problem**

- Should a front-end user creation be successful, but the appointment fails, a message is shown for the user, but if the modal is closed and later tried to appoint/recreate, it says the user already exists.

**Solution**

- Add change should the appointment creation fails, revert/delete the created user

---

#### **Job Management**

##### Fixed copying of reporting lines on the user summary page (#143977)

**Problem**

- The copy manager function for reporting lines on the user summary page is not working.

**Solution**

- Included the JS file with the function and added the needed hidden fields.

##### Uploaded Evidence only appears on Inherent Requirements after a Hard Refresh (#144492)

**Problem**

- When opening the modal, a global let is set, which is not reset

**Solution**

- Correct to pull the data-attribute directly

##### An error appears when deleting Required Evidence Files (#144493)

**Problem**

- Incorrect id attribute was retrieved to be passed for deletion

**Solution**

- Correctly retrieve the id for the document deletion

##### Previous delete reason gets cached when deleting evidence documents (#144494) 

**Problem**

- When a user opens the modal, it keeps the previously entered value

**Solution**

- Reset the value to the default when opened

---

#### **Imports**

##### Implemented visual enhancements to User Imports (#144481)

**Problem**

- User Import triggers a few other imports, but no visual knowledge of that

**Solution**

- Add an indent to the types that are included as part of the User Import

##### Add change to sync in partial for last edited date (#139776)

**Problem**

- When syncing data from V9 to V8, all data is pulled that is currently on V9, not just changed data. This caused the API calls to return very large datasets each time the APIs are called.

**Solution**

*V9*

- In each of the APIs below, implement an additional filter ChangeAfterDate 
    - ChangeAfterDate is a nullable datetime field
- The ChangeAfterDate should be used to only return the data with an edited date after the date 
    - When the date is null, then all data must be returned
    - The edited date of the main table, along with the relational tables, should be considered, e.g. 
        - Account.Users.EditedDate, Account.Genders.EditedDate etc.
- On the Ruleset | Integrations tab, split the push buttons into two 
    - All Data 
        - This will import all data from the start of time.
    - All Data from the last change 
        - This will only import the data from the date of the last successful import on V8.
    - Keep as is Theme Import
- APIs 
    - User Import
    - People Group Import 
        - Use the People group table as well as the materialised log table to determine changes
    - User people group permissions 
        - Use the link to the user and the roles' edited date
        - Add a field in Jobprofiler.MaterialsedUsers.PeopleGroupChangedDate, which is populated when people groups are removed from a user
    - User roles  
        
        - Check the edited date of the user role
        - Add a field to the account.Users.RolesChangedDate, which is populated when roles are deleted from a user
    - Reporting Lines  
        
        - Use Jobprofilers' reporting lines edited date to fetch the changed data
    - Job structure  
        
        - Check the edited date of the JobProfile, Position and Org nodes as well as their linked master data, to determine a change
    - Org structure  
        
        - Check the edited date of the Org nodes as well as their linked master data, to determine a change
    - Appointment  
        
        - Use the edited date of the appointment
        - Add a field in Jobprofiler.MaterialsedUsers.AppointmentChangedDate, which is populated when appointments are removed from a user
        - When any appointment has changed for a user, return all appointments for the user

*V8*

- Add a table sysSuccessfulSyncLog 
    - This table only stores the import types, with the date they were last successful
    - This table is then used to determine the date to include for ChangeAfterDate when the APIs are called
- Alternatively use sysProcesslog
- Display the import completion date stored on V9 after successful completion.

---

#### **Ruleset Management**

##### Resolved event handler not being triggered on system menu click (#144569)

**Problem**

- The off method is called, which removes all the event handlers from that element, so only the very last defined event is added

**Solution**

- Correctly remove the same event specified to be added

---

#### **Communication Portal**

##### Implemented Communication Priority Master data item (#140896)

**New Development**

- Add Master Data for the Priority to be set when creating notifications

##### Implemented Master Data Communication Category (#140897)

**New Development**

- Add Master Data for the Category to be set when creating notifications

##### Implemented import for Master Data (#140898)

**New Development**

- Add an import for Master Data to be available in V8

##### Added handling for external system message (#140899)

**New Development**

- Added functionality so that a V8-triggered mail can be sent as a System message

---

#### **Organisational Structure**

##### Load org nodes on org structure page on demand (108648)

**Problem**

- Org node loaded all org structures (including children) from the server, which can cause performance issues on the browser if there are alot of structures.

**Solution**

- Load only top level org structures on first page load and load the rest as the structure is expanded.

---

#### **Content Management**

##### Implemented a new change to be able to delete a signing document (#143364)

**Problem**

- When an assessment attempt has been signed, there is currently no way to ressign it from the front end

**Solution**

*Path*: *Manage Employees &gt; Select Employee &gt; Employee Development &gt; Assessment List*

- In the drop next to the assessment (see below), create an item "Reset signing"
- It should only be available if one of the attempts was signed digitally
- When selected, the user is prompted for a reason (free-text) and a message, "PLEASE NOTE: This action is not reversible and will remove the digital document." 
    - The reason is saved against a new field in abAssessmentsAttempts.ResetSigningReason
- When the reason is completed, and the user clicks Continue 
    - Remove the digital document from Nextcloud via the content service
    - Remove the document from the Fileserver application
    - The record is removed from sysSigniSignedDocuments and then abAssessmentSignatures according to the logic demonstrated in

---

#### **Tenant Management**

##### Updated system close colour + filter fix (#144226)

**Problem**

- System Close Date colour was orange when within 30 days of the close date
- The advanced filter is not working

**Solution**

- Change the colour to red and show the expiry dates nearest to today's date first by default
- Corrected the filter

---

#### **Identity and Authorisation**

##### Implement Auditing on Identity service (#143433)

**Problem**

- There is currently no auditing on the Identity Service. Registration development lies mostly here, and therefore, it should be considered for adding auditing.

**Solution**

- New implementation to subtract the base methods used for tracking entity changes and submit them to the Audit service. Create new Content for identity that also inherits this, add an option to add a new external provider to the list and audit

---

# Version 9.1.210.3 (Support Release - 2 March 2026)

#### **Learning Management**

##### Resolve height issue on Syncfusion grid toolbox control (#145434)

**Problem**

- The training matrix grid controls' toolbox height is too big.

**Solution**

- Resolve height issue on the Syncfusion grid toolbox control by adjusting height styling for the toolbox

##### Resolve missing Syncfusion scripts that are needed for the Grid control in MVC pages. Also modified ToSignifyDateTime extension to handle date strings that have a time component (#145434)

**Problem**

- The training requirement matrix does not load. Also, learning manage product setup crashes when the YearDTO master data has dates with a time component.

**Solution**

- Resolve missing Syncfusion scripts that are needed for the Grid control in MVC pages. Also modified ToSignifyDateTime extension to handle date strings that have a time component.

##### Fixed Attendance History duplication (#145489)

**Problem**

- Duplicated records on attendance history

**Solution**

- Resolved the issue by paging by user instead of attendance records

---

#### **Content Management**

##### Resolved Data Annotation for Online Marking (#141344)

**Problem**

- Online marking stamps not behaving correctly when trying to move, or when moving across the page, creating ghost elements

**Solution**

- Refactor logic and code after Syncfusion upgrade, corrected behavior and page move

---

#### **Report Builder**

##### Resolved Filter values showing Incorrect Date (#144246)

**Problem**

- Development was added to have dropdown values of like 'Today', Next week', but when viewing the report that is marked as an invalid date

**Solution**

- Add FilterValue to be converted based on this data to the correct values

---

#### **Performance Management**

##### Resolve issue with the additional agreement button displaying when the user does not have a primary agreement (#140461)

**Problem**

- When a user is assigned to more than 1 review setup and not yet had a contract, it must display the option to pick the review setup on which to create the contract. It does not do this and, by default, selects the first review setup available.

**Solution**

- Ensure that when the chosen review setup's contract does not exists that, it does not set the selected review setup and allows the user to pick the initial review setup.
- Also made a change to only fetch the additional agreement modal data when the modal is opened.

##### Ensure only one import is logged per ruleset when importing surveys from v8 (#142910)

**Problem**

- When importing surveys from V8, an import was logged for each contract instead of one per ruleset.

**Solution**

- Ensure only one import is logged per ruleset when importing surveys from v8

---

# Version 9.1.210.2 (Support Release - 19 February 2026)

#### **Learning Management**

##### Adjust dropdown sizes and exclude start and end date from year dropdown (#144958)

**Problem**

- The Year dropdown has regressed into the Date Range of the Master dataitem rather than the associated label, and the size has been adjusted and is no longer legible.

**Solution**

- Adjust dropdown sizes and exclude start and end dates from the year dropdown.

---

#### **Performance Management**

##### Resolve issue with the additional agreement button displaying when the user does not have a primary agreement (#140461)

**Problem**

- Add an additional agreement button that shows when impersonating a user and the user does not yet have a primary contact, and the user is only on a single review setup.

**Solution**

- Ensure the additional agreement button is correctly hidden when the user does not yet have a primary contract.

---

#### **People Management**

##### Add handling to not do PG update with rowlock when no data to update (#144529)

**Problem**

- Situation where if current activity on materialised PeopleGroupUsers, but there is no data in the table for the PG, then the rowlock causes performance issues.

**Solution**

- Wrapped the table update with the row lock in an if to only run if there is data to update.

##### Refactor People Management tab queries to increase performance (#144529)

**Problem**

- In some instances, the queries to fetch MyTeam / MyDepartment / MyCompany / PeopleGroupUsers time out or take an excessive amount of time to complete.
- Investigated and found a couple of areas that could be done better, one of which relates to the appointments
- 2 calls are made as subqueries to determine 1) the number of subordinates for the user, 2) whether the user is my manager.
- These are extremely inefficient, however, as for every row in the resultset the count is done from reporting lines / checked against my Line Manager.

**Solution**

- Changed the 'My Manager' check by fetching the user's manager beforehand into a variable and then comparing the result userid against that variable.
- Moved the subordinate count outside of the main cte query by first selecting everything into a temp table and then calculating and updating the subordinate count after the fact as a batch update.
- Some minor changes to React for mapped key uniqueness.

---

# Version 9.1.210.1 (Support Release - 10 February 2026)

#### **People Groups**

##### Correct people group materialisation clearance when the list of people group's users is fetched (#143861)

**Problem**

- When V8 requests the people group users from V9, and some PGs have been materialised, and others have not, it causes the materialised people groups to be cleared. Only the unmaterialised PGs are to be returned.

**Solution**

- Ensure only the calculated people groups are included when deleting the materialised people group users

---

#### **Ruleset Management**

##### Resolved event handler not being triggered on system menu click (#144569)

**Problem**

- The off method is called, which removes all the event handlers from that element, so only the very last defined event is added

**Solution**

- Correctly remove the same event specified to be added

---

# Version 9.1.210 (9 February 2026)

#### **System Access**

##### Replace system access caching for ruleset settings to allow the login page to display the correct MFA settings (#131818)

**Problem**

- When a ruleset's MFA settings are edited from another ruleset by a global ruleset administrator, the MFA setting does not change on the login page.

**Solution**

- Remove the in-memory caching of system access settings and replace it with Redis caching that is busted when changing the MFA settings

---

#### **Data Warehouse**

##### Updated Containers for lmStudentSubjects and lmTermMarks (#143406)

**Problem**

- Currently, the previous year data for the datasources StudentSubjects and TermMarks are being calculated and reinserted, which can cause issues with historic data

**Solution**

- Updated Containers for lmStudentSubjects and lmTermMarks to only process and insert data for the current year, and keep the previous year's data
- Disabled 2025 manual updates for StudentSubjects and TermMarks

##### Adjusted the update step for field AbsentAttendance within lmTermResults (#144262)

**Problem**

- The field AbsentAttendance calculation within lmTermResults does not consider the year for the students, which is incorrect

**Solution**

- Adjusted the update step for field AbsentAttendance within lmTermResults to consider the year as well, to ensure the field is being updated correctly

---

#### **People Management**

##### Resolved issue where email is mandatory on the Contact Details page, even though it is set to be not mandatory in the settings (#144273)

**Problem**

- The Email address is set to be not mandatory in the settings, but it is required on the Contact Details screen.

**Solution**

- Corrected the logic on the page to consider the setting as well.

##### Remove readonly restriction on username when auto-generated (#144410)

**Problem**

- Even though the username is auto generated should still be able to change it on the Summary / Personal detail views on a person's profile

**Solution**

- Remove readonly from the username field when auto generated, add existing username validation check.

---

#### **Ruleset Management**

##### Guard geolocation and prevent duplicate handlers on ruleset management (#143200)

**Problem**

- The request allow the country to be fetched is shown on all tabs. When saving the content server settings, it saves twice.

**Solution**

- Only run getUserCountry() when the active tab is the General tab (checks URL param 'tab'), and skip if the country is already selected or geolocation is unavailable. Replace several direct .on() bindings with .off().on() on #tab-content and form elements to avoid duplicate event handlers (menu item clicks, delete modal actions, checkbox change, and integration form submissions). Preserve existing AJAX flows for selecting/creating countries and for form submits, while cleaning up indentation and chaining for readability.

---

#### **Job Management**

##### Bust people group cache when updating position, as it might include an org change linked to a people group (#136729)

**Problem**

- People group users are not refreshed when updating position from the job management page.

**Solution**

- Bust the people group cache when updating the position, as it might include an org change linked to a people group

---

#### **Report Builder**

##### Unbind jQuery handlers and fix the jsTree load to ensure spamming the jsTree selector does not generate multiple bound events. (#144181)

**Problem**

- When a user spams the tree selector with clicks, many events then fire and the page glitches
- When the datasource loads without items, a JS tree error is thrown.

**Solution**

- Replace many direct .on(...) bindings with .off(...).on(...) across add-edit-report.js, pivot-table.js, and report-designer.js to prevent duplicate event handlers and memory leaks. Add missing .fail handlers for AJAX posts, ensure checkbox/form serialisation deduplicates entries, and tighten drag/mouse event binding/unbinding. Also, adjust the jsTree node payload to always provide children as an array and include a loaded flag to improve tree loading behaviour. Minor UI/interaction fixes (datepickers, export buttons, dropdown event handling) included.

---

# Version 9.1.209 (9 February 2026)

#### **Performance Management**

##### Resolved not being able to search for users on bulk actions (#143971)

**Problem**

- When a user is searched, a check is done to try and parse to an int for userIds. This then causes users with usernames with a valid type Number to be converted and not be able to return correct data, as the username is converted to type id, but not the user's id

**Solution**

- Change the code to make it of type string and search only on usernames

##### Corrected help file pageType (#144267)

**Problem**

- When retrieving a value, it selects the first one it matches, meaning it could be a shorter/earlier key; in this case, for this page type, it is true.

**Solution**

- Change check to decrease the length and the match

##### Implemented missing page routes and types for the Help Files (#144192)

**Problem**

- Missing page routes, so no page help file could be created and defaulted to the dashboard

**Solution**

- Added missing page help files

##### Resolved Job Grade Filter (#143971)

**Problem**

- Job Grade filter types are displayed instead of scales, as well as joining to the wrong data type for values

**Solution**

- Correct the dropdown to grading scales, as well as the query

##### Add calculated kpi weighted average field when exporting contract from printview (#142544)

**Problem**

- Request to add the KPI calculated weighted average to the export of the contract.

**Solution**

- Calculate the KPI weighted average when weighted over KPA during print preview of the contract. When weighted over setting, then the calculated kpi weight is the actual kpi weight.

##### Resolved data type on pre-recalculate score (#143988)

**Problem**

- Incorrect data type for decimal, so contracts with larger max ratings can not recalculate

**Solution**

- Corrected data type

##### Resolve issue where viewing documents on the KPA / Perspective level only showed the first KPI documents (#138511)

**Problem**

- When clicking on the view documents on the KPA or Perspective level, it only shows documents loaded on the 1st KPI.

**Solution**

- Corrected the reference filter to correctly check against which level to display documents

---

#### **Data Warehouse**

##### Created new DataSource cmFileTypeContents (#143697)

**Problem**

- A new datasource is required to store the different file type information

**Solution**

- Created new DataSource cmFileTypeContents

##### Created new table jpPeopleGroupRoles (#143862)

**Problem**

- The required permission data are required within the DWH

**Solution**

- Created a new table jpPeopleGroupRoles, within the DWH

##### Created new DataSource cmScormUploadFolders (#143697)

**Problem**

- A new datasource is required to store SCORM file details that are being uploaded

**Solution**

- Created new DataSource cmScormUploadFolders

---

#### **Organisational Structure**

##### Improvements to make org structure relationships more robust and prevent recursive operations (#144044)

**Problem**

- When a node references itself as a parent or a parent node references one of the children, then the entire system no longer loads.

**Solution**

- Updating recursive CTEs to build and check path information, adding new migration logic for path calculation, and enhancing data integrity by preventing circular references in both SQL and domain logic.
- These changes collectively improve the reliability and correctness of organisational hierarchy operations, ensuring accurate path calculations and preventing infinite loops or data corruption due to cycles.

---

#### **Tenant Management**

##### Resolve issue where a tenant having a subscription expiry date in the last month of the max date can no longer be edited (#144048)

**Problem**

- Related issue to the previous fix, if the expiry date is anywhere within the last month of the max date (9999-12-01 to 9999-12-30), then the same error occurs where the subscription becomes uneditable.

**Solution**

- Modified the calculation to check that if at all within the last month, then take as the exact max value, else add the default extension periods.

##### Resolve issue where a tenant having a max subscription expiry date can no longer be edited (#144048)

**Problem**

- When the tenant subscription expiry date is the max date (9999-12-31), it can not be edited since the calculation adds 1 month to the expiry date in certain scenarios which causes date arithmetic overflows.

**Solution**

- Correct check that when the expiry date is equal to the max date, then don't add additional months/days.

---

#### **Report Builder**

##### Handle datetime2 in filters and remove quotes (#144059)

**Problem**

- When the date is selected, the built query breaks and returns no results.

**Solution**

- Updates the SQL functions and procedures in the ReportBuilder service to improve support for the datetime2 data type, ensuring that filters and operators handle it correctly and consistently.
- The main changes involve adding explicit handling for datetime2 fields and removing unnecessary quotes from filter values for this type.

---

#### **People Management**

##### Implemented new validation type for User Front-end registration (#143993)

**Problem**

- When new users are created, Id number validation is required as well as a duplication check.

**Solution**

- A recent development has added registration-specific validation, extended the functionality to the Product Setup for People Management (Self-Service) add dropdown where validation type can also be selected. Add a check to validate the user Id number if the validation type is set

##### Resolved appointment and line manager not being displayed on the modal from the dashboard (#143995)

**Problem**

- The appointment start date is never used for the appointment, neither being captured to set on the modal within react side.

**Solution**

- Implemented a change to select the end date and use the same logic as people management to set the displayed text for the appointment, as well as just capture needed fields in React to be set

---

#### **Master Data**

##### Reset input fields for Master Data (#143898)

**Problem**

- The "active" property is not passed to the controller when the save add new button is pressed.

**Solution**

- This is due to the active property not being reset; the value is only assigned when the user interacts with this button

---

#### **Notifications**

##### Resolved Import Error Event not propagating (#144022)

**Problem**

- Import Error Event Code set to not propagate, which is needed on other rulesets

**Solution**

- Corrected seed data and migration

---

#### **Dashboards**

##### Limit dashboard reportees to 500 and update UI (#139661)

**Problem**

- Team insight does not load when the manager has an excessive number of subordinates

**Solution**

- When a manager has more than 500 subordinates, limit the team insights to 500. Add tooltips to indicate the subordinate count and that some users do not display

---

#### **People Groups**

##### Fix incorrect table variable reference and possible undefined temp table reference (#136729)

**Problem**

- People group users were not correctly updating after doing a hard refresh. This happened because at the start of the query, the materialised people group users are put into a temp table. The actual DB table is then updated from the newest calculations (which is correct). At the end, before returning the result, it selects again from the temp table, which does not include the updates, resulting in the incorrect users being returned.

**Solution**

- Clear and repopulate the temp table after the db table is refreshed, ensuring it uses the original list of people group IDs it received originally and not the list of people group IDs that needed to be refreshed, which can differ from the list of people group IDs for which we need to return users

---

# Version 9.1.208 (9 February 2026)

#### **Performance Management**

##### Error when adding a review setup without a name (#143965)

**Problem**

- The user gets an error when they add a review setup without a name.

**Solution**

- Make the name field a required property and give the custom sanitised input elements a required tag, which renders the required appearance

##### Fix event handlers being removed globally after page help is selected (#143965)

**Problem**

- After selecting the page help icon within the modal, it removes all click event handlers on buttons, etc.

**Solution**

- Corrected to make specific before removing click events

##### Resolved order of impersonating user route value (#143573)

**Problem**

- The route path expects the primary contract, then the impersonated user, whereas it is being supplied in reverse
- When the allow upload is checked, GRPC throws a valid exception that needs to be caught

**Solution**

- Corrected the order of path variables provided.
- Catch error and return a valid response

---

#### **Competency Analysis**

##### Fix popover, where the text is displayed in bold (#121394)

**Problem**

- The competency description popover displays in bold

**Solution**

- Ensure the popover text does not display in bold

---

#### **Ruleset Setup**

##### Created a script to dynamically delete data from Ruleset (#143128)

**Problem**

- Cannot dynamically delete data from Ruleset

**Solution**

- Implemented a new script to Archive and then delete data of a ruleset by id

##### Resolve URL sanitisation on multiple tabs (#143741)

**Problem**

- Cannot save on the system access, widgets and integration tabs

**Solution**

- Corrected the URL sanitisation on the system access, widgets and integration tabs
- Moved allowed domains configuration to ruleset 1

---

#### **Data Warehouse**

##### Updated Script for DWH Weekly Integrity Report (#142737)

**Problem**

- Script monGenerateDWHDataIntegrityReport needs to be updated for data source accDisciplinaryActions

**Solution**

- Updated Script monGenerateDWHDataIntegrityReport to update accDisciplinaryActions missing section to align with DWH Source Script

##### Created new Datasource cmNextCloudContents (#143697)

**Problem**

- New dataSource cmNextCloudContents is required within the DWH

**Solution**

- Created new Datasource cmNextCloudContents
- Created new SSIS Package ContentManagement\_ETL

##### Adjusted SQL Query C\_03712\_99999\_monitorDWHPackageResultsReport.sql (#143261)

**Problem**

- Adjustments need to be made to C\_03712\_99999\_monitorDWHPackageResultsReport.sql

**Solution**

- Adjusted script to exclude PackageLog.dtsx and select from WINDSORHYBRID

##### Updated accChats due to Refactor for Communication Portal (#143780)

**Problem**

- The package for accChats failed due to a refactor being done for the Communication Portal

**Solution**

- Adjusted source script with accChats to use new tables from the Communication Portal

##### Removed ReportCard fields within lmStudentSubjects and lmTermResults (#112511)

**Problem**

- The ReportCard fields are not required anymore within lmStudentSubjects and lmTermResults, as this is available within lmReportCards

**Solution**

- Removed ReportCard fields within lmStudentSubjects and lmTermResults

##### Updated Container for jpHRProcessRequestData (#143579)

**Problem**

- The jpHRProcessRequestData Update process did not work correctly

**Solution**

- Changed the update back to Truncate and Insert to ensure the data is being inserted correctly for jpHRProcessRequestData

##### Adjustments made within V9FullRefresh updates (#143176)

**Problem**

- When the V9 DWH are deployed to Production, the full refresh should not be updated for the afternoon run

**Solution**

- Updated Full Refresh steps to only update after 12 pm if the DWH package is deployed on Production during the morning

##### Updated Source Query for PackageLog.dtsx (#143261)

**Problem**

- PackageLog.dtsx needs to be excluded from PackageLogs

**Solution**

- Updated Source Query to exclude package\_name 'PackageLog.dtsx'

---

#### **Report Builder**

##### Added extra filter cases for datetime2 and adjusted filter for "Choose a specific date" (#142737)

**Problem**

- The filters, when using datetime, did not filter correctly
- "Choose a specific date" required conversion for certain scenarios

**Solution**

- Added extra filter cases for datetime2
- Adjusted filter for "Choose a specific date"
- Removed smalldatetime as we do not use this currently

---

#### **Notifications**

##### Resolved Properties not being replaced correctly (#143598)

**Problem**

- With the new masked property development done, once a property exists both for mask and non-mask, it will always just replace masked property values, keeping the placeholder for the property name

**Solution**

- Add a change that should we identify it is masked, do an extra check if there is any placeholder without the masked property to also update and replace

---

#### **People Management**

##### Remove previous validation messages and classes when selecting values for position and org. Resolve timeout on org node treeview (#143806)

**Problem**

- Validation messages are not removed immediately after selecting values, only after the form is posted.
- A timeout occurs when opening the org tree structure in the position transfer page.

**Solution**

- Remove previous validation messages and classes when selecting values for position and org.
- Also noticed while testing the bug, the org tree times out.
- Added a recompile option on the query, as the query runs fast in SSMS

##### Improve error messages for overlapping appointments (#143328)

**Problem**

- When adding a new appointment, editing an existing appointment or transferring the use,r the error message provides unspecific information to the user when it overlaps with a current appointment for the user themselves or on another position for another user

**Solution**

- Add new error messages for the overlap with more details of the user and the appointment that is overlapping.
- Remove duplicate code and improve error message handling.
- New error messages: 
    - Appointment overlaps with the user's own current appointment on position {{PositionTitle}} from {{AppointedFromDate}} to {{AppointedToDate}}. An appointment already exists for position({{PositionTitle}}) from {{StartDate}} to {{EndDate}} for user {{Username}}.

##### Always include default avatar images on the list of available avatar options (#135931)

**Problem**

- The default list of avatar images is not shown.

**Solution**

- The previous fix was reverted with the merge
- Restored solution to always fetch default avatar images

---

#### **Imports**

##### Add API call to v8 to delete appointment history (#143323)

**Problem**

- When an appointment is deleted in V9, the Appointment history is not deleted in V8.
- There was a request to add an API endpoint in V8 (Already merged) and an API call in V9 to ensure the Appointment History is deleted.

**Solution**

- Add new functionality in the import service to delete Appointments based on a List of IDs.
- This endpoint is generic and can also be adjusted to work for various other types of items, for example, job profiles.

---

#### **Communication Portal**

##### Resolved member count error (#143761)

**Problem**

- When selecting room members, this will return a view of users within the group, but still used old table for members

**Solution**

- Corrected query to select the room members

##### "Create New" button scrolls with the chat list (#143763)

**Problem**

- The new button is positioned absolutely within a relative container, causing the render to work, but as content gets shown from the accordion button is scrolled alongside container

**Solution**

- Adjust to render outside the modal body, which is not within the relative container that makes it to the modal position itself

##### \[PM\] Cannot return to the list of chats if you've sent a message from within a person's agreement (#143858)

**Problem**

- When inside a PM contract, discussion is open, which calculates to create a new discussion and not open discussion list, but once navigated back to the dashboard, a REACT change occurred, and no page redirect in MVC, which does not reset the content for the modal and the bool value is allowed to just reopen the modal as no 'context' has changed

**Solution**

- Add route value to be saved alongside the opening of the modal, so that should the route change, navigate inside REACT the portal will force reload if it is different from when opened in another context

---

#### **People Groups**

##### Add 'LastRefreshed' to list ruleset people groups (#143598)

**Problem**

- When a V8 menu is clicked, and the user's data is imported, then the peoplegroups linked to a user are also imported as subgroups, and their users are linked
- When more than one user is imported that has the same PGs linked to them, the PG data is unnecessarily fetched from V9, causing the PG calculation to use unnecessary resources

**Solution**

- When the PGs linked to a user are fetched, return the last refreshed date for the PG also
- Only fetch PG users then for the linked PGs where the last refreshed date is after the last edit of the people group users on V8
- This will limit unnecessary calls to the Peoplegroup users

---

#### **Learning Management**

##### Filter MaterialisedPeopleGroupUsers to only show active people on the PG on the attendance and marksheet page. When inheriting, marks only inherit from people who are an active part of the PG (#143629)

**Problem**

- On the attendance and mark sheets, inactive users are also included who are part of the PG

**Solution**

- Change to not take People condition for a user into account when the person is terminated
- The person will not be part of the people group users, and the count on the list of people items will not count this item
- Do not show terminated people on the attendance or attendance detail pages
- When marks are inherited, do not inherit marks from previous for terminated users in the subject's people group

---

#### **Content Management**

##### \[Image Resources\] \[Translation\] Translation for "Image Type" is missing (#143740) 

**Problem**

- Missing translations in the file type

**Solution**

- Added translation for field

##### \[Image Resources\] Preview not available when uploading a GIF file (#143783) 

**Problem**

- Restriction has been implemented to only compress image types, which excludes SVG and GIF files. Because of this, it does not render a compressed image and shows no preview available, which can cause confusion and seem like an error

**Solution**

- Adjust the flow to handle the null value of compressed to then not show the selection of image type, which results in the original image being selected

##### \[Image Resources\] \[Suggestion\] Streamline upload modal (#143736) 

**Problem**

- No clear indication as to why there is a choice or reason

**Solution**

- Add a label to indicate to select an image, move the compressed to the first selection and add a subtext to indicate the reason for the selection

##### \[Image Resources\] Display loading indicator after selecting an image (#143734) 

**Problem**

- When a file is selected, a new fetch call is made to retrieve the image and the compressed file; this does not trigger the ajax load to trigger a loader

**Solution**

- Add a new implementation to trigger a global event so that a loader is shown and then removed when the result is received

---

# Version 9.1.107 (9 February 2026)

#### **Report Builder**

##### Added extra case "Choose a specific date" within the where clause for filters and resolved conversion error (#143579)

**Problem**

- The current reports failed due to a conversion error with recently added extra date cases within the where clause for filters
- An extra case for Choose a specific date is required

**Solution**

- Updated script C\_00011\_99999\_ReportBuilder\_CreateSQLStatement.sql by adding an extra case "Choose a specific date" within the where clause for filters, and resolved conversion error

##### Added extra cases within the where clause for filters (#142011 &amp; #143230)

**Problem**

- The ReportBuilder gave an error due to string fields being used for date filters, and double quotations are inserted for date fields

**Solution**

- Added specific cases within the where clause for filters to ensure dates are being inserted correctly when using operators

---

#### **Identity and Authorisation**

##### Resolved font size on terms of use URL (#143651)

**Problem**

- Terms of use URL font size is the same as other a tags

**Solution**

- Decrease the font size

##### Add starting password for a user after appointment (#139782)

**Problem**

- When a new user is imported or appointed, they do not have a default password to start with

**Solution**

- Implemented a new change to set a default password on product Setup. When new users are created within Identity, they will use the default password. On first sign-in, a new expired result will be returned
- Resolved file import not setting default password

---

#### **People Management**

##### Implemented loading indicator on tab switch (#143524)

**Problem**

- When navigating between pill items within people management, no loading indicator is present

**Solution**

- Implemented a change to show a loading indicator

---

#### **Ruleset Management**

##### Resolved system access settings being thrown as an error (#143637)

**Problem**

- Cache implementation on ruleset system access settings, but once a save is initiated on the page, it triggers a clear to identity. If you stay on the page and save again, there is no item in identity, so it can not remove anything, which causes the 2nd save to show it failed to save

**Solution**

- Add a check to first confirm that there is an item before validating the TryRemove, else default to true for removed

##### Resolved domains saving as HTML (#143569)

**Problem**

- New section to enter allowed domains for a ruleset, but when saved, it saves through the mceEditor as HTML

**Solution**

- Added a change to set to plaintext before form submit to get plain text

##### \[Integrations\] Improve validations on the Integrations page (#143200)

**Problem**

- It is unclear what validation fails between the content server and sanitisation on the integration tab

**Solution**

- Split the content server setup and the general
- Ensure that the sanitaztion fatally falls rather save that fail
- Add the org path to the sanitised URLs

##### Media compression process - V9 (#140478)

**Problem**

- Currently, media is uploaded in its original size to the system without being compressed or optimised

**Solution**

- Implement a background service that cycles through media uploaded to the system and:
- Compress uploaded media
- Remove original large media
- Keep track of what was compressed to compress it once

---

#### **Event Scheduling**

##### Fix spelling error and icon on calendarview which does not load properly (#143375 &amp; #143488)

***Issue 1***

**Problem**

- Spelling error on pop-up modal

**Solution**

- Fix the spelling error

***Issue 2***

**Problem**

- An incorrect icon is being displayed on the Calendar View

**Solution**

- Import Syncfusion icons on the index.scss file for event scheduling

---

#### **System Access**

##### Resolved Account Swagger API (#10645)

**Problem**

- Duplicate test rate limit endpoints configured

**Solution**

- Removed duplicate

##### Shared grpc proto files (#143197)

**Problem**

- When updating proto files, the same proto file needs to be copied to multiple services, which wastes unnecessary time for developers to copy and maintain these files. Also, there is a high possibility of conflict during merges.

**Solution**

- Refactor GRPC Proto to one shared file

---

#### **Imports**

##### Add missing manager to the user import API to correct the mapping when importing custom fields (#135967)

**Problem**

- Userimport API mapping is incorrect when customfields are imported

**Solution**

- Added LeaveManagerAlternateApproverUsername and SecondaryJobRequisitionApproverUsername to the mapping in ImportManagementServiceV1 to support additional approver information.

---

#### **Content Management**

##### Restore the missing availability check on content management (#143582)

**Problem**

- The content management service availability check is missing, preventing the upload and download of PM documents

**Solution**

- Restore Content Management service availability check

---

#### **Learning Management**

##### Fix Subject Copy functionality (#143406)

**Problems**

- When a user copies and then saves a subject twice, a validation error occurs because the subject details are not being saved correctly during the copy process.
- The "Copy and Save" function does not accurately save the subject details.
- The "Copy" feature allows users to save a Class/Group that has already been used.
- Saving a copy of a page more than once creates duplicates instead of saving the newly copied subject.

**Solutions**

- Update the backend scripts to handle the copy page differently.

##### Don't include any URLs on absent notification templates (#143521)

**Problem**

- When an image has been added to the absent notification template, the editor automatically changes the reference to relative URLs.
- When the actual email is then sent out, the image path cannot be located, and the broken image link icon is displayed.

**Solution**

- Ensure that the editor does not replace any URLS and maintains the full paths provided.

---

#### **Performance Management**

##### Resolved styling on nav section item (#143453)

**Problem**

- When minimising the window text gets wrapped inside a container that has a fixed size and margin, also adding unneeded space

**Solution**

- Implemented a change so that the height gets adjusted to the content of the element, with padding around

---

#### **Communications Portal**

##### Large volumes on chat (#136516)

**Problem**

- When creating a new group chat or opening a group chat, all users of the people group linked to the chat group are loaded to the screen, causing the screen to break.
- When sending a chat message on a group, the chatreadlog is populated for each user in the chat group for every message, causing the table to grow exponentially

**Solution**

- Change the code to not load all users to the partial when the chat is a group type.
- When sending a message, send it from the communication portal via SignalR after the message has been saved
- Change the chat readlog to only store one record per user
- Split the message id column into a LastReadMessageId and a LatestMessageId
- The LastReadMessageId is used to indicate the blue ticks for the user, and the LatestMessageId to indicate if the user does have message that has not yet been read.

##### \[Coms Portal\] Keep section open while deleting chats (#143516)

**Problem**

- When deleting a chat group, the component is reloaded,

**Solution**

- Do not reload the component, but just remove the row from the grid.

---

# Version 9.1.206.3 (Support Release - 29 January 2026)

#### Performance Management

##### Resolved data type on pre-recalculate score (#143988)

**Problem**

- Incorrect data type for decimal, so contracts with larger max ratings can not recalculate

**Solution**

- Corrected data type

##### Resolve issue where viewing documents on the KPA / Perspective level only showed the first KPI documents (#138511)

**Problem**

- When clicking on the view documents on the KPA or Perspective level, it only shows documents loaded on the 1st KPI.

**Solution**

- Corrected the reference filter to correctly check against which level to display documents

---

# Version 9.1.206.2 (Support Release - 27 January 2026)

#### **Performance Management**

##### Resolved order of impersonating user route value (#143573)

**Problem**

- The route path expects the primary contract, then the impersonated user, whereas it is being supplied in reverse
- When the allow upload is checked, GRPC throws a valid exception that needs to be caught

**Solution**

- Corrected the order of path variables provided.
- Catch error and return a valid response

---

#### **Ruleset Management**

##### Resolve URL sanitisation on multiple tabs (#143741)

**Problem**

- Cannot save on the system access, widgets and integration tabs

**Solution**

- Corrected the URL sanitisation on the system access, widgets and integration tabs
- Moved allowed domains configuration to ruleset 1

##### Resolved system access settings being thrown as an error (#143637)

**Problem**

- Cache implementation on ruleset system access settings, but once a save is initiated on the page, it triggers a clear to identity. If you stay on the page and save again, there is no item in identity, so it can not remove anything, which causes the 2nd save to show it failed to save

**Solution**

- Add a check to first confirm that there is an item before validating the TryRemove, else default to true for removed

##### Resolved domains saving as HTML (#143569)

**Problem**

- New section to enter allowed domains for a ruleset, but when saved, it saves through the mceEditor as HTML

**Solution**

- Added a change to set to plaintext before form submit to get plain text

---

#### **Learning Management**

##### Filter MaterialisedPeopleGroupUsers to only show active people on the PG on the attendance and marksheet page. When inheriting, marks only inherit from people who are an active part of the PG (#143629)

**Problem**

- On the attendance and mark sheets, inactive users are also included who are part of the PG

**Solution**

- Change to not take People condition for a user into account when the person is terminated. The person will not be part of the people group users, and the count on the list of people items will not count this item.
- Do not show terminated people on the attendance or attendance detail pages. When marks are inherited, do not inherit marks from previous for terminated users in the subject's people group

---

# Version 9.1.206.1 (Support Release - 19 January 2026)

#### **Imports**

##### Add a missing manager to the user import API to correct the mapping when importing custom (#135967)

**Problem**

- Userimport API mapping is incorrect when customfields are imported

**Solution**

- Added LeaveManagerAlternateApproverUsername and SecondaryJobRequisitionApproverUsername to the mapping in ImportManagementServiceV1 to support additional approver information

---

#### **Content Management**

##### Restore the missing availability check on content management (#143582)

**Problem**

- The content management service availability check is missing, preventing the upload and download of PM documents

**Solution**

- Restore Content Management service availability check

---

#### **Learning Management** 

##### Fix Subject Copy functionality (#143406)

**Problem**

- When a user copies and then saves a subject twice, a validation error occurs because the subject details are not being saved correctly during the copy process.
- The "Copy and Save" function does not accurately save the subject details.
- The "Copy" feature allows users to save a Class/Group that has already been used.
- Saving a copy of a page more than once creates duplicates instead of saving the newly copied subject.

**Solutions**

- Update the backend scripts to handle the copy page differently.

##### URLs on absent notification templates (#143521)

**Problem**

- When an image has been added to the absent notification template, the editor automatically changes the reference to relative URLs. When the actual email is then sent out, the image path cannot be located, and the broken image link icon is displayed.

**Solution**

- Ensure that the editor does not replace any URLS and maintains the full paths provided.

---

#### **Performance Management**

##### Resolved styling on nav section item (#143453)

**Problem**

- When minimising the window text gets wrapped inside a container that has a fixed size and margin, also adding unneeded space

**Solution**

- Implemented a change so that the height gets adjusted to the content of the element, with padding around

---

# Version 9.1.206 (19 January 2026)

#### **People Management**

##### Change people groups query to use dynamic parameters to avoid parameter sniffing (#143512)

**Problem**

- The dapper query to fetch the list of people group users can, at times, take extremely long.
- This is due to the query plan caching and the parameter sniffing that is required with the current implementation.

**Solution**

- Added OPTION RECOMPILE to the temp table insert query, additionally changed the Dapper parameters to be dynamic to allow specifying the exact types, which enables SQL to create a better execution plan.
- Date values are submitted through as datetime parameters and not as varchar

---

#### **System Access**

##### Resolved system access not saving, throwing a sorry page (#143531)

**Problem**

- Url changes implemented for validation, and a new object is stored as JSON. Within the JSON conversion, it could not deserialise correctly

**Solution**

- Add implementation to navigate and correctly add items to a new list

---

# Version 9.1.205 (19 January 2026)

#### **Data Warehouse**

##### Corrected the SQL Source query (#143362)

**Problem**

- The Container for jpJobCompetencyInherentRequirements has failed due to source table changes

**Solution**

- Resolved issue by updating the Source query step for container jpJobCompetencyInherentRequirements

##### Created new SSIS Package "PackageLog.dtsx" (#143261)

**Problem**

- A table is required to log and store the DWH Package results
- Script is required to fetch and return DWH Packages results to measure Performance

**Solution**

- Created a new SSIS Package and table "PackageLog"
- Created sp monitorDWHPackageResultsReport to return the latest DWH Package results

##### Added a step to update the Active field within jpAppointments (#142737)

**Problem**

- The active was not updated for all the older Appointments since this is calculated manually within the DWH

**Solution**

- Added a step within Appointments to update the Active field for all the Appointments to ensure it is updated

##### Removed Shrink Log File step with Full Refresh (#142737)

**Problem**

- Since the Full Refresh has been adjusted only to refresh data for the current year, the Shrink Log File Step is not required anymore within ExecuteSequence

**Solution**

- Removed step "Shrink Log File for V9\_Datawarehouse with Full Refresh" within ExecuteSequence SSIS Package

##### Corrected Truncate step for rbDataIntegrityResults (#142737)

**Problem**

- An incorrect table name was used to try to truncate rbDataIntegrityResults, which is causing the package to fail

**Solution**

- Corrected SQL statement in the "Truncate rbDataIntegrityResults" task to reference the correct table name

---

#### **Performance Management**

##### Resolve various bugs due to visually impaired changes (#142553)

**Problem**

- Scrolling on a contract page is no longer working as it should. When you scroll down, the banner with the person's details should be made smaller, to only display the portrait and name (and score gauges when applicable). The panel on the left should always stay visible, and as you scroll, it should highlight the sections that are currently visible. Only the section cards should scroll up and down.
- Styling issue when selecting a score during the rating phase. The highlight does not cover all the text, and it is flat on the left and right sides instead of round.
- Delete the modal when deleting the agreement period is not working correctly. You cannot enter a delete reason because focus is lost after clicking in the text field. When you click cancel, the modal starts flickering.
- Cannot open the review period by clicking on the overall summary score Gauge

**Solution**

- Resolve the problem with the scroll not working correctly and the banner not auto-collapsing on scroll. Also fixes the scrollspy stickytop issue.
- Correct the problem with selected ratings styling
- Correct issue with the delete modal losing focus when clicking on the deletion reason
- Resolve the problem of not being able to open the contract from the overall summary score gauge

##### Resolve issue with editing section weights on contract due to missing parameter (#143437)

**Problem**

- Unable to edit section weights on a contract due to the missing primaryContract parameter not being sent from the frontend.

**Solution**

- Added missing parameter

##### Resolve issue with deleting action plans (#143402)

**Problem**

- Unable to delete action plans due to a missing primary contract parameter required for authentication

**Solution**

- Add required parameter

##### Resolve issue with adding/editing action plans (#143402)

**Problem**

- Error received when trying to add or edit action plan items. Bug due to recent additional contract development

**Solution**

- Resolve missing parameter not sent through when adding / editing / copying action plans.

---

#### **Identity and Authorisation**

##### File import not setting default password (#139782)

**Problem**

- When importing users from the frotnend the password does not get set

**Solution**

- Implemented a call to get the default password and set the password hash
- Implemented a new change to set a default password on product Setup. When new users are created inside identity it will make use of the default password, and a new expired result will be returned

---

#### **Job Management**

##### Resolve issue with Job Inherent Requirements incorrectly updating when rating on competency analysis (#143362)

**Problem**

- When rating competency for a user for Job Inherent Requirements, if multiple requirements of the same Master Data type exists all corresponding records for the same type are updated incorrectly.
- Picked up a design problem where for the Job Inherent Requirements, multiple requirements per type can be added; however, for the analysis, the Job Competency Inherent Requirements entity is incorrectly linked to the master data record instead of the job inherent requirement record, resulting in a user can only ever have one requirement per type.
- Front-end and backend allow for working with multiple per type, but cannot distinguish on the record level to which Job Inherent Requirement it is linked and as per the issue on request, updating one record leads to all of the same type being updated.

**Solution**

- Remapped the Job Competency Inherent Requirement to the Job Inherent Requirement and updated all references accordingly.

---

#### **Imports**

##### Update email confirmation logic in user creation (#142626)

**Problem**

- Email is not confirmed when empty

**Solution**

- Replaces dynamic email confirmation check with a hardcoded true value when creating users via gRPC.
- This change ensures all users created through people management have confirmed emails, likely to simplify sign-in during the MVP phase.

---

#### **Report Builder**

##### Resolved date filter breaking SQL script (#143230)

**Problem**

- When a datetime filter is added, the SQL script throws an exception as the datetime is not within an apostrophe

**Solution**

- Add a filter check to concat when the types are of datetime

---

#### **Event Scheduling**

##### Resolved Event Name not being set when tab page is reloaded (#140617)

**Problem**

- When navigating to a tab, the event name is already loaded from event details, but should you refresh the tab, it reloads the content, where the event name is removed

**Solution**

- Add a change to retrieve the event name on each tab to emit to set the display of the event name

---

# Version 9.1.204 (19 January 2026)

#### **Performance Management**

##### Implemented calculated average score (#142544)

**Problem**

- The KPI Calculated Average is not available on the View/Print | Export to Excel report

**Solution**

- Implemented a new column in the data export on contract preview

##### Resolved KPI not being able to delete (#143253)

**Problem**

- The primary contract's bool value was not being sent through, which caused an invalid object

**Solution**

- Add a change to pass through the primary contract's bool value

##### Resolved Scroll jumping to the top of the page after rating (#142537)

**Problem**

- Visually impaired changes made a change to auto focus first item for every useeffect change, this caused that when a rating was done it scrolled to the top

**Solution**

- Add a change to stop concurrent refocus to the top

##### Fix document link for KPIs, Disable buttons on content view when content server is unavailable (#140522)

**Problem**

- When clicking on View Documents on the KPI level, a page not found is displayed. When the content server is unavailable, clicking on the download or upload of a document causes errors

**Solution**

- Fix the view documents link for the KPI level. Add handling to show a content server unavailable message and disable buttons when the content server cannot be reached.

---

#### **Imports**

##### Remove duplicate self-service settings in validation when importing users (#142626)

**Problem**

- Cannot import users when ESS settings are duplicated in the DB

**Solution**

- Removes duplicate rows in ESS settings, keeping only the most recently edited entry for each unique combination of `FieldSection`, `FieldId`, and `RulesetId`. \* Updated the construction of the `requiredFields` dictionary in `UserDetailsValidationService.cs` to ensure unique combinations of `FieldSection` and `FieldId` are included, preventing issues caused by duplicate settings.

##### Resolved import not being triggered (#143185)

**Problem**

- Data-Action URL is not taken into account when the form modal is being submitted

**Solution**

- Corrected code and safety to use the action, and set the input fields correctly after selecting items.

##### Add custom user import SQL scripts for clients (#132261)

**Problem**

- There is no area to version the custom client import steps

**Solution**

- Introduced new SQL procedures for Discovery, FamousBrands, and Hirexe user import processes. These scripts implement custom pre/post import logic, such as clearing email addresses based on field values and removing non-Hirexe appointments, to support client-specific requirements.

---

#### **Data Warehouse**

##### Changed column name from ExecuteSequenceLastRefreshed to V9ExecuteSequenceLastRefreshed within PackageSettings (#143103)

**Problem**

- Only naming the column field to ExecuteSequenceLastRefreshed will create confusion when using V8 DWH as well

**Solution**

- Changed column name from ExecuteSequenceLastRefreshed to V9ExecuteSequenceLastRefreshed within PackageSettings

##### Resolved duplicate issue within accTenants (#142737)

**Problem**

- Duplicate data is being inserted within accTenants

**Solution**

- Added Distinct to resolve the duplicate insert issue

##### Added Update LastRefresh Steps within ExecuteSequence (#143103)

**Problem**

- LastRefresh data is required for SSIS Packages

**Solution**

- Added LastRefresh steps for all SSIS Modules and ExecuteSequence that will update within the table PackageSettings

##### Created new table rbDataIntegrityResults (#142922)

**Problem**

- A new table, rbDataIntegrityResults, is required within V9 DWH
- New fields are required within PackageSettings to update Last Refreshed for all modules

**Solution**

- Created a new table, rbDataIntegrityResults, within ReportBuilder\_ETL.dtsx
- Created a Script that will email the results to the required employees - Added fields PeopleManagementLastRefreshed, JobProfilerLastRefreshed, PerformanceManagementLastRefreshed, TenantManagementLastRefreshed, DataDictionaryLastRefreshed, LearningManagementLastRefreshed, LearningManagementReportLastRefreshed, ReportBuilderLastRefreshed and ExecuteSequenceLastRefreshed within PackageSettings

##### Adjustment made within LearningManagementReport (#143104)

**Problem**

- Adjustments are required within LearningManagementReport

**Solution**

- Moved manual update steps to its own container
- Updated manual step queries to update to the DWH table instead of the Staging table

##### Removed unused tasks from CreateFunctions (#125159)

**Problem**

- Some tasks are not being used anymore within SSIS Package CreateFunctions

**Solution**

- Removed unused tasks from SSIS Package CreateFunctions

##### Updated Insert steps within LearningManagement\_ETL (#140865)

**Problem**

- The package is currently failing with a full refresh due to joining with RulesetID within Insert Steps for LearningManagement

**Solution**

- Updated Insert steps within LearningManagement\_ETL by removing the RulesetID join

##### Updated Insert steps within JobProfiler\_ETL (#140865)

**Problem**

- The package is currently failing with a full refresh due to joining with RulesetID within Insert Steps for JobProfiler

**Solution**

- Updated Insert steps within JobProfiler\_ETL by removing RulesetID join

##### Updated Insert steps within PeopleManagement\_ETL (#140865)

**Problem**

- The package is currently failing with a full refresh due to joining with RulesetID within Insert Steps for PeopleManagement

**Solution**

- Updated Insert steps within PeopleManagement\_ETL by removing RulesetID join

##### Resolved errors within UpdateDataDictionary.dtsx (#142103)

**Problem**

- An error is received when selecting all the datasource fields for JobProfiles within ReportBuilder, since certain fields no longer exist anymore
- An error is received within "Add DataSourceJoins 2" due to not pointing to the correct Connection String

**Solution**

- Corrected the Data Dictionary to exclude fields for JobProfiles that do not exist anymore within the Data Warehouse
- Corrected Connection String for "Add DataSourceJoins 2"

---

#### **People Management**

##### Add immediate imports after transfer to another ruleset (#142770)

**Problem**

- When the user is transferred, the import is not requested immediately, delaying the sync of learner records

**Solution**

- Moved reporting line, cache busting and additional service import triggers from PeopleController to JobProfilerServiceV1 for better encapsulation. Added GetUsernameAsync to IUserQueries and UserQueries to support username retrieval by user ID. Updated ImportUsersEventConsumer to limit ImportTypes to UserData only. Also added placeholder fields for parent/guardian names in user export.

##### Fix materialisation when a people group has not been materialised before | Fix regression bug on people termination (#136729)

**Problem**

- When materialising people groups and the list of people groups to materialise is empty, it only materialises for people groups that have already been materialised in the past.

**Solution**

- When the 'forceSync' parameter is true, refresh for ALL people groups on the ruleset (if an empty people group was received).
- Still, only materialise people groups already materialised when 'forceSync' is false.
- \*\*PLUS\*\* Other issue picked up while testing: Termination broken due to a regression bug. A new field was added to a model used in a query in job profiler, but the query was not updated, which results in the query breaking, meaning ultimately people cannot be terminated anymore. Updated the model to make use of auto properties instead of a constructor, which makes it easier for Dapper to map the query result to the model.

##### Update SkiaSharp dependencies and Docker setup (#139069 &amp; #142672)

**Problem**

- The component to convert images and Word documents is not available, and an error is received. The version of the native libSkiaSharp library (88.1) is incompatible with this version of SkiaSharp. Supported versions of the native libSkiaSharp library are in the range \[116.0, 117.0).\\u0022)) An error occurred while processing your request., , , The type initializer for SkiaSharp.SKImageInfo threw an exception.)","Exception":"System.TypeInitializationException: The type initialiser for SkiaSharp.SKImageInfo threw an exception. System.DllNotFoundException: Unable to load shared library libSkiaSharp or one of its dependencies.

**Solution**

- This pull request updates the SkiaSharp dependencies to the latest version and ensures the application runtime environment is properly configured for SkiaSharp support. It also includes some minor code cleanups and Dockerfile improvements.

##### Hide summary sections that the people group do not provide access to (#139878)

**Problem**

- When the people group does not allow access to a section

**Solution**

- Added checks to only display payroll connector and payroll ID fields for the admins and manages, the user should not see the fields on their own profile. Updated ProfileSummaryViewModel to refine view permissions for particulars, contact details, and address based on user and group permissions.

---

#### **Report Builder**

##### Resolved Delete button not being enabled when toggle is checked (#143032)

**Problem**

- When a toggle is active for confirmation on the deletion modal, the delete button is not enabled

**Solution**

- Add a change to toggle the disabled state depending on the checked state

---

#### **System Access**

##### Implement rate limiting for gRPC transcoding HTTP requests (#142267)

**Problem**

- APIs do not impose any restrictions on the size or number of resources that can be requested by the client/user

**Solution**

- Add change to rate limit endpoint calls

##### Implement custom post import step (#137281)

**Problem**

- Employees do not have individual email addresses and are unable to reset their passwords, as they can not receive the Welcome mail

**Solution**

- Implement a step to set the user password hash when empty

##### Enhance the chatbot code to URL and JS detection (#142505)

**Problem**

- When the bot code is anything other than a properly formatted JS function, the Sanitisation does not work. Any URL and methods are then allowed that are incorrect.

**Solution**

- Change the URL checking to identify any URL regardless of the formatting, and if it is not part of the whitelisted URL, reject and clear the text received. Attempt to format the text before parsing to JS to allow the functions to work better. Other improvements identified during the above work to prevent harmful scripts of being injected.

---

#### **Exports**

##### Resolved Export notification not being shown (#143192)

**Problem**

- Change was made to trigger a download once export has been interacted with, due to messages being sent it was sent to each tab of the user that triggered a download, change was made to generate tab-ids for each request and only download on the tab that it interacted on, this caused that on report builder the id was not set hence why no message was shown

**Solution**

- Add a change to generate a tab ID to be sent with the export of a report

---

#### **Communication Portal**

##### Added media query to resolve position (#137794)

**Problem**

- On certain screen resolutions, the add button is rendered behind the footer, and one of the selections can not be seen clearly

**Solution**

- Add a media query change to accommodate this screen resolution

---

#### **Job Management**

##### Resolved job profile count (#140550)

**Problem**

- Count varied from the first load and then, when opened, resulted from the partition, as there could be multiple positions within a job profile

**Solution**

- Add a change to correct the partition for joins and counts

##### Resolved Job Profile Not being copied and global error snack (#142903)

**Problem**

- When copying a job profile, an exception is thrown because it tries to copy the disclaimer as well. Because of the value object, it created a reference to the job profile ID that causes the error. A recent change was made to ajax.tsx to correct the console errors being logged when partial view results are being returned over ajax, but this caused the middleware general exceptions snack messages did not display any more

**Solution**

- Add a change to create a new value object for disclaimer settings
- Revert and add another change to implement and correct to not write console errors when it is not JSON.

---

#### **Pathways**

##### \[Annotation\]\[Syncfusion\] Layout changes (#139069)

**Problem**

- Not all the stamps are available. A stamp reverts to the previous stamp when used more than once. The stamp does not persist between pages. When reusing ink and stamps where used before the stamp is reactivated

**Solution**

- Significant enhancements to the PDF annotation functionality in the pdfAnnotation.js file, focusing on improved custom stamp handling, user experience, and code clarity.
- It also updates the configuration to use production endpoints for the PDF viewer server and adjusts Content Security Policy settings for development.
- PDF Annotation and Custom Stamp Functionality: Refactored custom stamp toolbar integration: 
    - Custom stamps are now added to the toolbar with clear identifiers and properties, enabling easier mapping between toolbar buttons and stamp types.
    - The toolbar now also includes new stamps such as "Half" and "Blue Half Tick", and supports rotating pages with new rotate buttons.
    - Improved stamp selection and re-arming: Introduced logic to reliably restore the selected custom stamp after page changes and annotation additions, ensuring a smoother user experience when annotating multi-page PDFs.
    - Added robust page rotation support: Implemented a rotateAndReload function that supports both document-level and viewer-level rotation, handling active annotation modes and ensuring the viewer state remains consistent.
    - Enhanced annotation mode toggling: 
        - Refined ink annotation toggling and ensured that switching modes resets the custom stamp selection, preventing mode conflicts.
        - Configuration and Security: Updated PDF viewer server endpoint to production: Changed the PdfViewerServer URL in development settings to point to the production API for more realistic testing. Expanded Content Security Policy for development: Added the production server to the connect-src directive, allowing connections to the new PDF viewer endpoint during development.

---

#### **Identity &amp; Authorisation**

##### Resolved registration textarea field not outlining correctly (#142116)

**Problem**

- Within the input fields, there is styling that gets generated, which adds a border outline and correction when the label moves up, but on textareas, it does not

**Solution**

- Add a change to also add these divs to textareas so that the same styling and behaviour gets used

##### Resolved MFA enhancements (#143105 &amp; #143100)

**Problem**

- The countdown timer was adding a suffix with the added countdown value, which caused the old countdown and the current to be displayed next to each other. Missing translations

**Solution**

- Added a change to the countdown to remove and add as the timer counts down for resend, Added missing translations

---

# Version 9.1.203 (19 January 2026)

#### **System Access**

##### Update email confirmation logic for user import and update to allow a user without an email to login (#142626)

**Problem**

- A user without an email address cannot log in because the email has not been confirmed.

**Solution**

- In ImportUsersCommandHandler, email is now considered confirmed if the user has no email address. In UpdateUserCommandHandler, email is always marked as confirmed. These changes ensure consistent handling of email confirmation status during user import and update operations.

---

#### **Imports**

##### Change Import Modal to only fetch import status and available imports when opened (#138821)

**Problem**

- Currently, on every page, navigation checks are done on the import status being retrieved

**Solution**

- Change to only load the import status when being opened

---

#### **Job Management**

##### Resolved positions not loading the correct filter type (#140550)

**Problem**

- When job profiles are loaded, icons indicate the count of vacant, filled and inactive positions, but once clicked, it results in all positions

**Solution**

- Implement new development to list positions based on the filter type

##### Resolved sanitise text on reporting line (#142578)

**Problem**

- The title of the span is being set and used from JavaScript to set the modal title. When the title of the modal is set, it gets set with the encoding values when HTML is rendered

**Solution**

- Add a change to set the modal title as raw text to not be encoded

---

#### **Report Builder**

##### Resolved data source width expand and console error on invalid ajax json (#140432 &amp; #141369)

**Problem**

- On Firefox, the expand click event did not trigger from SVG find, script issue on Firefox that does not allow inline events CSP\* Console errors being logged when JSON is passed, which is HTML for partial views

**Solution**

- Add a change to rather just check for class collapse, move the event handler to the JavaScript file. Add a change on ajax.ts to handle JSON to not parse, should it be HTML and rather warn than error

##### Resolve issue where race condition on Ruleset creation prevents initial user from materialising on ReportBuilder (#140410)

**Problem**

- When a new ruleset is created, the ruleset creation is requested on each service sequentially. However, the user is copied to the new ruleset as soon as the ruleset is created, and then the SingleUser event is emitted, which informs all other services to materialise the user. This creates a race condition where the SingleUser create event reaches ReportBuilder before the ruleset creation has happened, and because of the foreign key relation between the materialised user and materialised ruleset table on RB, the user creation fails, and the first ruleset user is never created.

**Solution**

- Added additional functionality on the RulesetCreation on ReportBuilder, after the ruleset has been materialised, to check if there exist materialised users and then fetch all current users for the ruleset from Account Service and materialise them immediately

---

#### **Performance Management**

##### Reload page when user contract is deleted (#142780)

**Problem**

- Page reloads only if an additional contract is deleted

**Solution**

- Add a change to reload the page after the primary contract deletion

##### Resolve issue where bulk actions are not displaying all users (#142546)

**Problem**

- On bulk actions, the list of people displayed on the select list does not include all the available users, because only the first 20 users are filtered out when fetching details from JobProfiler, and then those with contracts or for the review year setup aren't all returned.

**Solution**

- Change functionality to the first page for users from performance management, then after selecting job details. Fixed the load more / load all functionality

##### Add loading indicator when creating contract (#142777)

**Problem**

- When creating a contract for a review setup, no loading indicator

**Solution**

- Add loading indicator

##### Resolve order of review setup names (#141701)

**Problem**

The order causes the numeric values to be incorrectly ordered, for example, Setup 1, Setup 10, Setup 2

**Solution**

Add change to the comparison to take numbers into consideration

---

#### **Identity**

##### Enhance MFA process with option to remember (#134730)

**Solution**

- Add change and enhancement to the MFA process. Add input to allow ruleset to change the number of hours to remember MFA, should they wish

---

#### **People Management**

##### Optimise user org path queries and improve appointment selection when calculating people group users (#142962 &amp; #142233)

**Problem**

- A user with an active and future-dated appointment has an incorrect future status in the calculated people group, and the user is excluded from the TA where it is used.

**Solution**

- Refactored user org path queries to use temp tables and bulk copy for efficiency, and improved appointment selection logic to better prioritise current appointments. Updated related PeopleGroups queries and gRPC service to handle distinct user IDs and avoid unnecessary queries.

##### Fix uploading profile image, causing user banner to be removed (#142688)

**Problem**

- Uploading a profile image causes the user's banner to be removed.

**Solution**

- Use the existing profile image if one is provided.

##### Fix banner not updated if you upload a new one (#142688)

**Problem**

- If you open the modal to change a person's banner and/or profile image and then upload a new banner image, that banner image will not be set as the new banner image for the person. The first time you select it, nothing will happen, but if you select it a second time, the banner is updated.

**Solution**

- Return uploaded banner image details and set them so that they can be used when the image is saved.

##### Remove functionality to copy profile image and avatar for transferring the user to the ruleset (#142521)

**Problem**

- Profile image and avatar should not be copied to the new user with transferring the user to a new ruleset

**Solution**

- Remove functionality to copy profile image and avatar for transferring the user to the ruleset

##### Resolve search and collapse problem on Orgnode tree on transfer person to ruleset modal, and prevent transfer of user with same ID number in destination ruleset (#142696 &amp; #142694)

**Problem**

When searching for organisations, the treeview populates duplicates. Able to transfer a person with Idnumber that already exists on the destination ruleset

**Solution**

Resolve the search and collapse problem on the Orgnode tree on transferring a person to the ruleset modal. Prevent transfer of the user with the same ID number in the destination ruleset

---

#### **Notifications**

##### Cannot send a list of CC or BCC recipients via the external email API (#142336)

**Problem**

- When more than one CC or BCC email address has been configured on V8, V9 do not send any emails

**Solution**

- Correct the concatenation of the list of emails to allow the SMTP service to process them

---

#### **Data Warehouse**

##### Implemented Performance Improvements within PerformanceManagement\_ETL.dtsx (#140865)

**Problem**

- Performance Improvements are required within the SSIS Package PerformanceManagement\_ETL.dtsx due to the growth of system data and the DWH Package

**Solution**

- Removed the DELETE and Truncate Steps and replaced them with Update and Inserts for the below Data Sources: pdmContracts, pdmContractSurveys, pdmContractPeriods, pdmContractPeriodActionPlans, pdmContractPeriodSectionItems, pdmReviewYears, pdmContractPeriodEvaluations, pdmReviewYearPeopleGroupsSetup, pdmContractPeriodSectionItemModerations
- Adjusted steps for Custom fields calculations/insert for pdmContracts and pdmContractPeriods to only do this for active Contracts/ContractPeriods

##### Added new Join between jpAppointments and jpJobProfiles (#142103)

**Problem**

- Join are required between jpAppointments and jpJobProfiles

**Solution**

- Added Join between Appointments and JobProfiles for Report Builder

##### Implemented Performance Improvements within LearningManagementReport\_ETL.dtsx (#140865)

**Problem**

- Performance Improvements are required within the SSIS Package LearningManagementReport\_ETL due to the growth of system data and the DWH Package

**Solution**

- Removed the DELETE and Truncate Steps and replaced them with Update and Inserts for the below Data Sources: - lmAttendances - lmReportCards

---

# Version 9.1.202.3 (Support Release - 14 January 2026)

#### **Performance Management**

##### Cannot edit section weights on the contract (#143437)

**Problem**

- Unable to edit section weights on a contract due to the missing primaryContract parameter not being sent from the frontend.

**Solution**

- Added missing parameter

##### Cannot delete action plans (#143402)

**Problem**

- Unable to delete action plans due to a missing primary contract parameter required for authentication

**Solution**

- Add required parameter

##### Issue when adding/editing action plans (#143402)

**Problem**

- Error received when trying to add or edit action plan items. Bug due to recent additional contract development

**Solution**

- Resolve missing parameter not sent through when adding / editing / copying action plans

---

#### **Job Management**

##### Issue with Job Inherent Requirements incorrectly updating when rating on competency analysis (#143362)

**Problem**

- When rating competency for a user for Job Inherent Requirements, if multiple requirements of the same Master Data type exists all corresponding records for the same type are updated incorrectly.
- Picked up a design problem where for the Job Inherent Requirements, multiple requirements per type can be added; however, for the analysis, the Job Competency Inherent Requirements entity is incorrectly linked to the master data record instead of the job inherent requirement record, resulting in a user can only ever have one requirement per type.
- Front-end and backend allow for working with multiple per type, but cannot distingush on the record level to which Job Inherent Requirement it is linked, and as per the issue on request updating one record leads to all of the same type being updated.

**Solution**

- Remapped the Job Competency Inherent Requirement to the Job Inherent Requirement and updated all references accordingly.

---

# Version 9.1.202.2 (Support Release - 7 January 2026)

#### **System Access**

##### Update email confirmation logic for user import and update to allow a user without an email to log in (#142626)

**Problem**

- A user without an email address cannot log in because the email has not been confirmed

**Solution**

- In ImportUsersCommandHandler, email is now considered confirmed if the user has no email address
- In UpdateUserCommandHandler, email is always marked as confirmed
- These changes ensure consistent handling of email confirmation status during user import and update operations

---

#### **Imports**

##### Remove duplicate self-service settings in validation when importing users (#142626)

**Problem**

- Cannot import users when ESS settings are duplicated in the DB

**Solution**

- This pull request addresses the issue of duplicate entries in the `SelfServiceSetup` table and improves the handling of required fields in the user details validation logic. The most important changes are as follows: 
    - Removes duplicate rows in ESS settings, keeping only the most recently edited entry for each unique combination of `FieldSection`, `FieldId`, and `RulesetId`.
    - Updated the construction of the `requiredFields` dictionary in `UserDetailsValidationService.cs` to ensure unique combinations of `FieldSection` and `FieldId` are included, preventing issues caused by duplicate settings.

---

#### **Performance Management**

##### Resolved KPI not being able to delete (#143253)

**Problem**

- Primary contract bool value not being sent through, which caused an invalid object

**Solution**

- Add a change to pass through the primary contract's bool value

---

#### **People Management**

##### Re-add transfer person JS logic (#143186)

**Problem**

- The transfer button was removed.

**Solution**

- Re-add it

##### Fix materialisation when a people group has not materialised before | Fix regression bug on people termination (#136729)

**Problem**

- When materialising people groups and the list of people groups to materialise is empty, it only materialises for people groups that have already been materialised in the past.

**Solution**

- When the 'forceSync' parameter is true, refresh for ALL people groups on the ruleset (if an empty people group was received).
- Still, only materialise people groups already materialised when 'forceSync' is false.
- **PLUS** Other issue picked up while testing: 
    - Termination broken due to a regression bug.
    - A new field was added to a model used in a query in the job profiler, but the query was not updated, which results in the query breaking, meaning ultimately, people cannot be terminated anymore.
    - Updated the model to make use of auto properties instead of a constructor, which makes it easier for Dapper to map the query result to the model.

---