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

Duplicate Catalog Item image Attachment record from Picture field to Icon field

Jake-K
Tera Contributor

I am currently working on a catalog script that deals image field attachments within the sc_cat_item record. Upon loading an sc_cat_item record, I need to verify if an image is present in the Picture field but absent in the Icon field. If this condition is met, the objective is to duplicate the Picture field attachment record and transfer it to the Icon field.

However, I have encountered an issue where directly obtaining the Picture field in the sys_attachment Table and inserting a copy with an altered file_name does not result in the creation of a new record. This could be due to a potential sys_id conflict. Although I can successfully generate a new empty record for the Icon field, I have yet to determine a method for transferring the file content from the Picture field to the newly created record, leaving it empty.

Is it possible to utilize the GlideSysAttachment API for this purpose, or would it be inapplicable since the image attachments in question do not belong to the same category as standard record file attachments? I've included screenshots of my client script and related records. Any direction you could provide would be greatly appreciated!

3 REPLIES 3

Maik Skoddow
Tera Patron
Tera Patron

Hi @Jake-K 

 

first a screenshot to make clear how it is working behind the scenes:

 

MaikSkoddow_0-1706596372877.png

 

In a Business Rule you could use the API GlideSysAttachment.writeContentStream() to have the full control over the file name (internal field name in the cat item) for the copied attachment. See https://developer.servicenow.com/dev.do#!/reference/api/vancouver/server_legacy/GlideSysAttachmentGl... for example

 

Hint: The copy() method in that API will not help you!

 

Maik

Thanks Maik. A Business Rule was definitely the way to go. My solution was not pretty, but it works. I have an insert/update business rule triggering on sys_attachment table when table_name is 'ZZ_YYsc_cat_item' and file_name is 'picture'. Code below for others to reference:

 

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

        var item = current.table_sys_id;

        //Get picture
        var gr_picture = new GlideRecord('sys_attachment');
        gr_picture.addQuery('table_sys_id', item);
        gr_picture.addQuery('table_name', 'ZZ_YYsc_cat_item');
        gr_picture.addQuery('file_name', 'picture');
        gr_picture.query();
		
        //Get icon
        var gr_icon = new GlideRecord('sys_attachment');
        gr_icon.addQuery('table_sys_id', item);
        gr_icon.addQuery('table_name', 'ZZ_YYsc_cat_item');
        gr_icon.addQuery('file_name', 'icon');
        gr_icon.query();

		//DO NOT ALTER ROW COUNT CONDITION
        //only run when 1 picture uploaded (avoid infinite loop) and if a picture exists
        if (gr_picture.getRowCount() <=1 && gr_picture.next()) {
            
			//Remove existing icon image if exists
			if (gr_icon.next()) {
				gr_icon.deleteRecord();
			}

			//Duplicate picture attachment
			var att = GlideSysAttachment.copy('sc_cat_item', item, 'sc_cat_item', item);
			//Get duplicated picture record sys_id
			var attSplit = att.toString().trim().split(',');
			var new_att = attSplit[1];
			var copy = new_att.slice(0, -1);
			//Update duplicated picture record to have file_name "icon"
			var gr_att = new GlideRecord('sys_attachment');
            gr_att.get(copy);
			gr_att.file_name = 'icon';
			gr_att.update();
			
            //Set sc_cat_item icon field to sys_id of inserted sys_attachment record
            var gr_item = new GlideRecord('sc_cat_item');
            gr_item.addQuery('sys_id', item);
            gr_item.query();
            if (gr_item.next()) {
                gr_item.icon = gr_att.getUniqueValue();
                gr_item.update();
            }
        }
 
})(current, previous);

 

Hi Maik, thanks for your reply. A business rule was definitely the way to go. I used a business rule on the sys_attachment table looking for insert/update when table_name is 'ZZ_YYsc_cat_item' and file_name is 'picture'. It isn't pretty but I got it working. Code below for others to reference:

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

        var item = current.table_sys_id;

        //Get picture
        var gr_picture = new GlideRecord('sys_attachment');
        gr_picture.addQuery('table_sys_id', item);
        gr_picture.addQuery('table_name', 'ZZ_YYsc_cat_item');
        gr_picture.addQuery('file_name', 'picture');
        gr_picture.query();
		
        //Get icon
        var gr_icon = new GlideRecord('sys_attachment');
        gr_icon.addQuery('table_sys_id', item);
        gr_icon.addQuery('table_name', 'ZZ_YYsc_cat_item');
        gr_icon.addQuery('file_name', 'icon');
        gr_icon.query();

		//DO NOT ALTER ROW COUNT CONDITION
        //only run when 1 picture uploaded (avoid infinite loop) and if a picture exists
        if (gr_picture.getRowCount() <=1 && gr_picture.next()) {
            
			//Remove existing icon image if exists
			if (gr_icon.next()) {
				gr_icon.deleteRecord();
			}

			//Duplicate picture attachment
			var att = GlideSysAttachment.copy('sc_cat_item', item, 'sc_cat_item', item);
			//Get duplicated picture record sys_id
			var attSplit = att.toString().trim().split(',');
			var new_att = attSplit[1];
			var copy = new_att.slice(0, -1);
			//Update duplicated picture record to have file_name "icon"
			var gr_att = new GlideRecord('sys_attachment');
            gr_att.get(copy);
			gr_att.file_name = 'icon';
			gr_att.update();
			
            //Set sc_cat_item icon field to sys_id of inserted sys_attachment record
            var gr_item = new GlideRecord('sc_cat_item');
            gr_item.addQuery('sys_id', item);
            gr_item.query();
            if (gr_item.next()) {
                gr_item.icon = gr_att.getUniqueValue();
                gr_item.update();
            }
        }
 
})(current, previous);