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.

How to initialize standard change via UI action using a standard change template ...

Zod
Giga Guru

Hi,

I need to initiate a standard change via a template from an UI script, but failed so far.

NOT talking about form templates! Talking about standard change templates used to create standard changes from predefined & approved templates.

Any quick help on this?

Thank you!

1 ACCEPTED SOLUTION

Here is the Script Include (may be a bit easier to read here).
And as you can see, different variables on an RP can be called using:

var r = new global.RBA_Base_RecordProducer('54654654654654');
r.setVariable('description','This will be added to Description.');
r.submit();

var RBA_Base_RecordProducer = Class.create();
RBA_Base_RecordProducer.prototype = {
	initialize: function (producerSysId) {
		this.producerSysId = producerSysId;
		this.producer = this.getProducer(producerSysId);
		this.targetTable = this.producer.table_name;
		this.userVariables = {};
		this.rpVariables = this.prepRecordProducerVariables();
		gs.print("producerSysId: " + producerSysId);
		gs.print("target table: " + this.targetTable);
	},
	getProducer: function (producerSysId) {
		var gr = new GlideRecord("sc_cat_item_producer");
		if (gr.get(producerSysId)) {
			gs.print("Yep, we found the RP: " + gr.name);
			return gr;
		}
		return null;
	},
	setVariable: function (name, value) {
		this.userVariables[name] = value;
	},
	setVariables: function (variableObject) {
		this.userVariables = variableObject;
	},
	submit: function () {
		var targetRecord = new GlideRecord(this.targetTable),
		producer,
		current;
		targetRecord.initialize();
		targetRecord.applyTemplate(this.producer.template.name);
		/* This should allow executing the Producer Script. */
		producer = this.userVariables; // Record Producer scripts have access to a producer variable that functions as a variable map like userVariables
		current = targetRecord; // Record Producer scripts have access to the target record as a current variable
		var scriptEval = new GlideScopedEvaluator(); // Evaluate the script
		scriptEval.putVariable('current', current);
		scriptEval.putVariable('producer', producer);
		scriptEval.evaluateScript(this.producer, 'script', null);

		var v;
		// Set mapped fields on target record
		for (v in this.rpVariables) {
			if (this.rpVariables[v].mapToField == true) {
				targetRecord.setValue(this.rpVariables[v].field, this.userVariables[v] || "");
			}
		}
		var targetSysId = targetRecord.insert();
		// if there's no target sys_id, don't create any question_answer entries
		if (targetSysId) {
			// One more loop - insert variables in question_answer table
			var qa;
			for (v in this.rpVariables) {
				qa = new GlideRecord("question_answer");
				qa.initialize();
				qa.question = this.rpVariables[v].sysId;
				qa.order = this.rpVariables[v].order;
				qa.table_name = this.targetTable;
				qa.table_sys_id = targetSysId;
				qa.value = this.userVariables[v];
				qa.insert();
			}
		}
		return targetSysId;
	},
	prepRecordProducerVariables: function () {
		var variables = {};
		var grItemOption = new GlideRecord("item_option_new");
		grItemOption.addQuery("cat_item", this.producerSysId);
		grItemOption.query();
		while (grItemOption.next()) {
			var obj = {};
			var name = grItemOption.getValue("name");
			obj.field = grItemOption.getValue("field");
			obj.mapToField = grItemOption.getValue("map_to_field");
			obj.sysId = grItemOption.getValue("sys_id");
			obj.order = grItemOption.getValue("order");
			variables[name] = obj;
		}
		return variables;
	},
	type: 'RBA_Base_RecordProducer'
};

View solution in original post

8 REPLIES 8

Here is the Script Include (may be a bit easier to read here).
And as you can see, different variables on an RP can be called using:

var r = new global.RBA_Base_RecordProducer('54654654654654');
r.setVariable('description','This will be added to Description.');
r.submit();

var RBA_Base_RecordProducer = Class.create();
RBA_Base_RecordProducer.prototype = {
	initialize: function (producerSysId) {
		this.producerSysId = producerSysId;
		this.producer = this.getProducer(producerSysId);
		this.targetTable = this.producer.table_name;
		this.userVariables = {};
		this.rpVariables = this.prepRecordProducerVariables();
		gs.print("producerSysId: " + producerSysId);
		gs.print("target table: " + this.targetTable);
	},
	getProducer: function (producerSysId) {
		var gr = new GlideRecord("sc_cat_item_producer");
		if (gr.get(producerSysId)) {
			gs.print("Yep, we found the RP: " + gr.name);
			return gr;
		}
		return null;
	},
	setVariable: function (name, value) {
		this.userVariables[name] = value;
	},
	setVariables: function (variableObject) {
		this.userVariables = variableObject;
	},
	submit: function () {
		var targetRecord = new GlideRecord(this.targetTable),
		producer,
		current;
		targetRecord.initialize();
		targetRecord.applyTemplate(this.producer.template.name);
		/* This should allow executing the Producer Script. */
		producer = this.userVariables; // Record Producer scripts have access to a producer variable that functions as a variable map like userVariables
		current = targetRecord; // Record Producer scripts have access to the target record as a current variable
		var scriptEval = new GlideScopedEvaluator(); // Evaluate the script
		scriptEval.putVariable('current', current);
		scriptEval.putVariable('producer', producer);
		scriptEval.evaluateScript(this.producer, 'script', null);

		var v;
		// Set mapped fields on target record
		for (v in this.rpVariables) {
			if (this.rpVariables[v].mapToField == true) {
				targetRecord.setValue(this.rpVariables[v].field, this.userVariables[v] || "");
			}
		}
		var targetSysId = targetRecord.insert();
		// if there's no target sys_id, don't create any question_answer entries
		if (targetSysId) {
			// One more loop - insert variables in question_answer table
			var qa;
			for (v in this.rpVariables) {
				qa = new GlideRecord("question_answer");
				qa.initialize();
				qa.question = this.rpVariables[v].sysId;
				qa.order = this.rpVariables[v].order;
				qa.table_name = this.targetTable;
				qa.table_sys_id = targetSysId;
				qa.value = this.userVariables[v];
				qa.insert();
			}
		}
		return targetSysId;
	},
	prepRecordProducerVariables: function () {
		var variables = {};
		var grItemOption = new GlideRecord("item_option_new");
		grItemOption.addQuery("cat_item", this.producerSysId);
		grItemOption.query();
		while (grItemOption.next()) {
			var obj = {};
			var name = grItemOption.getValue("name");
			obj.field = grItemOption.getValue("field");
			obj.mapToField = grItemOption.getValue("map_to_field");
			obj.sysId = grItemOption.getValue("sys_id");
			obj.order = grItemOption.getValue("order");
			variables[name] = obj;
		}
		return variables;
	},
	type: 'RBA_Base_RecordProducer'
};

Thank you!!!

This is working perfectly for me to create standard changes via a business rule. However the variables aren't passing correctly.. i'm using your r.setVariable('description','This will be added to Description.'); format. Any ideas?

Hi Felladin,

I hope everything is going well at your end.

I looked at this solution and it is very similar to what i need. however, i am having some issues and i was wondering if you could provide some guidance.

i do have an inbound action that creates a record producer (using your script), the problem is that i dont understand how to populate fields in the form nor variables in the form.

I remove the line that calls a template. how do i pass values to variables and to fields in the form?

regards,

max