- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-20-2023 09:00 AM
Hello.
I've been asked to copy External comments from Child incidents up to the Parent incident in he work_notes field. This is so the incident managers only have to watch one incident for incoming comments.
I've got a BR that does this fine. However what I've found is that this copy up is triggering the OOTB BR to copy work_notes back the other way.
I've tried to figure a way round this and so far I've drawn a blank. I've tried do setWorkFlow(false) on the child record BR but that doesn't seem to stop the parent copy from triggering.
It doesn't seem to get in a loop beyond Child.external -> Parent.work_note -> Child.work_note, but I'd really like to stop the child getting cascaded to when it's the child that's caused the update.
Any one solved something similar or have any ideas on what I might try?
Many thanks!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-21-2023 03:16 AM
So I've found two solutions. One is dirty and wants to make me scrub myself, the other is neat, and makes me wonder why I didn't come up with it the first place.
Apparently the reason setWorkflow isn't working in this instance is that it's (apparently) a BR that copies the comment to the sys_journal tables and updates the sys_audit tables. So setting setWorkflow stops that happening hence the comment in original script post saying, "stops THIS BR from updating the inc."
The solution I've gone with is to add some code the OOTB BR that cascades the comments from parent to child, to quit if the comment contains the text, "DO NOT REPLY ON THIS INCIDENT!" Since I'm adding that as part of the copy up I know I can control it (until some smart arse breaks it). There's still the issue of recursion and all the BRs for the parent are still run and I rather they weren't but it works. And isn't dirty. Well not as dirty as the dirty solution!
The dirty solution was to write direct to sys_journal_field and related audit tables. I found some code to do this on another post. It works, doesn't appear to break anything, but I just can't bring myself to leave it there. I'm sure they'll be something that it breaks, or does in the future and I'd never know.
I give you my dirty script in all its glory..
(function executeRule(current, previous /*null when async*/) {
// Add your code here
var inc = new GlideRecord('incident');
inc.get(current.parent_incident);
var msg = 'The following comment has been added by ' + gs.getUserDisplayName();
msg += ' on child incident ' + inc.number + ':';
var comment = current.comments.getJournalEntry(1);
msg += "<br/><br/>" + comment + "<br/>" + 'DO NOT REPLY ON THIS INCIDENT!';
// We are here creating the journal entry manually. This is dirty stuff but it works.
// The reason for this is because there's no way through normal BR processing to add a comment
// to the parent and not have it cascade down to the child. Comments are written to sys_journal_lo
// using a BR so if you setWorkflow(false) you stop that working. So we write directly..
// Create Journal Entry
var incSysId = inc.getUniqueValue();
var incTable = inc.getTableName();
var jrnlFld = new GlideRecord('sys_journal_field');
jrnlFld.initialize();
jrnlFld.setValue('element', 'work_notes');
jrnlFld.setValue('element_id', incSysId);
jrnlFld.setValue('name', incTable);
jrnlFld.setValue('value', msg);
jrnlFld.setValue('sys_created_by', gs.getUserName());
var jrnlSysId = jrnlFld.insert();
// Create Sys Audit and History Line using GlideAuditor
// for the incident
var prevModCount = parseInt(previous.sys_mod_count, 10);
var intCheckPoint;
if(prevModCount === 0){
// Get next 'internal_checkpoint', which is the same as internal_checkpoint
// for other Audit records for Update Number 1
intCheckPoint = GlideCounter.next('internal_checkpoint');
} else if(prevModCount > 0){
// Find existing 'internal_checkpoint' from [sys_history_set] to avoid slow query on [sys_audit]
//var hwINC = new sn_hw.HistoryWalker(incTable, incSysId);
var grHistSet = new GlideRecord('sys_history_set');
grHistSet.get('id', incSysId); // historywalker API created History Set if needed, so we're sure it exists
intCheckPoint = grHistSet.getValue('internal_checkpoint');
}
var auditor = new GlideAuditor(incTable, incSysId); //auditor adds correct username and sets correct mod count
auditor.auditField(null, current.sys_mod_count, intCheckPoint, 'work_notes', 'JOURNAL FIELD ADDITION', msg);
})(current, previous);

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-20-2023 09:04 AM
@spike Ideally, setWorkflow(false) in the child BR should address this issue. If possible please share the script of your child record business rule.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-21-2023 01:27 AM - edited 12-21-2023 01:55 AM
This is the script. You can see the places I've tried it and the output from each..
(function executeRule(current, previous /*null when async*/) {
// Add your code here
// gs.setWorkflow(false); // Doesn't work
var inc = new GlideRecord('incident');
// inc.setWorkflow(false); // stops THIS BR from updating inc
inc.get(current.parent_incident);
var msg = 'The following comment has been added by ' + gs.getUserDisplayName();
msg += ' on child incident ' + inc.number + ':';
var comment = current.comments.getJournalEntry(1);
// Stop other business rules from running. This is a bit contraversal but shouldn't be an issue
// here. We are only adding a message and so we don't want any other automatic processing to
// run.
// current.setWorkflow(false); // Doesn't work
inc.work_notes.setJournalEntry(msg + "<br/><br/>" + comment + "<br/>" + 'DO NOT REPLY ON THIS INCIDENT!');
// inc.setWorkflow(false); // stops THIS BR from updating inc
// gs.setWorkflow(false); // Doesn't work
// current.setWorkflow(false); // Doesn't work
inc.update();
gs.info('SPIKE: here');
})(current, previous);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-21-2023 03:16 AM
So I've found two solutions. One is dirty and wants to make me scrub myself, the other is neat, and makes me wonder why I didn't come up with it the first place.
Apparently the reason setWorkflow isn't working in this instance is that it's (apparently) a BR that copies the comment to the sys_journal tables and updates the sys_audit tables. So setting setWorkflow stops that happening hence the comment in original script post saying, "stops THIS BR from updating the inc."
The solution I've gone with is to add some code the OOTB BR that cascades the comments from parent to child, to quit if the comment contains the text, "DO NOT REPLY ON THIS INCIDENT!" Since I'm adding that as part of the copy up I know I can control it (until some smart arse breaks it). There's still the issue of recursion and all the BRs for the parent are still run and I rather they weren't but it works. And isn't dirty. Well not as dirty as the dirty solution!
The dirty solution was to write direct to sys_journal_field and related audit tables. I found some code to do this on another post. It works, doesn't appear to break anything, but I just can't bring myself to leave it there. I'm sure they'll be something that it breaks, or does in the future and I'd never know.
I give you my dirty script in all its glory..
(function executeRule(current, previous /*null when async*/) {
// Add your code here
var inc = new GlideRecord('incident');
inc.get(current.parent_incident);
var msg = 'The following comment has been added by ' + gs.getUserDisplayName();
msg += ' on child incident ' + inc.number + ':';
var comment = current.comments.getJournalEntry(1);
msg += "<br/><br/>" + comment + "<br/>" + 'DO NOT REPLY ON THIS INCIDENT!';
// We are here creating the journal entry manually. This is dirty stuff but it works.
// The reason for this is because there's no way through normal BR processing to add a comment
// to the parent and not have it cascade down to the child. Comments are written to sys_journal_lo
// using a BR so if you setWorkflow(false) you stop that working. So we write directly..
// Create Journal Entry
var incSysId = inc.getUniqueValue();
var incTable = inc.getTableName();
var jrnlFld = new GlideRecord('sys_journal_field');
jrnlFld.initialize();
jrnlFld.setValue('element', 'work_notes');
jrnlFld.setValue('element_id', incSysId);
jrnlFld.setValue('name', incTable);
jrnlFld.setValue('value', msg);
jrnlFld.setValue('sys_created_by', gs.getUserName());
var jrnlSysId = jrnlFld.insert();
// Create Sys Audit and History Line using GlideAuditor
// for the incident
var prevModCount = parseInt(previous.sys_mod_count, 10);
var intCheckPoint;
if(prevModCount === 0){
// Get next 'internal_checkpoint', which is the same as internal_checkpoint
// for other Audit records for Update Number 1
intCheckPoint = GlideCounter.next('internal_checkpoint');
} else if(prevModCount > 0){
// Find existing 'internal_checkpoint' from [sys_history_set] to avoid slow query on [sys_audit]
//var hwINC = new sn_hw.HistoryWalker(incTable, incSysId);
var grHistSet = new GlideRecord('sys_history_set');
grHistSet.get('id', incSysId); // historywalker API created History Set if needed, so we're sure it exists
intCheckPoint = grHistSet.getValue('internal_checkpoint');
}
var auditor = new GlideAuditor(incTable, incSysId); //auditor adds correct username and sets correct mod count
auditor.auditField(null, current.sys_mod_count, intCheckPoint, 'work_notes', 'JOURNAL FIELD ADDITION', msg);
})(current, previous);