Maik Skoddow
Tera Patron
Tera Patron
find_real_file.png
Part 1Part 2Part 3
Part 4

Bidirectional comment sync

According to ServiceNow's licensing model, a user who only has the "approval_user" role is also only allowed to work on approval records. In addition to approving or rejecting, such a user may only enter comments on the approval records. However, comments can also arise on the side of the task record, for example, in response to a comment from one of the approval records. 

In company-internal approval processes over several stages, each with several approvers a typical constellation can look schematically as follows:

find_real_file.png

 

Two problems arise with this scenario in a OOTB instance:

  1. There is no comment synchronization between the Task Record and all the Approval Records.
  2. There is no overview of all comments from all approval records at the end of the approval process. However, in order to make the reasons for an approval or rejection on the task record transparent afterwards, such an overview is absolutely necessary. Ideally, this overview is available directly at the task record.

 

The target picture should therefore look like this:

find_real_file.png

 

The solution approach is to implement a comment synchronization between the Task Record and all Approval Records. For this purpose, the comments on the source records are copied to the target records.

As a technical implementation, two business rules were implemented: one for the table task and one for the table sysapproval_approver. Copying comments from one table to another is simple. However, the challenge was to prevent infinite loops.

 

Business Rule on task Table

Configuration

find_real_file.png

 

Script

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

  var grApproval        = new GlideRecord("sysapproval_approver");
  var strCurrentComment = current.comments.getJournalEntry(1).trim();
  
  //prevent comment replication between approval records
  if (strCurrentComment.indexOf('Comment copied from approval record') == -1) {
    grApproval.addQuery("sysapproval", current.sys_id);
    grApproval.addQuery("state", "requested");
    grApproval.query();

    while (grApproval.next()) {
      var strApprovalComment = grApproval.comments.getJournalEntry(1);

      //prevent endless loops
      if (!strApprovalComment || strCurrentComment.indexOf(strApprovalComment) == -1) {
        grApproval.comments = 'Comment copied from record to approve:\n\n' + strCurrentComment;

        grApproval.update();
      }
    }
  }
  
})(current, previous);

 

Business Rule on sysapprovcal_approver Table

Configuration

find_real_file.png

 

Script

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

  var grTask            = new GlideRecord("task");
  var strCurrentComment = current.comments.getJournalEntry(1).trim();

  //prevent back replication from all approval records
  if (strCurrentComment.indexOf('Comment copied from record to approve') == -1) {
    if (grTask.get(current.sysapproval)) {
      var strTaskComment = grTask.comments.getJournalEntry(1);

      //prevent endless loops
      if(!strTaskComment || strCurrentComment.indexOf(strTaskComment) == -1) {
        grTask.comments = 'Comment copied from approval record:\n\n' + strCurrentComment;

        grTask.update();
      }
    }
  }

})(current, previous);

 

Feel free to customize the code according to your needs. And please let me know in the comments if you have any suggestions for improvement.

Comments
Jake Adams
Tera Contributor

Worked like a charm

Rajendher1
Tera Expert

Thanks Maik, 

 

I am looking for a solution which should sync comments between sc_req_item and sc_task without getting into loop.

RITM Additional Comments to SCTASK worknotes (1) 

SCTASK worknotes to RITM worknotes & Additional Comments (2) 

gunashalini
Tera Contributor

Hi @Maik Skoddow @Jake Adams @Rajendher1 
I have implemented the same concept for RITM to Approval record and when I post a comment in RITM record it is throwing duplicates

 

gunashalini_0-1705066708885.png

 

How can I solve this issue?

 

This is the code I have used

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

  var grApproval        = new GlideRecord("sysapproval_approver");
  var strCurrentComment = current.comments.getJournalEntry(1).trim();
  
  //prevent comment replication between approval records
  if (strCurrentComment.indexOf('Comment from Approver: ') == -1) {
    grApproval.addQuery("sysapproval", current.sys_id);
    grApproval.addQuery("state", "requested");
    grApproval.query();

    while (grApproval.next()) {
      var strApprovalComment = grApproval.comments.getJournalEntry(1);

      //prevent endless loops
      if (!strApprovalComment || strCurrentComment.indexOf(strApprovalComment) == -1) {
        grApproval.comments = 'Comment from RITM: ' + strCurrentComment;

        grApproval.update();
      }
    }
  }
  
})(current, previous);



Version history
Last update:
‎08-26-2021 10:00 PM
Updated by: