From 391fcf6258a39a5d44f42ab5f6b9ae7a511e7994 Mon Sep 17 00:00:00 2001 From: SaiSankar1309 Date: Thu, 2 Oct 2025 15:01:56 +0200 Subject: [PATCH 1/4] Added Validate CI on deployed asset snippet with README and script --- .../Validate CI on deployed asset/README.md | 31 +++++++++++++++++++ .../businessrulescript.js | 24 ++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 Server-Side Components/Business Rules/Validate CI on deployed asset/README.md create mode 100644 Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js diff --git a/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md b/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md new file mode 100644 index 0000000000..cceba9f7d2 --- /dev/null +++ b/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md @@ -0,0 +1,31 @@ +Business Rule: Validate CI on Deployed Assets + +Overview : This Business Rule enforces CMDB integrity by ensuring that any asset marked as "Deployed" must be linked to a valid "Configuration Item (CI)". If no CI is associated, the rule automatically notifies the assigned user's manager to take corrective action. + +This consists of 3 steps: +1. Business rule +2. Event setup +3. Email Notification + +1.Business Rule Configuration +Table: alm_asset +Type: Business Rule +When to run: After Update +Condition : current.install_status == 'Deployed' && !current.ci + +2.Event Setup +Go to System Policy > Events > Event Registry +Click New Name: asset.ci.missing +Table: alm_asset +Description: Triggered when deployed asset has no CI + +3.Email Notification +Go to System Notification > Email > Notifications +Create a new notification: +Name: Missing CI on Deployed Asset +Table: alm_asset +When to send: Event is fired → asset.ci.missing +Recipients: Event.parm1 (manager) +Subject: Asset numberisdeployedwithoutaCI +Message: +Hello{recipient.name}, The asset ${number} assigned to ${assigned_to.name} is marked as Deployed but has no linked Configuration Item. Please review and take appropriate action. Regards, IT Asset Management \ No newline at end of file diff --git a/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js b/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js new file mode 100644 index 0000000000..2041dd7d86 --- /dev/null +++ b/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js @@ -0,0 +1,24 @@ +(function executeRule(current, previous /*null when async*/) { + + + // Only act if asset is deployed and has no CI + if (current.install_status == 'Deployed' && !current.ci) { + // Get the user assigned to the asset + var userGR = new GlideRecord('sys_user'); + if (userGR.get(current.assigned_to.toString())) { + var manager = userGR.manager; + if (manager) { + // Send notification to manager + gs.eventQueue('asset.ci.missing', current, manager.toString(), current.assigned_to.toString()); + gs.info("[Asset-CI Check] Notification sent to manager: " + manager.name); + } else { + gs.info("[Asset-CI Check] Assigned user has no manager."); + } + } else { + gs.info("[Asset-CI Check] Assigned user not found."); + } + } + + + +})(current, previous); From d7181149630dfe1df7369cbb6c5175132266987a Mon Sep 17 00:00:00 2001 From: SaiSankar1309 Date: Fri, 3 Oct 2025 12:47:32 +0200 Subject: [PATCH 2/4] Business Service Lookup Script Include This code snippet fetches the business service related to the CI , when the CI is changed in the change_request form. --- .../Validate CI on deployed asset/README.md | 31 ----------- .../businessrulescript.js | 24 --------- .../README.md | 13 +++++ .../scriptinclude.js | 52 +++++++++++++++++++ 4 files changed, 65 insertions(+), 55 deletions(-) delete mode 100644 Server-Side Components/Business Rules/Validate CI on deployed asset/README.md delete mode 100644 Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js create mode 100644 Server-Side Components/Script Includes/Business Service Fetch When CI Changes/README.md create mode 100644 Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js diff --git a/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md b/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md deleted file mode 100644 index cceba9f7d2..0000000000 --- a/Server-Side Components/Business Rules/Validate CI on deployed asset/README.md +++ /dev/null @@ -1,31 +0,0 @@ -Business Rule: Validate CI on Deployed Assets - -Overview : This Business Rule enforces CMDB integrity by ensuring that any asset marked as "Deployed" must be linked to a valid "Configuration Item (CI)". If no CI is associated, the rule automatically notifies the assigned user's manager to take corrective action. - -This consists of 3 steps: -1. Business rule -2. Event setup -3. Email Notification - -1.Business Rule Configuration -Table: alm_asset -Type: Business Rule -When to run: After Update -Condition : current.install_status == 'Deployed' && !current.ci - -2.Event Setup -Go to System Policy > Events > Event Registry -Click New Name: asset.ci.missing -Table: alm_asset -Description: Triggered when deployed asset has no CI - -3.Email Notification -Go to System Notification > Email > Notifications -Create a new notification: -Name: Missing CI on Deployed Asset -Table: alm_asset -When to send: Event is fired → asset.ci.missing -Recipients: Event.parm1 (manager) -Subject: Asset numberisdeployedwithoutaCI -Message: -Hello{recipient.name}, The asset ${number} assigned to ${assigned_to.name} is marked as Deployed but has no linked Configuration Item. Please review and take appropriate action. Regards, IT Asset Management \ No newline at end of file diff --git a/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js b/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js deleted file mode 100644 index 2041dd7d86..0000000000 --- a/Server-Side Components/Business Rules/Validate CI on deployed asset/businessrulescript.js +++ /dev/null @@ -1,24 +0,0 @@ -(function executeRule(current, previous /*null when async*/) { - - - // Only act if asset is deployed and has no CI - if (current.install_status == 'Deployed' && !current.ci) { - // Get the user assigned to the asset - var userGR = new GlideRecord('sys_user'); - if (userGR.get(current.assigned_to.toString())) { - var manager = userGR.manager; - if (manager) { - // Send notification to manager - gs.eventQueue('asset.ci.missing', current, manager.toString(), current.assigned_to.toString()); - gs.info("[Asset-CI Check] Notification sent to manager: " + manager.name); - } else { - gs.info("[Asset-CI Check] Assigned user has no manager."); - } - } else { - gs.info("[Asset-CI Check] Assigned user not found."); - } - } - - - -})(current, previous); diff --git a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/README.md b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/README.md new file mode 100644 index 0000000000..f23788d6cb --- /dev/null +++ b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/README.md @@ -0,0 +1,13 @@ +Business Service Lookup Fetch When CI Changes + +This code snippet dynamically fetches and filters Business Services based on the selected Configuration Item (CI) in the change request forms. It ensures accurate service mapping, improves user experience, and supports compliance in Change Management and other ITSM workflows. + +Features +-Filters Business Services based on CI relationships +-Supports Script Includes and Client Script +-Compatible with Change Request forms and scoped apps +-Reusable across multiple catalog items and modules + +Use Case +When a user selects a CI (e.g., server, application), the form should only show Business Services linked to that CI. This avoids incorrect selections and enforces service ownership logic. This also checks for orphaned relationships by logging the details in Sytem Logs where a CI has no linked Business Services to avoid empty dropdowns. + diff --git a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js new file mode 100644 index 0000000000..ca017ed9f7 --- /dev/null +++ b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js @@ -0,0 +1,52 @@ +/** Client callable script include */ +var GetServiceDetails = Class.create(); +GetServiceDetails.prototype = Object.extendsObject(AbstractAjaxProcessor, { + type:'GetServiceDetails', + getService: function() { + var ciSysId = this.getParameter('sysparm_ci_sys_id'); + gs.log('GetServiceDetails called for CI: ' + ciSysId); + + var result = { + businessService: '' + }; + + // Find Business Service via cmdb_rel_ci + var rel = new GlideRecord('cmdb_rel_ci'); + rel.addQuery('child', ciSysId); + rel.query(); + if (rel.next()) { + var bs = new GlideRecord('cmdb_ci_service'); + if (bs.get(rel.parent.toString())) { + result.businessServiceId = bs.getUniqueValue(); + result.businessServiceName = bs.getDisplayValue(); + + } else { + gs.log('No Business Service relationship found for CI: ' + ciSysId); + result.businessService = 'No Business Service linked'; + } + + } + + return JSON.stringify(result); + }, + +}); + + +/**onChange Client Script on Change_Request form when CI changes */ + +function onChange(control, oldValue, newValue, isLoading) { + if (isLoading || newValue == '') { + return; + } + + var ga = new GlideAjax('GetServiceDetails'); + ga.addParam('sysparm_name', 'getService'); + ga.addParam('sysparm_ci_sys_id', newValue); + ga.getXML(callScriptInclude); + + function callScriptInclude(response){ + var answer = response.responseXML.documentElement.getAttribute("answer"); + } + +} From 1cc5227df45172ad84c02d752ce004adbbae4b87 Mon Sep 17 00:00:00 2001 From: SaiSankar1309 Date: Fri, 3 Oct 2025 14:03:41 +0200 Subject: [PATCH 3/4] Business Service Lookup Fetch When CI Changes --- .../scriptinclude.js | 77 +++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js index ca017ed9f7..d9c988ee5c 100644 --- a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js +++ b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js @@ -1,52 +1,67 @@ -/** Client callable script include */ -var GetServiceDetails = Class.create(); -GetServiceDetails.prototype = Object.extendsObject(AbstractAjaxProcessor, { - type:'GetServiceDetails', +/** Client callable script include named getServiceDetails*/ + +var getServiceDetails = Class.create(); +getServiceDetails.prototype = Object.extendsObject(AbstractAjaxProcessor, { + + /**creating a script include function named getService */ + getService: function() { + + /**getting the sysid of CI from client side */ var ciSysId = this.getParameter('sysparm_ci_sys_id'); - gs.log('GetServiceDetails called for CI: ' + ciSysId); - - var result = { - businessService: '' - }; - - // Find Business Service via cmdb_rel_ci - var rel = new GlideRecord('cmdb_rel_ci'); - rel.addQuery('child', ciSysId); - rel.query(); - if (rel.next()) { - var bs = new GlideRecord('cmdb_ci_service'); - if (bs.get(rel.parent.toString())) { - result.businessServiceId = bs.getUniqueValue(); - result.businessServiceName = bs.getDisplayValue(); - - } else { - gs.log('No Business Service relationship found for CI: ' + ciSysId); - result.businessService = 'No Business Service linked'; + gs.log('[getServiceDetails] Called for CI: ' + ciSysId); + + if (!ciSysId) { + gs.log('[getServiceDetails] No CI sys_id provided.'); + return ''; } - + + /**Querying the cmdb_rel_ci to find parent relationships for the CI */ + var relGR = new GlideRecord('cmdb_rel_ci'); + relGR.addQuery('child', ciSysId); + relGR.query(); + + while (relGR.next()) { + var parentSysId = relGR.getValue('parent'); + + /**Check if the parent is a Business Service (cmdb_ci_service) */ + var bsGR = new GlideRecord('cmdb_ci_service'); + if (bsGR.get(parentSysId)) { + var businessServiceName = bsGR.getValue('name'); + gs.log('[getServiceDetails] Found Business Service: ' + businessServiceName); + return businessServiceName; // Return the name of the businessService + } } - return JSON.stringify(result); + gs.log('[getServiceDetails] No linked Business Service found.'); + return ''; }, - + + type: 'getServiceDetails' }); /**onChange Client Script on Change_Request form when CI changes */ -function onChange(control, oldValue, newValue, isLoading) { +function onchange(control, oldValue, newValue, isLoading) { if (isLoading || newValue == '') { return; } - var ga = new GlideAjax('GetServiceDetails'); + var ga = new GlideAjax('getServiceDetails'); ga.addParam('sysparm_name', 'getService'); ga.addParam('sysparm_ci_sys_id', newValue); ga.getXML(callScriptInclude); - function callScriptInclude(response){ - var answer = response.responseXML.documentElement.getAttribute("answer"); + function callScriptInclude(response) { + var answer = response.responseXML.documentElement.getAttribute("answer"); + + if (answer) { + // Set the Business Service field with the service name returned + g_form.setValue('business_service', answer); + } else { + // Optional: show a message if no service is found + g_form.showFieldMsg('business_service', 'No linked Business Service found for this CI.', 'info'); } - + } } From 88401f2de5efb4aed80275a419198c2579597aba Mon Sep 17 00:00:00 2001 From: SaiSankar1309 Date: Fri, 3 Oct 2025 18:19:18 +0200 Subject: [PATCH 4/4] created a separate file created a separate file for onChange client script --- .../clientscript.js | 24 +++++++++++++++++++ .../scriptinclude.js | 24 ------------------- 2 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 Server-Side Components/Script Includes/Business Service Fetch When CI Changes/clientscript.js diff --git a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/clientscript.js b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/clientscript.js new file mode 100644 index 0000000000..dd85d8625b --- /dev/null +++ b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/clientscript.js @@ -0,0 +1,24 @@ +/**onChange Client Script on Change_Request form when CI changes */ + +function onchange(control, oldValue, newValue, isLoading) { + if (isLoading || newValue == '') { + return; + } + + var ga = new GlideAjax('getServiceDetails'); + ga.addParam('sysparm_name', 'getService'); + ga.addParam('sysparm_ci_sys_id', newValue); + ga.getXML(callScriptInclude); + + function callScriptInclude(response) { + var answer = response.responseXML.documentElement.getAttribute("answer"); + + if (answer) { + // Set the Business Service field with the service name returned + g_form.setValue('business_service', answer); + } else { + // Optional: show a message if no service is found + g_form.showFieldMsg('business_service', 'No linked Business Service found for this CI.', 'info'); + } + } +} diff --git a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js index d9c988ee5c..f13c2c131b 100644 --- a/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js +++ b/Server-Side Components/Script Includes/Business Service Fetch When CI Changes/scriptinclude.js @@ -41,27 +41,3 @@ getServiceDetails.prototype = Object.extendsObject(AbstractAjaxProcessor, { }); -/**onChange Client Script on Change_Request form when CI changes */ - -function onchange(control, oldValue, newValue, isLoading) { - if (isLoading || newValue == '') { - return; - } - - var ga = new GlideAjax('getServiceDetails'); - ga.addParam('sysparm_name', 'getService'); - ga.addParam('sysparm_ci_sys_id', newValue); - ga.getXML(callScriptInclude); - - function callScriptInclude(response) { - var answer = response.responseXML.documentElement.getAttribute("answer"); - - if (answer) { - // Set the Business Service field with the service name returned - g_form.setValue('business_service', answer); - } else { - // Optional: show a message if no service is found - g_form.showFieldMsg('business_service', 'No linked Business Service found for this CI.', 'info'); - } - } -}