Duplicate Catalog Item image Attachment record from Picture field to Icon field
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-29-2024 01:17 PM
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-29-2024 10:37 PM - edited ‎01-29-2024 10:44 PM
Hi @Jake-K
first a screenshot to make clear how it is working behind the scenes:
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-30-2024 05:23 PM
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);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎01-30-2024 05:26 PM
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);