Unable to run conflict detection in SOW using a workspace client script.

Justin Scheich
Tera Guru

Hello,
I'm attempting to run conflict detection and either allow the change to be submitted if none are found or stop the state from being changed to requested if a conflict is found and save the record.

I've added the scripting to the UI action Request approval.
This works in UI16 and the UI16 SOW view. However, when I try to run it from SOW I get an error "Failed to execute the UI Action. Please contact your administrator."

Any ideas on what is causing this not to run at all?

function runClientCode() {
    var sog = g_form.getValue('service_offering');
    var req = g_form.getValue('requested_by');
    var chg_type = g_form.getValue('type');
    var gr = new GlideRecord('service_offering');
    gr.addQuery('sys_id', sog);
    gr.query(checkrecord);

    //Verify the approver for an emergency change is not the same person submitting.
    function checkrecord(gr) {
        while (gr.next()) {
            if (gr.owned_by == req && chg_type == 'Emergency-Freeze') {
                alert('You can not submit this request with the current Business service selected as you would also be the approver. Please have another user submit this change.');
                return false;
            }
        }
    }

    //Start Conflict detection.
    var e = g_form.getValue("conflict_msg");
    if (e) e.remove();
    var fields = "";
    var i = 0;
    if (g_form.getControl("start_date") && g_form.getValue("start_date") == "") {
        fields += ", " + g_form.getLabelOf("start_date");
        i++;
    }
    if (g_form.getControl("end_date") && g_form.getValue("end_date") == "") {
        fields += ", " + g_form.getLabelOf("end_date");
        i++;
    }
    if (g_form.getControl("cmdb_ci") && g_form.getValue("cmdb_ci") == "") {
        fields += ", " + g_form.getLabelOf("cmdb_ci");
        i++;
    }
    if (i > 1) {
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following fields need values: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    } else if (i === 1) {
        g_form.clearMessages();
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following field needs a value: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    }
    gsftSubmit(null, g_form.getFormElement(), 'request.approval');
}


//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
    checkConflicts();
function checkConflicts() {

    //Array which stores fields that dont have a value 
    var fieldArray = [];

    //Put Start date label in array if it doesnt have a value
    if (current.start_date.nil())
        fieldArray.push(current.start_date.getLabel());

    //Put End date label in array if it doesnt have a value
    if (current.end_date.nil())
        fieldArray.push(current.end_date.getLabel());

    //Put CMDB CI label in array if it doesnt have a value
    if (current.cmdb_ci.nil())
        fieldArray.push(current.cmdb_ci.getLabel());

    //If there are values stored in the array then print message 
    if (fieldArray.length > 0) {
        var fieldMsg = '';
        for (var i = 0; i < fieldArray.length; i++) {
            fieldMsg += fieldArray[i] + ", ";
        }
        fieldMsg = fieldMsg.substring(0, fieldMsg.length - 2);
        gs.addErrorMessage(gs.getMessage("To check conflicts, the following fields need values: {0}", fieldMsg));
        current.update();
        action.setRedirectURL(current);
        return;
    }
    //else If there are NO values stored in the array execute the action
    else if (fieldArray.length == 0) {
        suppressMaintenanceScheduleMessages = true;
        var conflictDetector = new ChangeCheckConflicts(current);
        var conflictResults = conflictDetector.check();

        current.conflict_status = 'No Conflict';
        var msg;

        if (conflictResults < 0)
            msg = gs.getMessage('Configuration Item needed for conflict analysis');
        else if (conflictResults == 0) {
            msg = gs.getMessage('There are <FONT COLOR="green">NO CONFLICTS</FONT>');
            current.approval = 'requested';
        } else {
            msg = gs.getMessage('There <FONT COLOR="tomato">ARE CONFLICTS</FONT> - See "Conflicts" related list');
            current.conflict_status = 'Conflict';
        }
        gs.addInfoMessage(msg);
        current.update();
        action.setRedirectURL(current);
    }
}

 

1 ACCEPTED SOLUTION

Justin Scheich
Tera Guru

For anyone looking for the resolution, I got this working with the following UI action script and Workspace client script. This forces the conflict check before you can submit. 

function runClientCode() {
    var e = $("conflict_msg");
    if (e) e.remove();
    var fields = "";
    var i = 0;
    if (g_form.getControl("start_date") && g_form.getValue("start_date") == "") {
        fields += ", " + g_form.getLabelOf("start_date");
        i++;
    }
    if (g_form.getControl("end_date") && g_form.getValue("end_date") == "") {
        fields += ", " + g_form.getLabelOf("end_date");
        i++;
    }
    if (g_form.getControl("cmdb_ci") && g_form.getValue("cmdb_ci") == "") {
        fields += ", " + g_form.getLabelOf("cmdb_ci");
        i++;
    }
    if (i > 1) {
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following fields need values: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    } else if (i === 1) {
        g_form.clearMessages();
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following field needs a value: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    }
    gsftSubmit(null, g_form.getFormElement(), 'request.approval');
}

//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
    checkConflicts();

function checkConflicts() {
    //Get Current Change type
    var type = current.type;

    //Array which stores fields that dont have a value 
    var fieldArray = [];

    //Put Start date label in array if it doesnt have a value
    if (current.start_date.nil())
        fieldArray.push(current.start_date.getLabel());

    //Put End date label in array if it doesnt have a value
    if (current.end_date.nil())
        fieldArray.push(current.end_date.getLabel());

    //Put CMDB CI label in array if it doesnt have a value
    if (current.cmdb_ci.nil())
        fieldArray.push(current.cmdb_ci.getLabel());

    //If there are values stored in the array then print message 
    if (fieldArray.length > 0) {
        var fieldMsg = '';
        for (var i = 0; i < fieldArray.length; i++) {
            fieldMsg += fieldArray[i] + ", ";
        }
        fieldMsg = fieldMsg.substring(0, fieldMsg.length - 2);
        gs.addErrorMessage(gs.getMessage("To check conflicts, the following fields need values: {0}", fieldMsg));
        current.update();
        action.setRedirectURL(current);
        return;
    }
    //else If there are NO values stored in the array and the type is not emergency-freeze execute the action
    if (fieldArray.length == 0 && type != 'Emergency-Freeze') {
        suppressMaintenanceScheduleMessages = true;
        var conflictDetector = new ChangeCheckConflicts(current);
        var conflictResults = conflictDetector.check();

        current.conflict_status = 'No Conflict';
        var msg;

        if (conflictResults < 0)
            msg = gs.getMessage('Configuration Item needed for conflict analysis');
        else if (conflictResults == 0) {
            msg = gs.getMessage('There are <FONT COLOR="green">NO CONFLICTS</FONT>');
            current.approval = 'requested';
        } else {
            msg = gs.getMessage('There <FONT COLOR="tomato">ARE CONFLICTS</FONT> - See "Conflicts" related list');
            current.conflict_status = 'Conflict';
        }
        gs.addInfoMessage(msg);
        current.update();
        action.setRedirectURL(current);
    }
    // If the type is emergency-freeze do not run conflict detection automatically.	
    else if (type == 'Emergency-Freeze') {
        current.approval = 'requested';
        current.update();
        action.setRedirectURL(current);
    }
}

// Workspace Client Script

function runClientCode() {
    var sog = g_form.getValue('service_offering');
    var req = g_form.getValue('requested_by');
    var chg_type = g_form.getValue('type');
    var gr = new GlideRecord('service_offering');
    gr.addQuery('sys_id', sog);
    gr.query(checkrecord);

    //Verify the approver for an emergency change is not the same person submitting.
    function checkrecord(gr) {
        while (gr.next()) {
            if (gr.owned_by == req && chg_type == 'Emergency-Freeze') {
                alert('You can not submit this request with the current Business service selected as you would also be the approver. Please have another user submit this change.');
                return false;
            }
        }
    }
    g_form.submit('request.approval');



View solution in original post

4 REPLIES 4

Sanjay191
Tera Sage

Hello @Justin Scheich 

You do not need to change the Out-of-the-Box (OOB) behavior. Instead, you can achieve the requirement with a few customizations. Create a Before Business Rule (BR) with the following logic:

  1. Add a condition in the Business Rule to check for conflicts.
  2. Use the setAbortAction(true) method when a conflict is found to prevent the record from being submitted or processed.
  3. If no conflict is found, allow the request to proceed as normal.



Sanjay191_0-1735206735259.png




Sanjay191_1-1735206747717.png




If my answer has helped with your question, please mark my answer as accepted solution and give a thumb up.
Thank You

 

This works if the change is already saved.
It does not work if I'm creating a new change and have not yet saved the form. 
I have the UI Action script working for UI 16, and I need it to work in SOW.

Toderean alexan
Tera Contributor

Hi @Justin Scheich 

   I would check if there is a problem with permissions, maybe some ACL that require special permission. If there is no problem you have to make a debug through printing, there are many things in the code that could generate that problem.

Justin Scheich
Tera Guru

For anyone looking for the resolution, I got this working with the following UI action script and Workspace client script. This forces the conflict check before you can submit. 

function runClientCode() {
    var e = $("conflict_msg");
    if (e) e.remove();
    var fields = "";
    var i = 0;
    if (g_form.getControl("start_date") && g_form.getValue("start_date") == "") {
        fields += ", " + g_form.getLabelOf("start_date");
        i++;
    }
    if (g_form.getControl("end_date") && g_form.getValue("end_date") == "") {
        fields += ", " + g_form.getLabelOf("end_date");
        i++;
    }
    if (g_form.getControl("cmdb_ci") && g_form.getValue("cmdb_ci") == "") {
        fields += ", " + g_form.getLabelOf("cmdb_ci");
        i++;
    }
    if (i > 1) {
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following fields need values: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    } else if (i === 1) {
        g_form.clearMessages();
        g_form.addErrorMessage(formatMessage(getMessage("To check conflicts, the following field needs a value: {0}"), fields.substring(2)), "conflict_msg");
        return false;
    }
    gsftSubmit(null, g_form.getFormElement(), 'request.approval');
}

//Code that runs without 'onclick'
//Ensure call to server-side function with no browser errors
if (typeof window == 'undefined')
    checkConflicts();

function checkConflicts() {
    //Get Current Change type
    var type = current.type;

    //Array which stores fields that dont have a value 
    var fieldArray = [];

    //Put Start date label in array if it doesnt have a value
    if (current.start_date.nil())
        fieldArray.push(current.start_date.getLabel());

    //Put End date label in array if it doesnt have a value
    if (current.end_date.nil())
        fieldArray.push(current.end_date.getLabel());

    //Put CMDB CI label in array if it doesnt have a value
    if (current.cmdb_ci.nil())
        fieldArray.push(current.cmdb_ci.getLabel());

    //If there are values stored in the array then print message 
    if (fieldArray.length > 0) {
        var fieldMsg = '';
        for (var i = 0; i < fieldArray.length; i++) {
            fieldMsg += fieldArray[i] + ", ";
        }
        fieldMsg = fieldMsg.substring(0, fieldMsg.length - 2);
        gs.addErrorMessage(gs.getMessage("To check conflicts, the following fields need values: {0}", fieldMsg));
        current.update();
        action.setRedirectURL(current);
        return;
    }
    //else If there are NO values stored in the array and the type is not emergency-freeze execute the action
    if (fieldArray.length == 0 && type != 'Emergency-Freeze') {
        suppressMaintenanceScheduleMessages = true;
        var conflictDetector = new ChangeCheckConflicts(current);
        var conflictResults = conflictDetector.check();

        current.conflict_status = 'No Conflict';
        var msg;

        if (conflictResults < 0)
            msg = gs.getMessage('Configuration Item needed for conflict analysis');
        else if (conflictResults == 0) {
            msg = gs.getMessage('There are <FONT COLOR="green">NO CONFLICTS</FONT>');
            current.approval = 'requested';
        } else {
            msg = gs.getMessage('There <FONT COLOR="tomato">ARE CONFLICTS</FONT> - See "Conflicts" related list');
            current.conflict_status = 'Conflict';
        }
        gs.addInfoMessage(msg);
        current.update();
        action.setRedirectURL(current);
    }
    // If the type is emergency-freeze do not run conflict detection automatically.	
    else if (type == 'Emergency-Freeze') {
        current.approval = 'requested';
        current.update();
        action.setRedirectURL(current);
    }
}

// Workspace Client Script

function runClientCode() {
    var sog = g_form.getValue('service_offering');
    var req = g_form.getValue('requested_by');
    var chg_type = g_form.getValue('type');
    var gr = new GlideRecord('service_offering');
    gr.addQuery('sys_id', sog);
    gr.query(checkrecord);

    //Verify the approver for an emergency change is not the same person submitting.
    function checkrecord(gr) {
        while (gr.next()) {
            if (gr.owned_by == req && chg_type == 'Emergency-Freeze') {
                alert('You can not submit this request with the current Business service selected as you would also be the approver. Please have another user submit this change.');
                return false;
            }
        }
    }
    g_form.submit('request.approval');