petercawdron
Kilo Guru

This is a handy little script that allows you to prevent a parent record (such as an incident or a problem) from being closed if there are still open child tasks.

First, add a client callable script includes with the name childTasks

var childTasks = Class.create();
childTasks.prototype = Object.extendsObject(AbstractAjaxProcessor, {

	activeTasks:function() { 

		var result = [];		
		var whichTable = this.getParameter('sysparm_table');
		var whichField = this.getParameter('sysparm_field');
		var whichValue = this.getParameter('sysparm_value');
		
		var gr = new GlideRecord(whichTable);
		gr.addEncodedQuery(whichField+'.sys_id='+whichValue);
		gr.query();
		
		while(gr.next()){
			if(gr.active){result.push(gr.number.toString());}
		}
		return result.toString(); 
	},

	type: 'childTasks'
});

Then update the Resolve button's UI Action script to call this server side code via GlideAjax

For Incident, this is...

function resolveIncident(){

	var ga = new GlideAjax('childTasks');
	ga.addParam('sysparm_name', 'activeTasks');
	ga.addParam('sysparm_table', 'incident_task');
	ga.addParam('sysparm_field', 'incident');
	ga.addParam('sysparm_value', g_form.getUniqueValue());
	ga.getXMLAnswer(activeTasks);

	function activeTasks(response) {

		var outstandingTasks = response;
 
		if(outstandingTasks!=''){
			g_form.addErrorMessage('You must close the following related tasks before you can resolve this record: ' + outstandingTasks.split(',').join(', '));
		}else{
			//There are no active child tasks so proceed
			//Set the 'Incident state' and 'State' values to 'Resolved', and display mandatory fields
			g_form.setValue('incident_state', 6);
			g_form.setValue('state', 6);
			g_form.setValue('resolved_by', g_user.userID);

			gsftSubmit(null, g_form.getFormElement(), 'resolve_incident'); //MUST call the 'Action name' set in this UI Action
		}
	}
}

//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
	serverResolve();

function serverResolve(){
	current.incident_state = IncidentState.RESOLVED;
	current.state = IncidentState.RESOLVED;
	current.resolved_by = gs.getUserID();
	current.update();
}

Note, only the first 15 lines (up until the }else{ are actually new. Everything else is the OOB code from ServiceNow.

This code evaluates whether there are any open tasks before proceeding with the resolved actions.

For problem this is...

function onResolve() {

	var ga = new GlideAjax('childTasks');
	ga.addParam('sysparm_name', 'activeTasks');
	ga.addParam('sysparm_table', 'problem_task');
	ga.addParam('sysparm_field', 'problem');
	ga.addParam('sysparm_value', g_form.getUniqueValue());
	ga.getXMLAnswer(activeTasks);

	function activeTasks(response) {

		var outstandingTasks = response;

		if(outstandingTasks!=''){
			g_form.addErrorMessage('You must close the following related tasks before you can resolve this record: ' + outstandingTasks.split(',').join(', '));
		}else{
			if (!g_form.hasField("state") || !g_form.hasField("resolution_code")) {
				getMessage('Cannot resolve the Problem as atleast one of the following fields are not visible: \'State\' \'Resolution code\'', function(msg) {
					g_form.addErrorMessage(msg);
				});
				return false;
			}
			g_form.setValue("state", g_scratchpad.STATE.RESOLVED);
			g_form.setValue("resolution_code", g_scratchpad.RESOLUTION_CODES.FIX_APPLIED);
			g_form.save();
		}
	}
}

Have fun

Comments
RWHeals
Tera Contributor

Does anyone know how to get this to apply to the Service Operation Workspace "resolve" ui action as well?

Ansh Mahajan
Tera Contributor

Hi @RWHeals 

 

Just add the same code into the workspace section of the custom "Resolve" UI action you created for the instance side.

 

Regards

Ansh Mahajan

Ansh Mahajan
Tera Contributor

Hi @petercawdron 

 

Can we have the same thing for on saving the record by manually changing the state to resolve and then saving the record? 

 

Please help me with the code which will work both on workspace and instance aswell.

 

Regards 

Ansh Mahajan

Sam Motley
Giga Guru

i have this working on a custom table but it's pulling all tasks instead of the one attached to the record, has anyone else had this? 

cheers

Ansh Mahajan
Tera Contributor

Hi @Sam Motley 

 

Please check your glide record query. There should be a filter available which will pull only related child records of that parent record. 

 

If the filter is there then check the field value which is tagging the child record to it's parent record. 

 

For example:- when we create a problem record from incident record the first reported by field is automatically populated with the respective incident number which will create a relationship between parent incident and child problem record. Same thing should be there in your custom table too.

 

Mark this as helpful if this answers your query.

 

 

Version history
Last update:
‎09-12-2019 09:53 PM
Updated by: