The CreatorCon Call for Content is officially open! Get started here.

asifnoor
Kilo Patron

Hi,

In the last article, as you have seen, I have shown you how to copy all attachments from 1 record to another set of record(s). In this article, I will show you how you can copy a specific attachment from 1 record to another set of record(s).

To do this, we will need the following.

  • Attachment_entry (UI Macro): This is OOB UI Macro. So open this, click on insert and stay so that the OOB Record is not edited. Then deactivate the original record. We will add Copy link in our UI Macro attachment_entry
  • A popup view to select target incidents
  • A UI Button (list choice) to trigger copy action
  • A script include to actually copy the attachment.

Attachment_entry (UI Macro)

In this macro, we will add a copy link as shown below

find_real_file.png

 

Below, in the file add this javascript function onCopy which is being called by that copy link.

In the file, you will see a<script> tag. In that, you can add this function

function onCopy(source_table,source_table_sys_id,source_file_id) {
  console.log("test "+source_table+"---"+source_table_sys_id);
  //open the popup view of incidents
  var dialog = new GlideDialogWindow("copy_incidents_attach_view");
  dialog.setTitle("Select Attachments to Copy");
  dialog.setPreference('table', 'incident_list');
  dialog.setPreference('sysparm_view', 'copy_incident_attachments_view');
  dialog.setPreference('sysparm_force_row_count', 10);
  dialog.setPreference("source_table_name", source_table);
  dialog.setPreference("source_table_sys_id", source_table_sys_id);
  dialog.setPreference("source_file_id", source_file_id);
  dialog.render();
}

Once this is done, you shall see a link Copy beside each attachment in your incident record as you see below.

 A popup View to select Target Records

find_real_file.png

 

UI Action Copy Attachment

Create a UI action as per this screenshot on the incident table.

find_real_file.png

 

And in the script, add this code.

function copyAttachment() {
  var gdw = GlideDialogWindow.get();
  var source_table_name = gdw.getPreference('source_table_name');
  var source_table_sys_id = gdw.getPreference('source_table_sys_id');
  var source_file_id = gdw.getPreference('source_file_id');
  var target_table_name = g_list.getTableName();
  var selected_elem = g_list.getChecked();
  var selected_ids = selected_elem.split(",");
  if(selected_ids.length>1) {
    for(i=0;i<selected_ids.length;i++) {
      if(selected_ids[0]==source_table_sys_id) {
        alert("You seem to have selected the source record also here. kindly check ");
        return false;
      }
    }
  } 
  else {
    if(selected_elem==source_table_sys_id) {
      alert("The selected record is the same as source record. kindly check ");
      return false;
    }	
  }	
  console.log("Copy attachments"+source_table_name+"---"+source_table_sys_id+"---"+g_list.getChecked()+"--"+g_list.getTableName()+"---"+source_file_id+"--"+selected_ids.length);
  //call script include to copy attachment.	
  var ga = new GlideAjax('Copy_Individual_Attachment');
  ga.addParam('sysparm_name','copySpecificAttachment');
  ga.addParam('sysparm_source_table_name',source_table_name);
  ga.addParam('sysparm_source_table_sys_id',source_table_sys_id);
  ga.addParam('sysparm_source_file_id',source_file_id);
  ga.addParam('sysparm_target_table_name',target_table_name);
  ga.addParam('sysparm_target_table_sys_id',selected_elem);
  ga.addParam('sysparm_target_ids_count',selected_ids.length);
  ga.getXML(callback);
  function callback(response)
  {
    var answer = response.responseXML.documentElement.getAttribute("answer");
    if(answer) {
      gdw.destroy();
      g_form.addInfoMessage("Attachment copied successfully");
    } else {
      g_form.addErrorMessage("Error: Attachment is not copied ");
    }	
  }
}

 

Script Include (Copy Attachment)

 

var Copy_Individual_Attachment = Class.create();
Copy_Individual_Attachment.prototype = Object.extendsObject(AbstractAjaxProcessor, {
  copySpecificAttachment: function() {
    var donorTable = this.getParameter('sysparm_source_table_name');
    var donorID = this.getParameter('sysparm_source_table_sys_id');
    var recipientTable = this.getParameter('sysparm_target_table_name');
    var recipientID = this.getParameter('sysparm_target_table_sys_id');
    var fileID = this.getParameter('sysparm_source_file_id');
    var recordCount = this.getParameter('sysparm_target_ids_count');
    for(i=0;i<recordCount;i++) {
      var donorAttSysID;
      var newAttRecord;
      var linkToNewRecord;
      var attDataRecord;
      var newDocRecord;
      var attRecord = new GlideRecord('sys_attachment');	
      attRecord.addQuery('sys_id', fileID);
      attRecord.query();
      if (attRecord.next()) {
        donorAttSysID = attRecord.getValue('sys_id');
        newAttRecord = this.copyRecord(attRecord);
        newAttRecord.setValue('table_name', recipientTable);
        if(recordCount>1) {
          var target_ids = recipientID.split(",");
          newAttRecord.setValue('table_sys_id', target_ids[i]);
        } else {
          newAttRecord.setValue('table_sys_id', recipientID);
        }
        newAttRecord.update();
        linkToNewRecord = gs.getProperty('glide.servlet.uri') + newAttRecord.getLink();
        attDataRecord = new GlideRecord('sys_attachment_doc');
        attDataRecord.addQuery('sys_attachment', donorAttSysID);
        attDataRecord.query();
        while (attDataRecord.next()) {
          newDocRecord = this.copyRecord(attDataRecord);
          newDocRecord.setValue('sys_attachment', newAttRecord.getValue('sys_id'));
          newDocRecord.update();
        }
      }
    }
    return 1;
  },
  copyRecord: function(record) {
    var recordElement;
    var recordElementName;
    var recordTable = record.getTableName();
    var recordFields = record.getFields();
    var newRecord = new GlideRecord(recordTable);
    newRecord.initialize();
    for (var i = 0; i < recordFields.size(); i++) {
      recordElement = recordFields.get(i);
      if(recordElement.getName() != 'sys_id' && recordElement.getName() != 'number')
      {
        recordElementName = recordElement.getName();
        if(recordTable == 'sys_attachment')
        newRecord.setValue(recordElementName, record.getValue(recordElementName));
      }
    }
    var newSysid = newRecord.insert();
    if(recordTable == 'sys_attachment')
      return newRecord;
  },	
  type: 'Copy_Individual_Attachment'
});

Let me know if you have any questions in the comments.

Mark the article as helpful and bookmark if you found it useful.

Note: The server-side code is taken from this blog https://snprotips.com/blog/2016/2/25/understanding-and-using-glideattachment

Comments
Rob Sestito
Mega Sage

Hello,

How can I apply this into a scoped application?

I was able to reproduce the UI Macro as your first step suggested. When I go to an HR Case, I have the following errors appear:

find_real_file.png

Able to help me out?

From what I believe this article is accomplishing, is the exact same thing as to what I am asking in my post: Selecting which attachments to copy from one record to another

Are you able to lend a hand?

Cheers!

-Rob

asifnoor
Kilo Patron

Hello Rob,

Glad to hear that this article is going to help your use case. Could you disable the UI action once and check and confirm if the issue is coming with the UI action code or anything else. Based on that i can assist you further on this.

Rob Sestito
Mega Sage

So Sorry! I never saw this - the Community notifications have not been right for me in a while.

Regardless, I am not seeing the error anymore - but now nothing happens when I click on my UI Action.

I am going to post everything I have, in hopes that you are able to help me out with this.

Thank you!!

UI Macro: attachment_entry (changes) Line 95 - 110

find_real_file.png

 

Script Include:

find_real_file.png

Script Include Script:

var Copy_Individual_Attachment = Class.create();
Copy_Individual_Attachment.prototype = Object.extendsObject(AbstractAjaxProcessor, {
	copySpecificAttachment: function() {
		var donorTable = this.getParameter('sysparm_source_table_name');
		var donorID = this.getParameter('sysparm_source_table_sys_id');
		var recipientTable = this.getParameter('sysparm_target_table_name');
		var recipientID = this.getParameter('sysparm_target_table_sys_id');
		var fileID = this.getParameter('sysparm_source_file_id');
		var recordCount = this.getParameter('sysparm_target_ids_count');
		for(i=0;i<recordCount;i++) {
			var donorAttSysID;
			var newAttRecord;
			var linkToNewRecord;
			var attDataRecord;
			var newDocRecord;
			var attRecord = new GlideRecord('sys_attachment');
			attRecord.addQuery('sys_id', fileID);
			attRecord.query();
			if (attRecord.next()) {
				donorAttSysID = attRecord.getValue('sys_id');
				newAttRecord = this.copyRecord(attRecord);
				newAttRecord.setValue('table_name', recipientTable);
				if(recordCount>1) {
					var target_ids = recipientID.split(",");
					newAttRecord.setValue('table_sys_id', target_ids[i]);
				} else {
					newAttRecord.setValue('table_sys_id', recipientID);
				}
				newAttRecord.update();
				linkToNewRecord = gs.getProperty('glide.servlet.uri') + newAttRecord.getLink();
				attDataRecord = new GlideRecord('sys_attachment_doc');
				attDataRecord.addQuery('sys_attachment', donorAttSysID);
				attDataRecord.query();
				while (attDataRecord.next()) {
					newDocRecord = this.copyRecord(attDataRecord);
					newDocRecord.setValue('sys_attachment', newAttRecord.getValue('sys_id'));
					newDocRecord.update();
				}
			}
		}
		return 1;
	},
	copyRecord: function(record) {
		var recordElement;
		var recordElementName;
		var recordTable = record.getTableName();
		var recordFields = record.getFields();
		var newRecord = new GlideRecord(recordTable);
		newRecord.initialize();
		for (var i = 0; i < recordFields.size(); i++) {
			recordElement = recordFields.get(i);
			if(recordElement.getName() != 'sys_id' && recordElement.getName() != 'number')
				{
				recordElementName = recordElement.getName();
				if(recordTable == 'sys_attachment')
					newRecord.setValue(recordElementName, record.getValue(recordElementName));
			}
		}
		var newSysid = newRecord.insert();
		if(recordTable == 'sys_attachment')
			return newRecord;
	},
	type: 'Copy_Individual_Attachment'
});

 

UI Action:

find_real_file.png

 

UI Action Script:

function grabAttachments(){
	var gdw = GlideDialogWindow.get();
	var source_table_name = gdw.getPreference('source_table_name');
	var source_table_sys_id = gdw.getPreference('source_table_sys_id');
	var source_file_id = gdw.getPreference('source_file_id');
	var target_table_name = g_list.getTableName();
	var selected_elem = g_list.getChecked();
	var selected_ids = selected_elem.split(",");
	if(selected_ids.length>1) {
		for(i=0;i<selected_ids.length;i++) {
			if(selected_ids[0]==source_table_sys_id) {
				alert("You seem to have selected the source record also here. kindly check ");
				return false;
			}
		}
	}
	else {
		if(selected_elem==source_table_sys_id) {
			alert("The selected record is the same as source record. kindly check ");
			return false;
		}
	}
	console.log("Copy Attachment"+source_table_name+"---"+source_table_sys_id+"---"+g_list.getChecked()+"--"+g_list.getTableName()+"---"+source_file_id+"--"+selected_ids.length);
	//call script include to copy attachment.
	var ga = new GlideAjax('Copy_Individual_Attachment');
	ga.addParam('sysparm_name','copySpecificAttachment');
	ga.addParam('sysparm_source_table_name',source_table_name);
	ga.addParam('sysparm_source_table_sys_id',source_table_sys_id);
	ga.addParam('sysparm_source_file_id',source_file_id);
	ga.addParam('sysparm_target_table_name',target_table_name);
	ga.addParam('sysparm_target_table_sys_id',selected_elem);
	ga.addParam('sysparm_target_ids_count',selected_ids.length);
	ga.getXML(callback);
	function callback(response)
	{
		var answer = response.responseXML.documentElement.getAttribute("answer");
		if(answer) {
			gdw.destroy();
			g_form.addInfoMessage("Attachment copied successfully");
		} else {
			g_form.addErrorMessage("Error: Attachment is not copied ");
		}
	}
}

Does things look right to you, for what I am trying to do based off of your post?

Thank you so much!

-Rob

asifnoor
Kilo Patron

Hello Rob,

Seems like I am having the same issue with notifications. I did not see your reply.

May be we can get in touch over the email asif@azrisolutions.com and i can quickly assist you there.

Simon Ciglia
Giga Guru

Thank you very much @asifnoor 

 

The only thing not working is that the "Manage Attachments" header doesn't get updated, I see the uploaded files in the "Activities" but not in the header....do you have any idea why this is the case? Thank you in advance, Simon

asifnoor
Kilo Patron

Hi Simon,

Kindly note that once you select the record in the popup , then you need to go to that record and check manage attachments header of that incident.

 

Simon Ciglia
Giga Guru

Hi @asifnoor ,

Thank you, but my problem is, that the target incident record management attachment header get's not updated.
I see that the attachment was copied to the target record in the target incident activities...but no changes in the header...

 

asifnoor
Kilo Patron

Hi Simon,

Go to sys_attachment and search by your incident sys_id in the table_sys_id column and see if you see the entry or not.

I feel that the table_sys_id could not have been updated, bcoz of which you are not seeing the attachments in the attachment header.

Mark the comment as helpful if it helps to solve your problem.

Regards,
Asif
2020 ServiceNow Community MVP

Community Alums
Not applicable

Hi Asif,

 

I am still facing some issues, nothing happens when i click on my UI action.

PS: i am using it in scoped application.

 

kindly assist.

 

Thanks,

Palak

Community Alums
Not applicable

Hi Rob,

 

Kindly let me know the steps after this, as i am also facing the same issue.

 

Thanks,

Palak

asifnoor
Kilo Patron

Hi Palak,

AS we have checked, getFields function is not available in a scoped application. So  in place of that, may be you might have to use actual field names and try it once.

Mark the comment as helpful if it helps.

mahesh72
Kilo Contributor

Hello Asifnoor,

Please help me with this, whether it is possible or not

- When you have attachments in the Case and need to open a Task, add an option to add specific attachments from the case to task. Its too cumbersome now.

How to Reproduce : Attach a file to the case, you also have to attach to Task.

ServiceNow expo
Kilo Contributor

Hi Asifnoor,

 

The code is working as we excepted. But, after copied attachments from source incident to target incident, I am not able to download the same. Getting error, please refer below screenshot. Even for image,pdf attachments also.

 

Please help us.

find_real_file.png

ServiceNow expo
Kilo Contributor

Hi Asifnoor,

 

This issue is resolved. 

 updated script include attached here.

 

var Copy_Individual_Attachment = Class.create();
Copy_Individual_Attachment.prototype = Object.extendsObject(AbstractAjaxProcessor, {
copySpecificAttachment: function() {
var donorTable = this.getParameter('sysparm_source_table_name');
var donorID = this.getParameter('sysparm_source_table_sys_id');
var recipientTable = this.getParameter('sysparm_target_table_name');
var recipientID = this.getParameter('sysparm_target_table_sys_id');
var fileID = this.getParameter('sysparm_source_file_id');
var recordCount = this.getParameter('sysparm_target_ids_count');
for (i = 0; i < recordCount; i++) {
var donorAttSysID;
var newAttRecord;
var linkToNewRecord;
var attDataRecord;
var newDocRecord;
var attRecord = new GlideRecord('sys_attachment');
attRecord.addQuery('sys_id', fileID);
attRecord.query();
if (attRecord.next()) {
donorAttSysID = attRecord.getValue('sys_id');
newAttRecord = this.copyRecord(attRecord);
newAttRecord.setValue('table_name', recipientTable);
if (recordCount > 1) {
var target_ids = recipientID.split(",");
newAttRecord.setValue('table_sys_id', target_ids[i]);
} else {
newAttRecord.setValue('table_sys_id', recipientID);
}
newAttRecord.update();
linkToNewRecord = gs.getProperty('glide.servlet.uri') + newAttRecord.getLink();
attDataRecord = new GlideRecord('sys_attachment_doc');
attDataRecord.addQuery('sys_attachment', donorAttSysID);
attDataRecord.query();
while (attDataRecord.next()) {
newDocRecord = this.copyRecord(attDataRecord);
newDocRecord.setValue('sys_attachment', newAttRecord.getValue('sys_id'));
newDocRecord.update();
}
}
}
return 1;
},
copyRecord: function(record) {
var recordElement;
var recordElementName;
var recordTable = record.getTableName();
var recordFields = record.getFields();
var newRecord = new GlideRecord(recordTable);
newRecord.initialize();
for (var i = 0; i < recordFields.size(); i++) {
recordElement = recordFields.get(i);
if (recordElement.getName() != 'sys_id' && recordElement.getName() != 'number') {
recordElementName = recordElement.getName();
if (recordTable == 'sys_attachment' || recordTable == 'sys_attachment_doc' )
newRecord.setValue(recordElementName, record.getValue(recordElementName));
}
}
var newSysid = newRecord.insert();
if (recordTable == 'sys_attachment' || recordTable == 'sys_attachment_doc' )
return newRecord;
},
type: 'Copy_Individual_Attachment'
});

Jan Moser
Tera Expert

Hi,

regarding copying the attachment, is there any reason for not using simply ".insert()" on both the source  Attachment and Attachment Doc for creating new (copied) records?

Am I missing anything?

Example:

find_real_file.png

Thanks.

Jan

Version history
Last update:
‎07-22-2019 03:14 AM
Updated by: