Copy Attachment from SCATSK to RITM

Clement_V
Tera Guru

To copy attachments from an SCTASK to a RITM, I used BusinessRule#1, which I found in a ServiceNow Community post

 

The problem is that each time an attachment is added to the SCTASK, all of its attachments are copied to the RITM, even those already there, which causes duplicates.

 

To solve this, I have BusinessRule#2 that automatically deletes an existing attachment on a RITM if a new, identical attachment (same name, type, size) is added, to avoid duplicates.

 

BusinessRule#1 (after - insert)

Condition : current.table_name == 'sc_task'

Script : 

(function executeRule(current, previous /*null when async*/ ) {
    var taskRec = new GlideRecord('sc_task');
    taskRec.addQuery('sys_id', current.table_sys_id);
    taskRec.query();
    if (taskRec.next()) {
        var ritmRec = new GlideRecord('sc_req_item');
        ritmRec.addQuery('sys_id', taskRec.request_item);
        ritmRec.query();
        if (ritmRec.next()) {
            GlideSysAttachment.copy('sc_task', current.table_sys_id, 'sc_req_item', ritmRec.sys_id);
        }
    }
})(current, previous);
 

BusinessRule#2 (before - insert, update)

Condition : current.table_name == 'sc_req_item'

Script :

(function executeRule(current, previous /*null when async*/ ) {
    var attach = new GlideRecord('sys_attachment');
    attach.addQuery('table_sys_id', current.table_sys_id);
    attach.addQuery('table_name', current.table_name);
    attach.addQuery('file_name', current.file_name);
    attach.addQuery('content_type', current.content_type);
    attach.addQuery('size_bytes', current.size_bytes);
    attach.setLimit(1);
    attach.query();
    if (attach.next()) {
        attach.deleteRecord();
    }
})(current, previous);

 

This technique works well, but the following points bother me:

  • With each new addition to the SCTASK, all the task's attachments are still copied to the RITM before the duplicates are deleted.
  • Deletion is based solely on name, type, and size, so two different files that are identical based on these criteria risk being deleted by mistake.
  • The two Business Rules execute one after the other (after insert + before insert), which can cause temporary duplicates, unexpected deletions, or an unpredictable execution order.

 

I'd like to copy only the newly added attachment to avoid any duplicates from the start. Do you know of a way to do this?

1 ACCEPTED SOLUTION

Uncle Rob
Kilo Patron

This is way easier to do in Flow Designer.  There are all kinds of Flow Actions for managing attachments now.

UncleRob_0-1755703116197.png

Plus you can isolate it to a single attachment via conditions

UncleRob_1-1755703205120.png

 

 

View solution in original post

10 REPLIES 10

Rafael Batistot
Tera Sage

Hi @Clement_V 

May you try this code:

  • Table: sys_attachment

  • When: after insert

  • Condition: current.table_name == 'sc_task'



 

var taskGr = new GlideRecord('sc_task');
    if (taskGr.get(current.table_sys_id)) {
        var ritmGr = new GlideRecord('sc_req_item');
        if (ritmGr.get(taskGr.request_item)) {
            // Copy only this attachment (the one just inserted)
            GlideSysAttachment.copy(
                current.table_name,
                current.table_sys_id,
                ritmGr.getTableName(),
                ritmGr.getUniqueValue()
            );
        }