Singlescore (and other visualization) aggregations with COUNT and COUNT DISTINCT should not show Decimal precisionDescriptionSingle score visualizations with COUNT and COUNT DISTINCT have unexpected decimal precision, post upgradeSteps to Reproduce Create a single score report with aggregation COUNT or COUNT DISTINCT set formatting value to have Decimal precision 2 (see screenshot). Observe that report does not show decimal part. WorkaroundRun glide script named fix_countVizDecimalPrecision.txt attached in the PRB using background script. This script will fix all migrated visualizations decimal precision value. /** * Script to find and update pie, bar, area, single score, pivot visualizations with COUNT aggregate function * in the par_coreui_migration_bridge_component table and par_dashboard_widget records * referenced by migrated dashboards in par_coreui_migration_bridge_dashboard table * Updates decimalPrecision from any value greater than 0 to 0 * Relates to PRB1939279 * Supports multi-domain ServiceNow instances */ (function() { const COMPONENT_ID_RICH_TEXT = '2d56f06d55f46bbd4e79b5e624beb940'; const COMPONENT_ID_SINGLE_SCORE = 'd24d53f60350de7a652caf3188a46ed2'; const COMPONENT_ID_PIE = '96abe7e38d8790718022c5630a92176c'; const COMPONENT_ID_DONUT = 'a2b0596cec6b9d49dd1ff9bf76b5084b'; const COMPONENT_ID_SEMI_DONUT = '3809c6583b8dd540a0bf735ed493bae2'; const COMPONENT_ID_FILTER = '226449101138d0dff1abe0e1566c8b2a' const COMPONENT_ID_AREA = 'aba8630dc2ccc9b3c1774af1b6820696'; const COMPONENT_ID_COLUMN = '2bd5dc19a7ad083941b7c992a966dd78'; const COMPONENT_ID_LINE = '18ac962264404bcc0039359d184b15f3'; const COMPONENT_ID_SPLINE = '0f1e76928c4814e1430774fb864003f0'; const COMPONENT_ID_STEP_LINE = '7fa5f7264941fabfb1542985da30e0b8'; const COMPONENT_ID_TABLE = '7ff373544303121093711347efb8f23c'; const COMPONENT_ID_HORIZONTAL_BAR = '85855283b7e03010097cb81cde11a91d'; const COMPONENT_ID_VERTICAL_BAR = '23051643b7e03010097cb81cde11a910'; const COMPONENT_ID_PARETO = '53e0a2b49e3ff92ba54ea7ea6f0d0583'; const COMPONENT_ID_HEATMAP = 'd1f6c60ce95607ea1ef236430d5fdec9'; const COMPONENT_ID_LEGACY_WIDGET = '0805a7bf91a93efbdf0a975b38b01051'; const COMPONENT_ID_MAP = '9c8c44bd78fe5918950e0db8e286211d'; const COMPONENT_ID_PIVOT = '06f6aacbd1818110f877d87436272684'; const COMPONENT_ID_BOX = 'c5d01636ff2602109bd2ffffffffff0a'; const COMPONENT_ID_GAUGE = '037bd8ea3013833fd049186779528b70'; const COMPONENT_ID_DIAL = '63f050cf050137731a828878839e0b33'; const COMPONENT_ID_BUBBLE = '50dbc52a13c8b4691f7c60e0246bf28c'; const COMPONENT_ID_CALENDAR = '259e0221ff18a75c5f5f0fb28fa5d32f'; const COMPONENT_ID_SCORECARD = '9d31ba4d773ce32ef350d4555b673f6e'; const vizComponentIds = [COMPONENT_ID_SINGLE_SCORE, COMPONENT_ID_PIE, COMPONENT_ID_DONUT, COMPONENT_ID_SEMI_DONUT, COMPONENT_ID_DIAL, COMPONENT_ID_GAUGE, COMPONENT_ID_AREA, COMPONENT_ID_COLUMN, COMPONENT_ID_LINE, COMPONENT_ID_SPLINE, COMPONENT_ID_STEP_LINE, COMPONENT_ID_HORIZONTAL_BAR, COMPONENT_ID_VERTICAL_BAR, COMPONENT_ID_PIVOT ]; var countViz = []; var isDomainSeparated = new SNC.PADomainUtils().isDomainSeparated(); gs.log('Starting to search for visualizations with COUNT aggregate function', 'fix_countVizDecimalPrecision'); // Part 1: Process migrated components processMigratedComponents(countViz); // Part 2: Process migrated dashboards and their widgets processMigratedDashboards(countViz); /** * Process migrated components from par_coreui_migration_bridge_component table * @param {Array} countViz - Array to store results */ function processMigratedComponents(countViz) { gs.log('Processing migrated components', 'fix_countVizDecimalPrecision'); // Query the par_coreui_migration_bridge_component table var bridgeComponentGr = new GlideRecord('par_coreui_migration_bridge_component'); bridgeComponentGr.addQuery('is_last', true); bridgeComponentGr.addQuery('type', 'Report'); if (isDomainSeparated) bridgeComponentGr.queryNoDomain(); else bridgeComponentGr.query(); while (bridgeComponentGr.next()) { // Get the component reference var componentRef = bridgeComponentGr.getValue('component'); if (!componentRef) { continue; } // Query the referenced component to check if it's a visualization var reportGr = new GlideRecord('par_visualization'); reportGr.get(componentRef); if (!reportGr.isValidRecord()) { continue; } // Check if visualization type is // pie, bar, area, single score, pivot var reportTypes = ['Pie', 'Dial', 'Gauge', 'Donut', 'Semi donut', 'Bar', 'Vertical bar', 'Horizontal bar', 'Area', 'Line', 'Spline', 'Column', 'Step line', 'Single score', 'Pivot', 'Pivot Table', 'pivot_v2']; if (reportTypes.includes(reportGr.getValue('type'))) { // Get properties and check for aggregateFunction:COUNT var properties = reportGr.getValue('properties'); if (properties && properties.indexOf('"aggregateFunction":"COUNT') > -1) { processPropertiesForCountViz(countViz, { source_type: 'bridge_component', source_sys_id: bridgeComponentGr.getUniqueValue(), source_name: bridgeComponentGr.getValue('name'), target_table: 'par_visualization', target_sys_id: componentRef, target_name: reportGr.getValue('name'), properties: properties }); } } } } /** * Process migrated dashboards and their widgets * @param {Array} countViz - Array to store results */ function processMigratedDashboards(countViz) { gs.log('Processing migrated dashboards', 'fix_countVizDecimalPrecision'); // Query the par_coreui_migration_bridge_dashboard table var bridgeDashboardGr = new GlideRecord('par_coreui_migration_bridge_dashboard'); bridgeDashboardGr.addQuery('is_last', true); if (isDomainSeparated) bridgeDashboardGr.queryNoDomain(); else bridgeDashboardGr.query(); while (bridgeDashboardGr.next()) { // Get the dashboard reference var dashboardRef = bridgeDashboardGr.getValue('par_dashboard'); if (!dashboardRef) { continue; } // Find par_dashboard_canvas records for this dashboard var canvasGr = new GlideRecord('par_dashboard_canvas'); canvasGr.addQuery('dashboard', dashboardRef); if (isDomainSeparated) canvasGr.queryNoDomain(); else canvasGr.query(); while (canvasGr.next()) { var canvasSysId = canvasGr.getUniqueValue(); // Find par_dashboard_widget records that reference this canvas var widgetGr = new GlideRecord('par_dashboard_widget'); widgetGr.addQuery('canvas', canvasSysId); widgetGr.addQuery('component', 'IN',vizComponentIds); if (isDomainSeparated) widgetGr.queryNoDomain(); else widgetGr.query(); while (widgetGr.next()) { // Get component_props and check for aggregateFunction:COUNT var componentProps = widgetGr.getValue('component_props'); if (componentProps && componentProps.indexOf('"aggregateFunction":"COUNT') > -1) { processPropertiesForCountViz(countViz, { source_type: 'dashboard_widget', source_sys_id: bridgeDashboardGr.getUniqueValue(), source_name: bridgeDashboardGr.getValue('name'), target_table: 'par_dashboard_widget', target_sys_id: widgetGr.getUniqueValue(), target_name: widgetGr.getValue('name') || 'Widget ' + widgetGr.getUniqueValue(), properties: componentProps }); } } } } } /** * Process properties for COUNT visualization and check if decimalPrecision needs update * @param {Array} countViz - Array to store results * @param {Object} data - Data object with record information */ function processPropertiesForCountViz(countViz, data) { // Check if properties contain decimalPrecision > 0 var needsUpdate = false; var updatedProperties = data.properties; // Use regex to find decimalPrecision with any value greater than 0 var decimalPrecisionRegex = /"decimalPrecision":(\d+)/g; var match; while ((match = decimalPrecisionRegex.exec(data.properties)) !== null) { var precisionValue = parseInt(match[1], 10); if (precisionValue > 0) { gs.log('Found decimalPrecision: ' + precisionValue + ' (needs update) for ' + data.target_table + ' ' + data.target_name, 'fix_countVizDecimalPrecision'); needsUpdate = true; // Replace the found precision with 0 updatedProperties = updatedProperties.replace( '"decimalPrecision":' + precisionValue, '"decimalPrecision":0' ); } } // Found a visualization with COUNT aggregate function countViz.push({ source_type: data.source_type, source_sys_id: data.source_sys_id, source_name: data.source_name, target_table: data.target_table, target_sys_id: data.target_sys_id, target_name: data.target_name, properties: data.properties, updated_properties: needsUpdate ? updatedProperties : null, needs_update: needsUpdate }); } gs.log('Found ' + countViz.length + ' visualizations/widgets with COUNT aggregate function', 'fix_countVizDecimalPrecision'); // Output the results and update records if needed var updatedCount = 0; for (var i = 0; i < countViz.length; i++) { var record = countViz[i]; if (record.needs_update) { gs.print('Decimal precision needs update'); // Update the record var updateGr = new GlideRecord(record.target_table); if (updateGr.get(record.target_sys_id)) { // Set the appropriate field based on the target table var fieldName = record.target_table === 'par_visualization' ? 'properties' : 'component_props'; updateGr.setValue(fieldName, record.updated_properties); updateGr.update(); updatedCount++; gs.print('✓ Updated decimal precision to 0'); } else { gs.print('✗ Failed to update record'); } } } gs.print('Summary: Updated ' + updatedCount + ' out of ' + countViz.length + ' visualizations/widgets'); return { total: countViz.length, updated: updatedCount, records: countViz }; })(); Related Problem: PRB1939279