How to update SCTASK when additional comment is added to RITM

ShawnaW
Tera Contributor

Hello!

 

We have a requirement where we are wanting all additional comments entered at RITM level to be updated on all associated SCTASKS as an additional comment.  In addition, we are needing this same requirement to go the other way so that when an additional comment is entered at the SCTASK level, it adds/updates the additional comment at the RITM level.  I will need the complete script for how to accomplish this along with any step-by-step instructions as I have never done this before.  I am an admin in our system, but do not have developer/scripting abilities at this time.  Appreciate in advance any insight on how to get this completed!

 

EDIT: I have figured out how to roll comments entered at RITM level to add to SCTASK level, but will need help with the script to update any additional comment entered to SCTASK to update on RITM additional comments.

 

Here is my script for updating additional comments from RITM to SCTASK, I need help with script for SCTASK>RITM additional comments:

(function executeRule(current, previous /*null when async*/) {
    var sctask = new GlideRecord('sc_task');
    sctask.addQuery('request_item', current.sys_id);
    sctask.addQuery('active', 'true');
    sctask.query();
    while(sctask.next()){
        var curAC = current.comments.getJournalEntry(1);
        sctask.comments = curAC;
        sctask.update();
    }
       
})(current, previous);
1 ACCEPTED SOLUTION

Brad Bowman
Kilo Patron
Kilo Patron

If you want to get a little fancier, here's the current iteration of the scripts we have been using to which add the Task/RITM number for reference, prevent recursion, and won't copy duplicates when users repeatedly enter the same comment for whatever reason.

 

The first rule, on the sc_req_item table after Update when Additional comments changes:

(function executeRule(current, previous /*null when async*/) {
	//To Copy the Additional Comments from RITM to SCTASKs
    var compare = '';
	var ritm_comment2 = '';
	var ritm_comment = '';
	var task_comment2 = '';
	var task_comment = '';
	
	ritm_comment = current.comments.getJournalEntry(1);
	
	//Remove timestamp and name from additional comment
	var regex= new RegExp('\n');
	var i = ritm_comment.search(regex);
	if (i>0) {
		ritm_comment2 = ritm_comment.substring(i+1, ritm_comment.length);	
	}
	
	var task_gr = new GlideRecord('sc_task');
	task_gr.addQuery('request_item', current.sys_id);
	task_gr.addQuery('active', 'true');
	task_gr.query();
	while (task_gr.next()) {
		task_comment = task_gr.comments.getJournalEntry(1);
		
		//Remove timestamp and name from additional comment
		var i1 = task_comment.search(regex);
		if(i1 > 0) {
			task_comment2 = task_comment.substring(i1+1, task_comment.length);
			var numberstring = current.number + ' - ';
			var regex2= new RegExp(numberstring);
			var i2 = task_comment2.search(regex2);
			if(i2>=0) {
				task_comment2 = task_comment2.substring(i2+numberstring.length, task_comment2.length);
			}
		} else {
			task_comment2 = 'empty';
		}
		var numberstring2 = task_gr.number + ' - ';
		var regex3= new RegExp(numberstring2);
		var i3 = ritm_comment2.search(regex3);
		if(i3>=0) {
			ritm_comment2 = ritm_comment2.substring(i3+numberstring2.length, ritm_comment2.length);
		}
		
		compare = ritm_comment2.indexOf(task_comment2);
				
		if (compare != 0) {// if no match found
			task_gr.comments = current.number + ' - ' + ritm_comment2.trim();
			task_gr.update();
		}
	}	
})(current, previous);

 

The second rule, on the sc_task table after Update when Additional comments changes:

(function executeRule(current, previous /*null when async*/) {
	//to copy the Additional Comments from SCTASK to RITM
	var compare = '';
	var task_comment2 = '';
	var task_comment = '';
	var ritm_comment2 = '';
	var ritm_comment = '';
	
	task_comment = current.comments.getJournalEntry(1);
		
	//Remove timestamp and name from additional comment
	var regex= new RegExp('\n');
	var i = task_comment.search(regex);
	if (i>0) {
		task_comment2 = task_comment.substring(i+1, task_comment.length);
	}
	
	var ritm_gr = new GlideRecord('sc_req_item');
	ritm_gr.addQuery('sys_id', current.request_item);
	ritm_gr.query();
	if(ritm_gr.next()) {		
		ritm_comment =ritm_gr.comments.getJournalEntry(1);
			
		//Remove timestamp and name from additional comment
		var i1 = ritm_comment.search(regex);
		if(i1 > 0) {
			ritm_comment2 = ritm_comment.substring(i1+1, ritm_comment.length);
			var numberstring = current.number + ' - ';
			var regex2= new RegExp(numberstring);
			var i2 = ritm_comment2.search(regex2);
			if(i2>=0) {
				ritm_comment2 = ritm_comment2.substring(i2+numberstring.length, ritm_comment2.length);
			}
		} else {
			ritm_comment2 = 'empty';
		}
		
		var numberstring2 = ritm_gr.number + ' - ';
		var regex3= new RegExp(numberstring2);
		var i3 = task_comment2.search(regex3);
		if(i3>=0) {
			task_comment2 = task_comment2.substring(i3+numberstring2.length, task_comment2.length);
		}
		
		compare = task_comment2.indexOf(ritm_comment2);
		
		if(compare != 0) {  // If no exact entire match found
			ritm_gr.comments = current.number + ' - ' + task_comment2.trim();
			ritm_gr.update();
		}		
	}
})(current, previous);

 

View solution in original post

8 REPLIES 8

Brad,

Thank you for providing these script examples, this ended up working better than my initial solution.  I was noticing the duplicate entries and it was rather confusing to parse information in the activity feed.  Your above solution works perfect in that it allows us to roll comments up and down respectively and eliminate duplicate entries.  This will be huge for our dept to have implemented!  Many thanks again

You are welcome!  

 

 

Connect with me https://www.linkedin.com/in/brad-bowman-321b1567/

Brad,

We have implemented these business rules and for the most part, things are working as intended, thank you!

One question, how would I add/modify the above script to include flowing attachments as well?  Currently, when an attachment is added, it applies at the RITM level and does not flow like the comments down to the task level.

Consider instead adding a custom related list that will show the attachments of the RITM.  This will prevent the need to copy attachments, which adds to the database size, then there's a discrepancy when an attachment is replaced/deleted at the RITM level...

We have one setup that Applies to table global, Queries from table sys_attachment.  The script looks like this:

 

(function refineQuery(current, parent) {

  var tableName = parent.getTableName();
  var queryString = "table_name=" + tableName + " ^table_sys_id=" + parent.getValue("sys_id");   //default query


  switch (tableName){

       //===== Requested Items =====
      case "sc_req_item":
      queryString = "table_nameINsc_request,sc_req_item,sc_task^table_sys_idIN" + parent.getValue("request") + "," + parent.getValue("sys_id");

      //find the related Catalog Tasks
      queryString += u_getRelatedRecords("sc_task", "request_item", parent.getValue("sys_id"));

      break;

 
      //===== Catalog Tasks =====
      case "sc_task":
      queryString = "table_nameINsc_request,sc_req_item,sc_task^table_sys_idIN" + parent.request_item.request.toString() + "," + parent.getValue("request_item");

      //find the related Catalog Tasks
      queryString += u_getRelatedRecords("sc_task", "request_item", parent.getValue("request_item"));

      break;

  }

  current.addEncodedQuery(queryString);
 

  function u_getRelatedRecords(table, field, sysId){
      var result = "";
      var gr = new GlideRecord(table);
      gr.addQuery(field, sysId);
      gr.query();
      while (gr.next()){
          result += "," + gr.getValue("sys_id");
      }
      return result;
  } 

})(current, parent);

 

So you can add the same Related List to the RITM and SCTASK forms, and it will show any attachments on both records / all SCTASKS in the same RITM...

 

If you really want/need to go the copy route, add the GlideSysAttachment.copy method to a Business Rule

https://www.servicenow.com/docs/bundle/xanadu-api-reference/page/app-store/dev_portal/API_reference/...