how do I prevent a delegate of one user from approving the record if they have already approved it before in a change
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-21-2022 06:29 AM
Hello,
I have a story which is giving me a lot of trouble and here is the scenario.
We have a person 1 - Paul. He has 4 delegates - steve, neil, john and Allan
1) Steve creates a change CHG123 and just saves it - state=new
2) impersonate Neil - he requests approval on CHG123 and state=assess now. Neil has requested approval and moved the state from new to assess.
3) impersonate John - he then goes to the approvers related list where he is listed and approves the CHG123 from there and now the state=authorize
at this point, all 3 steve, neil and john's records are cancelled in the approver related list (tab)
4) impersonate Neil again - although his record is cancelled. He is still able to approve the record of Paul (since he is his delegate) and move the change state again so it proceeds to state=schedule
This is the problem, they want that once a person has approved it and moved the state they should not be able to do it again themselves or even as a delegate. The issue seems to be arising that the person who moved it from new to assess is able to do it again and they should not be able to. I have found this business rule and amended it (the part in bold) but its still not working...what can I do to fix this please.
(function executeRule(current, previous /*null when async*/ ) {
var message = '';
//RITM
if (current.sysapproval.sys_class_name == 'sc_req_item' && (current.sysapproval.u_requested_for == gs.getUserID() || current.sysapproval.opened_by == gs.getUserID())) {
message = gs.getMessage('You cannot approve or reject this item as you are either the requested for or you opened the request');
}
// Request
else if (current.sysapproval.sys_class_name == 'sc_request' && (current.sysapproval.requested_for == gs.getUserID() || current.sysapproval.opened_by == gs.getUserID())) {
message = gs.getMessage('You cannot approve or reject this request as you are either the requested for or you opened the request');
}
//Change
else if (current.sysapproval.sys_class_name == 'change_request' && (current.sysapproval.requested_by == gs.getUserID() || current.sysapproval.opened_by == gs.getUserID())) {
message = gs.getMessage('You cannot approve or reject this change request as you requested this change');
}
//Change - Delegate Approval restriction
else if (current.sysapproval.sys_class_name == 'change_request' && current.sys_created_by == gs.getUserName()) {
message = gs.getMessage('You cannot approve or reject this change request, as you either moved this record State from New to Assess or approved this change at Assess');
}
else if (current.sysapproval.sys_class_name == 'change_request') {
gs.log('log 1 test');
var gr = new GlideRecord('sysapproval_approver');
gr.addEncodedQuery('state=approved^sys_updated_by=' + gs.getUser().getName() + '^document_id=' + current.document_id);
gr.query();
if (gr.next()) {
gs.log('log 2 test');
message=gs.getMessage('You cannot approve this change request, as you have already approved the record before.');
}
}
if (message != '') {
gs.addErrorMessage(message);
current.state = previous.state;
current.setAbortAction(true);
}
})(current, previous);
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-21-2022 06:30 PM
Hi, you may need to clarify your scenario\issue as the only way I can see to reproduce this is if the delegate manually changes an already approved approval record from approved to requested and then changes it back to approved?
if you are looking to fix this with code, a list edit ACL on sysapproval_approver.state field would probably be my initial approach.
Otherwise a before BR on sysapproval_approver table that aborts the action when the users tries to set the state from approved to any other state.
untested but something like
BR conditions // Only if user interaction via the UI
current.state.changes() && previous.state == 'approved' && gs.isInteractive()
BR script
gs.addErrorMessage("An error message here");
current.setAbortAction(true);
//you might want to expand this, or the conditions, to exclude admin users
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-22-2022 02:47 AM
Hello
What happens is Steve creates the change. He just saves it, thats it. At that point the state is automatically set to new.
Neil comes and requests approval from the button and then state=assess.
Then John comes in and scrolls to the bottom where there is a tab called 'Approvers', he is listed there and he approves his own record from there, now state=authorize.
Then Neil comes back again and goes to the same 'Approvers' tab and although his own record is cancelled, Paul's is still there and is in requested so he goes and approves Paul's record from the tab and state=schedule...I hope that makes it more clear.
No the delegate is not manually changing anyone's records. And if the delegate tries to approve someone elses they can't. If after state=schedule, John, Allan or Neil tries to approve Paul's record again then they get an error. The issue only seems to be happening for the person who moves it from new --> Assess
Thanks for replying, I will try your solutions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-22-2022 12:10 PM
Hi, your description sounds like you are using multiple group approval stages, in which case the behavior is correct\expected and the required solution is user education\training.