How to Trigger change workflow/record producer from transform script

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-04-2014 11:45 AM
We have a requirement to create a change request with workflow and approval from a transform map script.
to create the change record, we have a record producer in place. But i'm not sure how to trigger the record producer from transform script and how to ploulate theRP variables.
I tried using Catalog API as mention below but it is creating a RITM instead of change request.
var cart = new Cart(); var item = cart.addItem('sys id of record producer'); cart.setVariable(item, 'RP variable name', source.TransformMapVariableName); ..... var rc = cart.placeOrder(); gs.log(rc.number);
above code is not working, is there any other mathod to invoke change_request with workflow from a transform script ?
Pradeep Sharma can you help ?
- Labels:
-
Change Management
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-04-2014 04:59 PM
We ended up solving a similar problem by creating a Script Include which allowed us to programmatically call a Record Producer. No guarantees that it will solve your exact problem, but your problem looks very similar to the one we were trying to solve.
This is invoked with the sys_id of the Record Producer you want to call. Once the RP is created, add question/answer pairs to it with the setVariable() function. It should be pretty obvious how to use it. Using this method, you completely avoid the Cart() interface, though.
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);
targetRecord.initialize();
targetRecord.applyTemplate(this.producer.template.name);
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'
}
Thanks to Josh for the formatting hint!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-04-2014 05:00 PM
And if anyone can tell me how to include the code in the fancy code-block, I'd appreciate it.

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎11-07-2014 07:27 AM
Hi Ian,
When editing your comment, click "Use advanced editor", highlight the code block, click the ">>" in the toolbar and then select the appropriate language.
Cheers!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-04-2015 11:55 AM
Hi Ian,
I realize this is an older thread but it saved me some time today so I figured I would offer the last piece of the puzzle. The code below should either do the trick or be pretty close.
See line 45-48. Calling eval is the easiest way to handle this though if you check around the eval is evil threads there are other script evaluators in ServiceNow. The main side effect of eval is that is executes the script in the current scope, so technically the RP script could access this.rpVariables if it wanted to. But lets face it, as long as Joe User isn't creating Record Producer scripts and you have positive control over those scripts (ACLs) then eval is generally good enough.
This side effect is also our advantage as it allows us to easily expose the producer and current variables to the evaluated script. I hope this helps!
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
eval(this.producer.script + ''); // Evaluate the script
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'
}