- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 04-07-2022 05:20 AM
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
- 17,902 Views

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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);
}
});

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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);
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi,
My requirement is when a previously added comment on a task is changed then that particular comment on RITM should get change/ update
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
(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);
,
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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);

- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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?
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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 notes
And this is what that configuration looks like:
Bonus tips:
- 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).
- 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".
- 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.)
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
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.
Thanks,
Devi sri