How to create a list menu ui action that can do multiple attestation using a defined script?

ChuanYanF
Tera Guru

Dear experts,

 

My client would like to have a bulk attest button just like the bulk approve button in the approval table where they can select multiple records in the list then in the list menu they have an approve button to approve all the things required in servicenow. So their requirements are without going into the attestation form and fill in the attestation form which only have two fields
1. Is the control implemented (Yes or No) - Mandatory
2. Explanation
They would like to have the ui action in the list menu which is approve where when click approve it will help them fill in the first question is yes and the explanation field is just leave it blank then changed the state of attestation form to complete. I have tried my own approach to create a new approve ui action list menu and a script include below: 
UI Action Script:

function onBulkApprove() {
  var selectedRecords = g_list.getChecked();
  if (selectedRecords.length === 0) {
    alert("Please select at least one record.");
    return;
  }

  var ga = new GlideAjax('global.BulkAttestationProcessor');
  ga.addParam('sysparm_name', 'processBulkAttestation');
  ga.addParam('sysparm_sys_ids', selectedRecords.join(','));
  ga.getXMLAnswer(function(response) {
    alert(response); // Show confirmation
    g_list.refresh(); // Refresh list
  });
}


Script Include:

var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {
  processBulkAttestation: function() {
    var sysIds = this.getParameter('sysparm_sys_ids').split(',');
    var count = 0;

    // Get the metric sys_id for the "Is the control implemented?" question
    var metricGr = new GlideRecord('asmt_metric');
    metricGr.addQuery('name', 'Is the control implemented?');
    metricGr.query();
    if (!metricGr.next()) {
      return 'Metric "Is the control implemented?" not found.';
    }
    var metricSysId = metricGr.getUniqueValue();

    for (var i = 0; i < sysIds.length; i++) {
      var instanceId = sysIds[i];

      var instanceGr = new GlideRecord('asmt_assessment_instance');
      if (!instanceGr.get(instanceId)) continue;

      // Check if metric result already exists
      var resultGr = new GlideRecord('asmt_metric_result');
      resultGr.addQuery('metric', metricSysId);
      resultGr.addQuery('instance', instanceId);
      resultGr.query();

      var resultExists = false;
      while (resultGr.next()) {
        resultExists = true;
        resultGr.setValue('actual_value', 1);
        resultGr.update();
        count++;
      }

      // If no result exists, create one manually
      if (!resultExists) {
        var newResult = new GlideRecord('asmt_metric_result');
        newResult.initialize();
        newResult.setValue('metric', metricSysId);
        newResult.setValue('instance', instanceId);
        newResult.setValue('actual_value', 1);
        newResult.insert();
        count++;
      }

      // Mark the instance as complete
      instanceGr.setValue('state', 'complete');
      instanceGr.update();
    }

    return count + " attestation(s) approved.";
  }
});


 

1 ACCEPTED SOLUTION

J Siva
Kilo Patron
Kilo Patron

Hi @ChuanYanF 

You need to set the survey reponse in "asmt_assessment_instance_question" table.
I've modified your script and tested it in my PDI. It's working as expected. Please review and modify as required.

UI action:

function onBulkApprove() {
    var selectedRecords = g_list.getChecked();
    if (selectedRecords.length === 0) {
        alert("Please select at least one record.");
        return;
    } else {
        var ga = new GlideAjax('BulkAttestationProcessor');
        ga.addParam('sysparm_name', 'processBulkAttestation');
        ga.addParam('sysparm_sys_ids', selectedRecords);
        ga.getXMLAnswer(function(response) {
            alert(response); // Show confirmation
            g_list.refresh(); // Refresh list
        });
    }

}

Script include:

var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    processBulkAttestation: function() {
        var sysIds = this.getParameter('sysparm_sys_ids').split(',');
		
        var count = 0;

        // Get the metric sys_id for the "Is the control implemented?" question
        var metricGr = new GlideRecord('asmt_metric');
        metricGr.addQuery('name', 'Is the control implemented?');
        metricGr.query();
        if (!metricGr.next()) {
            return 'Metric "Is the control implemented?" not found.';
        } else {
            var metricSysId = metricGr.getUniqueValue();
        }

        for (var i = 0; i < sysIds.length; i++) {
            var instanceId = sysIds[i];

            var instanceGr = new GlideRecord('asmt_assessment_instance');
            if (!instanceGr.get(instanceId)) continue;

            // Check if metric result already exists
            var resultGr = new GlideRecord('asmt_assessment_instance_question'); //UPDATED
            resultGr.addQuery('metric', metricSysId);
            resultGr.addQuery('instance', instanceId);
            resultGr.query();

            var resultExists = false;
            while (resultGr.next()) {
                resultExists = true;
                resultGr.setValue('value', 1);
                resultGr.update();
                count++;
            }

            // Mark the instance as complete
            instanceGr.setValue('state', 'complete');
            instanceGr.update();
        }

        return count + " attestation(s) approved.";
    },

    type: 'BulkAttestationProcessor'
});

Regards,
Siva

View solution in original post

11 REPLIES 11

Ankur Bawiskar
Tera Patron
Tera Patron

@ChuanYanF 

so where are you asking the input? I couldn't see that

where are you stuck?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

I dunno why it is not working, the approve ui action is under the list menu but when I click it nothing happens. So I dont know if my script is wrong or it is not doable?

@ChuanYanF 

did you debug if script include is getting called?

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

J Siva
Kilo Patron
Kilo Patron

Hi @ChuanYanF 

You need to set the survey reponse in "asmt_assessment_instance_question" table.
I've modified your script and tested it in my PDI. It's working as expected. Please review and modify as required.

UI action:

function onBulkApprove() {
    var selectedRecords = g_list.getChecked();
    if (selectedRecords.length === 0) {
        alert("Please select at least one record.");
        return;
    } else {
        var ga = new GlideAjax('BulkAttestationProcessor');
        ga.addParam('sysparm_name', 'processBulkAttestation');
        ga.addParam('sysparm_sys_ids', selectedRecords);
        ga.getXMLAnswer(function(response) {
            alert(response); // Show confirmation
            g_list.refresh(); // Refresh list
        });
    }

}

Script include:

var BulkAttestationProcessor = Class.create();
BulkAttestationProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor, {

    processBulkAttestation: function() {
        var sysIds = this.getParameter('sysparm_sys_ids').split(',');
		
        var count = 0;

        // Get the metric sys_id for the "Is the control implemented?" question
        var metricGr = new GlideRecord('asmt_metric');
        metricGr.addQuery('name', 'Is the control implemented?');
        metricGr.query();
        if (!metricGr.next()) {
            return 'Metric "Is the control implemented?" not found.';
        } else {
            var metricSysId = metricGr.getUniqueValue();
        }

        for (var i = 0; i < sysIds.length; i++) {
            var instanceId = sysIds[i];

            var instanceGr = new GlideRecord('asmt_assessment_instance');
            if (!instanceGr.get(instanceId)) continue;

            // Check if metric result already exists
            var resultGr = new GlideRecord('asmt_assessment_instance_question'); //UPDATED
            resultGr.addQuery('metric', metricSysId);
            resultGr.addQuery('instance', instanceId);
            resultGr.query();

            var resultExists = false;
            while (resultGr.next()) {
                resultExists = true;
                resultGr.setValue('value', 1);
                resultGr.update();
                count++;
            }

            // Mark the instance as complete
            instanceGr.setValue('state', 'complete');
            instanceGr.update();
        }

        return count + " attestation(s) approved.";
    },

    type: 'BulkAttestationProcessor'
});

Regards,
Siva