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