Attachment added from RITM to SCTASK and SCTASK to RITM Vice Versa Incase of deletion

Sirri
Tera Guru

Hi All,

 

I have requirement like in the below scenarios:

1) If any attachment is added to RITM I need to copy that attachment to SC task.

In this case i need to update Additional comments in RITM attachment added with file name and in sctask I need to update work notes Attachment "file name" copied from RITMNumber.

2)If any attachment is added to sctask I need to copy that attachment to RITM.

In this case I need to update work notes in sctask like this a Attachment file name added and in RITM comments like Attachment file name copied from sctasknumber.

3)If Any attachment is deleted in RITM and same attachment need to be deleted from sctask.

In this case I need to update comments in RITM Attachment file names is removed and sctask Attachment file name is removed from RITM and same in sctask like this.

4)If Any attachment is deleted in Sctask and same attachment need to be deleted from RITM.

In this case work notes in sc task Needs to update to attachment file name removed and RITM comments Attachment file name has been removed from sctask and RITM.

 

For all these requirements I have written one business rules as per the below:

Table: sys_attachment

When to run: After - Insert & Delete

 

In Advance condition Iike below:

current.table_name=="sc_req_item" || current.table_name=="sc_task"

 

Script is like below:

(function executeRule(current, previous /*null when async*/ ) {
 
 if (current.table_name == "sc_req_item" || current.table_name == "sc_task") {
        var action = (current.operation() == "insert") ? "added to" : "removed from";
        var fileName = current.file_name; // Get the attachment file name

        function copyAttachment(sourceTable, sourceSysId, targetTable, targetSysId) {
            var attachment = new GlideSysAttachment();
            var sourceAttachment = new GlideRecord('sys_attachment');
            sourceAttachment.addQuery('table_name', sourceTable);
            sourceAttachment.addQuery('table_sys_id', sourceSysId);
            sourceAttachment.query();
            while (sourceAttachment.next()) {
                var inputStream = attachment.getContentStream(sourceAttachment.sys_id);
                attachment.write(targetTable, targetSysId, sourceAttachment.file_name, sourceAttachment.content_type, inputStream);
            }
        }

        function removeAttachment(targetTable, targetSysId, fileName) {
            var attachment = new GlideSysAttachment();
            var targetAttachment = new GlideRecord('sys_attachment');
            targetAttachment.addQuery('table_name', targetTable);
            targetAttachment.addQuery('table_sys_id', targetSysId);
            targetAttachment.query();
            while (targetAttachment.next()) {
                if (targetAttachment.file_name == fileName) {
                    attachment.deleteAttachment(targetAttachment.sys_id);
                }
            }
        }

        var recordSysId = current.table_sys_id;
        var recordRec = new GlideRecord(current.table_name);
        if (recordRec.get(recordSysId)) {
            var recordNumber = recordRec.number;
            var workNoteMessage = "Attachment: '" + fileName + "' has been " + action + " " + current.table_name.toUpperCase() + ": " + recordNumber;
            recordRec.comments = workNoteMessage;
            recordRec.update();

            if (current.table_name == "sc_req_item") {
                // Handle SC Task records
                var taskRec = new GlideRecord("sc_task");
                taskRec.addQuery("request_item", recordSysId);
                taskRec.query();
                while (taskRec.next()) {
                    if (current.operation() == "insert") {
                        copyAttachment("sc_req_item", recordSysId, "sc_task", taskRec.sys_id);
                        var taskWorkNoteMessage = "Attachment: '" + fileName + "' has been copied from RITM: " + recordNumber;
                        taskRec.comments = taskWorkNoteMessage;
                    } else if (current.operation() == "delete") {
                        removeAttachment("sc_task", taskRec.sys_id, fileName);
                        var taskWorkNoteMessage = "Attachment: '" + fileName + "' has been removed from RITM: " + recordNumber;
                        taskRec.comments = taskWorkNoteMessage;
                    }
                    taskRec.update();
                }
            } else if (current.table_name == "sc_task") {
                // Handle RITM record
                var ritmRec = new GlideRecord("sc_req_item");
                if (ritmRec.get(recordRec.request_item)) {
                    if (current.operation() == "insert") {
                        copyAttachment("sc_task", recordSysId, "sc_req_item", ritmRec.sys_id);
                        var ritmWorkNoteMessage = "Attachment: '" + fileName + "' has been copied from SC Task: " + recordNumber;
                        ritmRec.comments = ritmWorkNoteMessage;
                    } else if (current.operation() == "delete") {
                        removeAttachment("sc_req_item", ritmRec.sys_id, fileName);
                        var ritmWorkNoteMessage = "Attachment: '" + fileName + "' has been removed from SC Task: " + recordNumber;
                        ritmRec.comments = ritmWorkNoteMessage;
                    }
                    ritmRec.update();
                }
            }
        }
    }
 
})(current, previous);
 
Comments are updating fine as per this script but copy is not happening.
Please let me know why this not working fine in all scenarios as per my requirement. Please help me with exact code which works in these all scenarios.
 
Thank you
13 REPLIES 13

Voona Rohila
Kilo Patron
Kilo Patron

Hi @Sirri 

The logic goes on loop, Once the attachment is copied from RITM to SCTask, the BR Triggers again and your else if statement runs again and so on...

 

Ex- If attachment is added on RITM( then same attachment is copied to CTASK, the BR gets Triggered twice once when attachment is added on RITM and again when it's copied to CTASK, to prevent copying twice, we need to check if it already exists on the destination record before proceeding.

 


Mark it helpful if this helps you to understand. Accept solution if this give you the answer you're looking for
Kind Regards,
Rohila V
2022-25 ServiceNow Community MVP

As brian suggested, Related list is the good option if you have sync from both RITM to CTASK and vice-versa.


Mark it helpful if this helps you to understand. Accept solution if this give you the answer you're looking for
Kind Regards,
Rohila V
2022-25 ServiceNow Community MVP

@Voona Rohila ,

 

Can you provide as per my script . I need to copy like that only I didn't to user Related List concept in this case.

 

Thank you

Brian Lancaster
Tera Sage

You should use attachment.copy. You would then pass it the source and destination table as well as the source and destination sys_id. A better method unless you the end user needs to see attachments that are added from the sc_task would be to use a related list. See this article below.

 

https://www.servicenow.com/community/developer-blog/a-better-requested-item-attachments-related-list...