Join the #BuildWithBuildAgent Challenge! Get recognized, earn exclusive swag, and inspire the ServiceNow Community with what you can build using Build Agent.  Join the Challenge.

Metrics for Planning Items (Demand Feature Epic and Story)

Bkimani
Tera Contributor

I have Replicated the Metrics Events Business Rule with this: 

 

queueMetricUpdate();

function queueMetricUpdate() {
    gs.info('Brian: Starting queueMetricUpdate function.');

    // var gru =  new GlideScriptRecordUtil.get(current);
    // var fieldsChanged = gru.getChangedFieldNames();
    var fieldsChanged = getChangedFieldNames(current);
    gs.info('Brian: Fields Changed Array: ' + JSON.stringify(fieldsChanged));

    var gr = getDefinitions(fieldsChanged);
    var fields = '';

    while (gr.next()) {
        fields += gr.field + ',';
        gs.info('Brian: Found definition for field: ' + gr.field);
    }

    if (fields.length > 0) {
        fields = '[' + fields.substring(0, fields.length - 1) + ']';
        gs.info('Brian: Final fields string: ' + fields);
        gs.eventQueue('sn_align_core.activation.reports.metrics', current, fields, current.sys_mod_count, 'metric_update');
        //  gs.eventQueue('sn_align_core.activation.reports.metrics', current, fields, current.sys_mod_count, 'spm_metric_update');

        gs.info('Brian: Event queued successfully.');
    } else {
        gs.info('Brian: No fields changed, no event queued.');
    }
}


function getDefinitions(fields) {
    gs.info('Brian: Starting getDefinitions with fields: ' + fields.join(', '));
    var gr = new GlideAggregate('metric_definition');
    gr.addQuery('active', 'true');
    var tables = new GlideTableHierarchy(current.getTableName());
    gs.info("Brian Tables: " + tables.toString());
    gr.addQuery('table', tables);
    gr.addQuery('field', fields);
    gr.groupBy('field');
    gr.query();
    gs.info("Brian: final gr: " + gr);
    return gr;
}

function getChangedFieldNames(gr) {
    gs.info('Brian: Starting getChangedFieldNames function.');
    var result = [];
    var elements = gr.getElements();
    var size = elements.length;
    for (var i = 0; i < size; i++) {
        var ge = elements[i];
        if (ge.changes()) {
            result.push(ge.getName());
            gs.info('Brian: Field changed: ' + ge.getName());
        }
    }
    return result;
}

 

I then created this Metric Definition:

Bkimani_0-1723237323563.png

here's the metric definition code: 

if (current.planning_state != '') {
    answer = false;
    mi.endDuration();
    gs.info('Duration ended for Metric Instance with ID: ' + mi.current.sys_id);
    closeDurations(mi.current);
}

function closeDurations(current) {
    gs.info('Entering closeDurations function for Metric Instance with ID: ' + current.sys_id);

    var gr = new GlideRecord('metric_instance');
    gr.addQuery('id', current.sys_id);
    gr.addQuery('calculation_complete', false);
    gr.addQuery('definition.type', 'field_value_duration');
    gr.addQuery('definition', '7ce5750adbe74ed030f968f8139619d5');
    gr.query();

    gs.info('Query executed on metric_instance table. Number of records found: ' + gr.getRowCount());

    while (gr.next()) {
        gs.info('Processing Metric Instance with ID: ' + gr.sys_id);

        var definition = new GlideRecord('metric_definition');
        if (definition.get(gr.definition)) {
            gs.info('Metric Definition found with ID: ' + gr.definition);
            var mi = new MetricInstance(definition, current);
            mi.endDuration();
            gs.info('Duration ended for Metric Instance with ID: ' + current.sys_id);
        } else {
            gs.info('Metric Definition not found for ID: ' + gr.definition);
        }
    }

    gs.info('Exiting closeDurations function');
}

 

I then recreated the Script Action in Global: 

Bkimani_1-1723237459956.png

Here's the code for the script Action:

// current: GlideRecord - event scheduled on behalf of (incident for example) 
// event: GlideRecord - sysevent that caused this to be invoked
metricUpdate();

function metricUpdate() {
    var fields = getChangedFields();
    var updateCount = new String(event.parm2);
    var gr = getDefinitions();

    var didRollback = false;
    while (gr.next()) {
        if (!fields.contains(gr.field))
            continue;

        if (!didRollback) {
            rollback(current, updateCount);
            didRollback = true;
        }

        var type = gr.type;
        if (type == 'field_value_duration')
            setDuration(gr, gr.field, current[gr.field]);
        else if (type == 'calculation')
            scriptCalculation(gr);
        else
            gs.log('>>> skipping: ' + gr.name);
    }
}

function scriptCalculation(gr) {
    definition = gr;
    eval(gr.script);
}

function setDuration(gr, field, value) {
    var mi = new MetricInstance(gr, current);
    mi.process(field);
}

// changed fields string is a serialized ArrayList [a,b,c]
function getChangedFields() {
    var fields = new String(event.parm1);
    if (fields.length > 3) {
        fields = fields.substring(1, fields.length - 1);
        fields = GlideStringUtil.split(fields, ",");
    }
    return fields;
}

function getDefinitions() {
    var gr = new GlideRecord('metric_definition');
    gr.addActiveQuery();
    var tables = GlideDBObjectManager.getTables(current.getTableName());
    gr.addQuery('table', tables);
    gr.orderBy('order');
    gr.query();
    return gr;
}

function rollback(gr, updateCount) {
    var r = new GlideRecordRollback();
    r.toVersion(gr, updateCount);
}

 

Finally i built this Event: 

Bkimani_2-1723237594860.png

I haven't got the event to fire even once. From logs i can see the code gets stuck at the getDefinitions() function in the business rule. Can someone point me to the right direction please?

0 REPLIES 0