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 & #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 & 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 & #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