Sort recovery task in business continuity management based on the configuration item attached

ritikanand
Tera Expert

Is the requirement even feasible??

Requirement is to sort the recovery task in business continuity management based on the configuration item attached in the recovery task.

ritikanand_2-1744290418374.png

Suppose this configuration item is attached in the recovery task then we should go to cmdb_m2m_business_process_ci table and try to find the configuration item attached with the business process.
Now that business process contains a field which decides the criticality. If 1-most critical then the recovery task should be placed at the top of the list.

ritikanand_3-1744290580074.png 
Now this "Breakdown handling" business process contains the field which decides the criticality.

ritikanand_4-1744290627284.png

 

 

Once we get the information then the recovery task should be placed at the top.
If there are multiple business process having the same criticality then sort of recovery task to be done in alphabetical order.
There might be a case where one configuration item can have two different business process. One of the business process criticality is 1-most critical and the other is 2-somewhat critical. Still it should sort considering the recovery task as 1-most critical

ritikanand_5-1744290973028.pngritikanand_6-1744291043578.png

 

ritikanand_7-1744291107848.pngritikanand_8-1744291140114.png


The recovery task to be sorted here according to the above-mentioned criteria.

ritikanand_9-1744291273808.png

 

If anyone can recommend a solution. It would be really helpful.

1 ACCEPTED SOLUTION

ritikanand
Tera Expert

The requirement is feasible 😊

Solution to the above problem:


1. Create a UI Action: Reorder.
    Configure this for both Native UI as well as Business Continuity Workspace.
    Refer to screenshot below for UI Action:
    

ritikanand_0-1747731310626.png

 


UI Action code for Native UI:

function reorderTask() {

    var ga = new GlideAjax("global.VLV_BCMUtils");

    ga.addParam('sysparm_name', 'reorderRecoveryTasks');

    ga.addParam('sysparm_BCPSysId', g_form.getUniqueValue());

    ga.getXML(function(response) {

        var result = response.responseXML.documentElement.getAttribute("answer");

        if (result == "true") {

            g_navigation.reloadWindow();

        }

       

    });

}
UI Action code for Business Continuity Workspace:

function onClick(g_form) {

    var ga = new GlideAjax("global.VLV_BCMUtils");

    ga.addParam('sysparm_name', 'reorderRecoveryTasks');

    ga.addParam('sysparm_BCPSysId', g_form.getUniqueValue());

    ga.getXML(function(response) {

        var result = response.responseXML.documentElement.getAttribute("answer");

        if (result == "true") {

            this.window.location.reload();

           

        }

    });

}


2. Script include code which is called from the UI Action:

var VLV_BCMUtils = Class.create();

VLV_BCMUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    reorderRecoveryTasks: function() {

        var bcpSysID = this.getParameter('sysparm_BCPSysId');

        var counterAlreadyUsed = {};

        var planlocation = new GlideRecord('sn_bcp_plan_asset');

        planlocation.addEncodedQuery("plan.sys_id=" + bcpSysID);

        planlocation.query();

        if (planlocation.next()) {

            loc = planlocation.item.u_location_id;

        }

        var recTask = new GlideRecord('sn_bcp_recovery_task');

        recTask.addEncodedQuery("plan=" + bcpSysID);

        recTask.orderBy('task_id');

        recTask.query();

 

        var emptyConfigCount = 0; // Counter for empty configuration items

 

        while (recTask.next()) {

            if (recTask.configuration_item == "") {

                emptyConfigCount++;

                continue; // Skip to the next iteration

            }

 

            var criticality = this.getCriticality(recTask.configuration_item + "", loc);

            criticality = criticality.split("-")[0].trim();

            if (!counterAlreadyUsed[criticality]) {

                counterAlreadyUsed[criticality] = 0;

            }

            counterAlreadyUsed[criticality] += 1;

            var taskIDCounter = (Number(criticality) * 1000) + (counterAlreadyUsed[criticality] * 10);

            taskIDCounter = Number(taskIDCounter).toFixed(2);

 

            recTask.task_id = taskIDCounter;

            recTask.update();

        }

 

        // Set task_id for empty configuration items

        var emptyConfigCounter = 1; // Counter for empty configuration items

        recTask = new GlideRecord('sn_bcp_recovery_task');

        recTask.addQuery("plan", bcpSysID);

        recTask.addQuery("configuration_item", "");

        recTask.orderBy('task_id');

        recTask.query();

        while (recTask.next()) {

            recTask.task_id = (emptyConfigCounter * 10) + 5000;

            recTask.update();

            emptyConfigCounter++; // Increment the counter for each empty configuration item

        }

 

        return true;

    },

 

    getCriticality: function(recoveryTasks_CI, loc) {

        var getBizProcess = new GlideRecord('cmdb_m2m_business_process_ci');

        getBizProcess.addEncodedQuery("business_process.location.u_location_id=" + loc + "^cmdb_ci.sys_id=" + recoveryTasks_CI);

        getBizProcess.query();

 

        var highestCriticality = 4; // Start with the lowest criticality (4 - not critical)

 

        while (getBizProcess.next()) {

            var currentCriticality = getBizProcess.business_process.business_crit_determined + "";

            var criticalityValue = this.getCriticalityValue(currentCriticality);

            if (criticalityValue < highestCriticality) {

                highestCriticality = criticalityValue;

            }

        }

        return this.getCriticalityString(highestCriticality);

    },

 

    getCriticalityValue: function(criticality) {

        switch (criticality) {

            case "1 - most critical":

                return 1;

            case "2 - somewhat critical":

                return 2;

            case "3 - less critical":

                return 3;

            default:

                return 4;

        }

    },

 

    getCriticalityString: function(value) {

        switch (value) {

            case 1:

                return "1 - most critical";

            case 2:

                return "2 - somewhat critical";

            case 3:

                return "3 - less critical";

            default:

                return "4 - not critical";

        }

    },

    reorderButtonVisibility: function(planSysID) {

        var gr = new GlideRecord('sn_bcp_plan_asset');

        gr.addEncodedQuery("plan.sys_id=" + planSysID);

        gr.query();

        if (gr.next()) {

            if (gr.element_definition.getDisplayValue() == "Locations") {

                return true;

            } else {

                return false;

            }

        }

    },

    type: 'VLV_BCMUtils'

});


The recovery tasks before clicking the Reorder Button:
      > Verify the Task ID

ritikanand_1-1747731310630.png


The recovery tasks after clicking the Reorder Button:
      > Verify the Task ID

ritikanand_2-1747731310634.png

As there was multiple recovery tasks with criticality 1 so task id was updated as 1010,1020...
For criticality 2, the task id was updated as 2010,2020....
This continues till criticality 4.
There were few recovery tasks which didn't had a configuration item attached then those were updated as 5010,5020....



Please mark this as helpful if this solution helped you in achieving your requirement. 

Thanks
Ritik Anand

View solution in original post

1 REPLY 1

ritikanand
Tera Expert

The requirement is feasible 😊

Solution to the above problem:


1. Create a UI Action: Reorder.
    Configure this for both Native UI as well as Business Continuity Workspace.
    Refer to screenshot below for UI Action:
    

ritikanand_0-1747731310626.png

 


UI Action code for Native UI:

function reorderTask() {

    var ga = new GlideAjax("global.VLV_BCMUtils");

    ga.addParam('sysparm_name', 'reorderRecoveryTasks');

    ga.addParam('sysparm_BCPSysId', g_form.getUniqueValue());

    ga.getXML(function(response) {

        var result = response.responseXML.documentElement.getAttribute("answer");

        if (result == "true") {

            g_navigation.reloadWindow();

        }

       

    });

}
UI Action code for Business Continuity Workspace:

function onClick(g_form) {

    var ga = new GlideAjax("global.VLV_BCMUtils");

    ga.addParam('sysparm_name', 'reorderRecoveryTasks');

    ga.addParam('sysparm_BCPSysId', g_form.getUniqueValue());

    ga.getXML(function(response) {

        var result = response.responseXML.documentElement.getAttribute("answer");

        if (result == "true") {

            this.window.location.reload();

           

        }

    });

}


2. Script include code which is called from the UI Action:

var VLV_BCMUtils = Class.create();

VLV_BCMUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    reorderRecoveryTasks: function() {

        var bcpSysID = this.getParameter('sysparm_BCPSysId');

        var counterAlreadyUsed = {};

        var planlocation = new GlideRecord('sn_bcp_plan_asset');

        planlocation.addEncodedQuery("plan.sys_id=" + bcpSysID);

        planlocation.query();

        if (planlocation.next()) {

            loc = planlocation.item.u_location_id;

        }

        var recTask = new GlideRecord('sn_bcp_recovery_task');

        recTask.addEncodedQuery("plan=" + bcpSysID);

        recTask.orderBy('task_id');

        recTask.query();

 

        var emptyConfigCount = 0; // Counter for empty configuration items

 

        while (recTask.next()) {

            if (recTask.configuration_item == "") {

                emptyConfigCount++;

                continue; // Skip to the next iteration

            }

 

            var criticality = this.getCriticality(recTask.configuration_item + "", loc);

            criticality = criticality.split("-")[0].trim();

            if (!counterAlreadyUsed[criticality]) {

                counterAlreadyUsed[criticality] = 0;

            }

            counterAlreadyUsed[criticality] += 1;

            var taskIDCounter = (Number(criticality) * 1000) + (counterAlreadyUsed[criticality] * 10);

            taskIDCounter = Number(taskIDCounter).toFixed(2);

 

            recTask.task_id = taskIDCounter;

            recTask.update();

        }

 

        // Set task_id for empty configuration items

        var emptyConfigCounter = 1; // Counter for empty configuration items

        recTask = new GlideRecord('sn_bcp_recovery_task');

        recTask.addQuery("plan", bcpSysID);

        recTask.addQuery("configuration_item", "");

        recTask.orderBy('task_id');

        recTask.query();

        while (recTask.next()) {

            recTask.task_id = (emptyConfigCounter * 10) + 5000;

            recTask.update();

            emptyConfigCounter++; // Increment the counter for each empty configuration item

        }

 

        return true;

    },

 

    getCriticality: function(recoveryTasks_CI, loc) {

        var getBizProcess = new GlideRecord('cmdb_m2m_business_process_ci');

        getBizProcess.addEncodedQuery("business_process.location.u_location_id=" + loc + "^cmdb_ci.sys_id=" + recoveryTasks_CI);

        getBizProcess.query();

 

        var highestCriticality = 4; // Start with the lowest criticality (4 - not critical)

 

        while (getBizProcess.next()) {

            var currentCriticality = getBizProcess.business_process.business_crit_determined + "";

            var criticalityValue = this.getCriticalityValue(currentCriticality);

            if (criticalityValue < highestCriticality) {

                highestCriticality = criticalityValue;

            }

        }

        return this.getCriticalityString(highestCriticality);

    },

 

    getCriticalityValue: function(criticality) {

        switch (criticality) {

            case "1 - most critical":

                return 1;

            case "2 - somewhat critical":

                return 2;

            case "3 - less critical":

                return 3;

            default:

                return 4;

        }

    },

 

    getCriticalityString: function(value) {

        switch (value) {

            case 1:

                return "1 - most critical";

            case 2:

                return "2 - somewhat critical";

            case 3:

                return "3 - less critical";

            default:

                return "4 - not critical";

        }

    },

    reorderButtonVisibility: function(planSysID) {

        var gr = new GlideRecord('sn_bcp_plan_asset');

        gr.addEncodedQuery("plan.sys_id=" + planSysID);

        gr.query();

        if (gr.next()) {

            if (gr.element_definition.getDisplayValue() == "Locations") {

                return true;

            } else {

                return false;

            }

        }

    },

    type: 'VLV_BCMUtils'

});


The recovery tasks before clicking the Reorder Button:
      > Verify the Task ID

ritikanand_1-1747731310630.png


The recovery tasks after clicking the Reorder Button:
      > Verify the Task ID

ritikanand_2-1747731310634.png

As there was multiple recovery tasks with criticality 1 so task id was updated as 1010,1020...
For criticality 2, the task id was updated as 2010,2020....
This continues till criticality 4.
There were few recovery tasks which didn't had a configuration item attached then those were updated as 5010,5020....



Please mark this as helpful if this solution helped you in achieving your requirement. 

Thanks
Ritik Anand