Dinesh Kumar11
Kilo Sage
Kilo Sage

Step 1 ) Create a business rule as below. (for Copying additional comments to SC Task from RITM)

Table : sc_req_item 

When : After , update 

Filter condition : Additional comments  : changes 

Advanced Script : 

(function executeRule(current, previous /*null when async*/) {

updateTasks();

function updateTasks() {
var compare,task_comment2,task_comment,ritm_comment2,ritm_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 ritm_gr = new GlideRecord('sc_task');
ritm_gr.addQuery('request_item', current.sys_id);
ritm_gr.query();

if(ritm_gr.next())
{
task_comment =ritm_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);
}
compare = ritm_comment2.indexOf(task_comment2);

if(compare == -1) // If No match found
{
ritm_gr.comments = ritm_comment2.trim();
ritm_gr.update();
}
}
}
})(current, previous);

Step 2 ) Create a business rule as below. (for Copying additional comments From SC Task to RITM)

Table : sc_task

When : After , update 

Filter condition : Additional comments  : changes 

Advanced Script : 

(function executeRule(current, previous /*null when async*/) {

// Add your code here

var compare,task_comment2,task_comment,ritm_comment2,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.parent);
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);
}
compare = task_comment2.indexOf(ritm_comment2);

if(compare == -1) // If No match found
{
ritm_gr.comments = task_comment2.trim();
ritm_gr.update();
}
}

})(current, previous);

 

Hope you will find it as helpful. Don’t forget to Mark it Helpful and Bookmark article so you can easily find on your profile.

Thank you,
Dinesh Kumar Raghu,
Capgemini India Pvt Ltd.

GmailID : dineshkumar.raghu9426@gmail.com

Comments
dwilborn
Tera Contributor

Dinesh,

Thank you very much for this, it is very helpful.

In testing the functionality of your code I've found that if multiple tasks exist, only 1 task is updated.  I've tested from the agent view of the platform, employee self service, service portal, and employee center.  I'm a JavaScript novice at best on a good day (admin turning dev) and was hoping you might be able to provide some insight and potential solution to this requirement.

Daniel

wmcgrath
Tera Expert

Dinesh,

The only improvement I would argue is that you could put this in a sole business rule targeted at the task table.

 

Business Rule Name: Sync RITM/SCTASK comments

Table: task

When: before

Order: 1001

On: Update only

Filter: When Additional comments changes AND the task type is 'Requested Item' or the task type is 'Catalog Task'.

(function executeRule(current, previous /*null when async*/) {
    try{
		
		var task_type = current.getRecordClassName();
		var email = {};

		/**
		 * Copy the comments from the SCTASK into RITM and vice-versa.
		 * WM, SER-426
		 */

		if (task_type == 'sc_task') {
			// Item updated is the catalog task (SCTASK)
			
			var sc_req_item = new GlideRecord('sc_req_item');
			if(sc_req_item.get(current.request_item)){
				/**
				 * Note that we don't run setUseEngines here. This is because we don't want
				 * to prevent e-mail notifications from going out, and in this case, there
				 * is a many-to-one relationship between an sc_task and its associated
				 * sc_req_item (sc_task.request_item)
				 */
				sc_req_item.comments = current.comments;
				sc_req_item.update();

				email.sys_id = sc_req_item.u_requested_for.sys_id;
				email.name = sc_req_item.u_requested_for.getDisplayValue();
				gs.eventQueue("custom.catalog.ritm.commented", sc_req_item, email.sys_id, email.name);
			}
		} else if (task_type == 'sc_req_item') {
			// Record being updated is an RITM.
			var sc_task = new GlideRecord('sc_task');
			sc_task.addQuery('request_item', current.sys_id);
			sc_task.addQuery('active','true');
			sc_task.query();
			while(sc_task.next()){
				/**
				 * We run setUseEngines here because:
				 * 1. The user has updated the sc_req_item, not the sc_task
				 * 2. Therefore the comment comes from the sc_req_item by virtue of
				 *    it being the key record being updated.
				 * 3. We are about to update the sc_task. Given the sc_task updated would normally 
				 *    trigger this very business rule, we'd be in a pick. We _don't_ want that.
				 *    Given we have no notifications associated with comments triggered
				 *    from sc_task, there is no risk we break something here by preventing workflow
				 *    engines from continuing.
				 */
				sc_task.comments = current.comments;
				sc_task.setUseEngines(false);
				sc_task.update();
				sc_task.setUseEngines(true);


				if(sc_task.assigned_to){
					email.sys_id = sc_task.getValue('assigned_to');
					email.name = sc_task.assigned_to.getDisplayValue();
				} else {
					email.sys_id = sc_task.getValue('assignment_group');
					email.name = sc_task.assignment_group.getDisplayValue();
				}
				gs.eventQueue("custom.catalog.ritm.commented", sc_task, email.sys_id, email.name);
			}
		} 
			
		
    } catch (error) {
        var log = 'Sync RITM/SCTASK comments';
        gs.log('Error: ' + error, log);
    }
});

 

sailesh1
Tera Contributor

Hi
This solution works if there is a single task for RITM.

Were you able to figure out if there are multiple tasks on RITM?

 

Daniel Wilborn
Tera Contributor

Found the below a while back... wish I could credit the author but I don't recall where this was at.  I've leveraged this to sync up the work notes as well with a little bit of modification.

Testing shows that the notification engine recognizes these updates as well, so emails get generated when this method is used.  Also made sure no loops got created by way of the email update to the journal fields.

Have to admit... I'm not 100% sure what all is going on in the script, but it's working, has the desired result, and no unintended side effects I can find.

//Business Rule on sc_task table
//when : Before
//Order : 10,0001
//update : true
//Filter condition : additional comments changes

(function executeRule(current, previous /*null when async*/) {

	if (global.z_comments_rollup_history && 
		global.z_comments_rollup_history.indexOf(current.request_item + '') > -1)
		return;

	if (!global.z_comments_rollup_history)
		global.z_comments_rollup_history = [];

	global.z_comments_rollup_history.push(current.getUniqueValue() + '');

	var comment = current.comments.getJournalEntry(1) + '';

	comment = comment.split('\n');
	comment.shift();
	comment = comment.join('\n');

	var ritm = current.request_item.getRefRecord();
	ritm.comments = comment;
	ritm.update();

})(current, previous);

// Business Rule on sc_req_item
// when : before
// update : true
// Filter Condition : when additional comments change
// order : 100

(function executeRule(current, previous /*null when async*/) {

	if (global.z_comments_rollup_history && 
		global.z_comments_rollup_history.indexOf(current.getUniqueValue() + '') > -1)
		return;
	
	if (!global.z_comments_rollup_history)
		global.z_comments_rollup_history = [];
	
	global.z_comments_rollup_history.push(current.getUniqueValue() + '');

	var sctask = new GlideRecord('sc_task'),
		comment = current.comments.getJournalEntry(1) + '';
	
	comment = comment.split('\n');
	comment.shift();
	comment = comment.join('\n');
	
	sctask.addQuery('request_item', current.sys_id);
	sctask.addQuery('active', 'true');
	sctask.query();
	while (sctask.next()) {
		if (global.z_comments_rollup_history.indexOf(sctask.getUniqueValue() + '') > -1)
			continue;
		sctask.comments = comment;
		sctask.update();
	}
	
})(current, previous);

 

AishwaryaS
Tera Contributor

Hi, 

My requirement is when a previously added comment on a task is changed then that particular comment on RITM should get change/ update

Sudeep1
Tera Explorer
Spoiler
Try this, if RITM has multiple taks.

 

(function executeRule(current, previous /*null when async*/) {

updateTasks();

function updateTasks() {
var compare,task_comment2,task_comment,ritm_comment2,ritm_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 ritm_gr = new GlideRecord('sc_task');
ritm_gr.addQuery('request_item', current.sys_id);
ritm_gr.query();

while(ritm_gr.next())
{
ritm_gr.work_notes =ritm_comment2
ritm_gr.update();

}
}
})(current, previous);

 

Aaron Struphar
Kilo Guru

Hello Dinesh, thank you for sharing. These business rules work very well!

 

Thanks Sudeep, this works well. However, this is posting the comments as work notes, rather than additional comments on the tasks. In order to have them be additional comments on the task level, just change line 21 from 'ritm_gr.work_notes' to 'ritm_gr.comments'. This worked for me.

(function executeRule(current, previous /*null when async*/ ) {

    updateTasks();

    function updateTasks() {
        var compare, task_comment2, task_comment, ritm_comment2, ritm_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 ritm_gr = new GlideRecord('sc_task');
        ritm_gr.addQuery('request_item', current.sys_id);
        ritm_gr.query();

        while (ritm_gr.next()) {
            ritm_gr.comments = ritm_comment2;
            ritm_gr.update();

        }
    }
})(current, previous);

 

Narsing1
Mega Sage

Hey All,

I came up with one solution which will address all the scenarios i.e. worknotes & comments, ritm/change request/problem etc.,

Go through with this Article and download the update set from here

Please feel free to provide your feedback to enhance this

 

Thanks,

Narsing

AugustoObramax
Tera Contributor

Hello @Sudeep1!

 

I insert this script for which table? RITM ou SCTASK?

 

Thanks!

kmannem
Tera Contributor

Is there a way for us to show the history of additional comments and worknotes on the SC task which is created at a later point of time?

Will West1
Tera Contributor

Hi folks,


I just wanted to point out that Business Rules is an option... but there is a second way that has the advantage of no code needed, no duplication of data, and instantly reflects all the RITM's Comments regardless of when the Catalog Task is created. It is also the OOB configuration for the "Default" View of a Catalog Task if the Procurement "com.snc.procurement" Plugin is installed so this should have ServiceNow's support. (You can verify for yourselves by by installing the Plugin in a fresh PDI.)


It does have a UI disadvantage as it has no "Post" button under the Comments box for your fulfillers (so they will have to press either "Save" or "Update") and it isn't formatted as Activities normally formats -- but it does display!

 

Simply modify the "Catalog Task [sc_task]" form, dot-walk into the Request Item, and include the "Request item.Additional comments" and "Request item.Comments and Work notes" fields. That's it!

 

Users can't see Comments on Tasks so there is no reason to store Comments on Catalog Tasks. And, normally, Work notes are Catalog Task specific so there is no reason to busy up the Request Item with them. But showing and making the RITM's Comments easy to update from the Catalog Task makes it easy for your fulfillers to keep the end user updated.

This is how the Catalog Task form appears OOB with the Procurement Plugin installed. The yellow box is actually showing the RITM's Comments -- not the Catalog Tasks. And the blue box is showing the Catalog Tasks' Work notes.

Yellow = RITM' Comments / Blue =  Catalog Task's Work notesYellow = RITM' Comments / Blue = Catalog Task's Work notes

And this is what that configuration looks like:
OOB Catalog Task with Procurment Plugin installed configuration.png

Bonus tips:

  1. Don't forget to update your Workspace's Views as well! It won't follow the Workspace UI (since it will be in the form section on the left rather than the activity section in the middle).

  2. If you want the Label to read "Additional comments (Customer visible)", don't forget to either modify (or make a new) "Modify Comments Label" Client Script (/sys_script_client.do?sys_id=8e3c775a0a0a3c74010bedda85570a82) as the OOB one is will try to update the field named "comments" but, on the Catalog Task, our field is now called "request_item.comments".

  3. Want your Catalog Task assignees to to be notified when a Comment is made in the Request Item? That secretly exists! There is a "sc_req_item comment events" Business Rule (/sys_script.do?sys_id=9790a7400a00070450a5ccf2d15a89c3) that loads the "Assigned to"(s) into Param 1 and "Assignment group"(s) into Parm 2 and triggers the "sc_req_item.commented.itil" Event. That Event triggers the "Request Item commented (all assignees)" Notification (/sysevent_email_action.do?sys_id=1e2b8ea10a0a3c7401d488fb70f99cda) which is active but does not have Param 1 or 2 checked. So check whichever you want (use the Notification's "Advanced" View if you do not see them) and it'll start sending email to your Catalog Task assignees when a Comment is made in the Request Item. (Although I personally would customize that Business Rule to not include a Group if it has been assigned to a User to make sure fulfillers don't get swamped by email.)
DeviSriB
Tera Contributor

Hi @Dinesh Kumar11 

I followed your steps, and I have created business rules. So, when I'm doing the manual steps to close the SC task. I got multiple comments of next SC tasks in the RITM when SC task has been closed. I attached the screenshot for your understanding.

DeviSriB_0-1750241415120.png

 

Thanks,

Devi sri

 

Version history
Last update:
‎04-07-2022 05:20 AM
Updated by: