how to create request item from script
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-27-2017 09:14 PM
I'm trying to build a background script that will create a new request item. Since there are related tables involved, what would be the correct creation sequence, e.g. which table record should be created first to be associated with the request item record? If somebody has a working code snippet or a least an idea, I would appreciate it. Tried to find a solution in the community posts but related topics are not very descriptive.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎03-21-2018 10:07 AM
Hi I have a similar question.
First link the first responder had doesn't work. Second link works but seems like it using the cart API.
I originally had found another post about how to do it with out or with the cart API. I had given the non cart API route a shot and it seems like whatever I am doing doesn't end up with the variables or workflow of the catalog item associated with the RITM.
https://community.servicenow.com/community?
id=community_question&sys_id=e6f647e5db1cdbc01dcaf3231f9619db
AND
http://www.servicenowelite.com/blog/2014/2/6/request-generation-methods
The first link I pasted here states you can get the workflow to automatically trigger as long as you first create the RITM and then go back and associate the catalog item. I tried both ways and still had the same result. Basically the Request was created and then the RITM was created and was associated with the request. The RITM was also associated with the cat item but only by the name box when looking at the RITM in the UI. Meaning I could see that the correct cat item was in the text box of the RITM BUT all the variables of the form didn't show up below in the variables tab of the RITM that should be there--they are there when I go fully through the GUI to create the RITM. And the workflow isn't there either.
I didn't try the couple extra lines of code to create the workflow and associate it with the RITM as there is a small sample of that but then I don't exactly understand some of the parameters that I would be passing to the workflow. Mainly because the example is using "current." and I'm just initially testing this via Background script run box.
Here is the code I have tried:
var catItmID = ''
var rec = new GlideRecord('sc_cat_item');
rec.addQuery('name', 'Employee Onboarding');
rec.query();
if(rec.next()){
catItmID = rec.getValue('sys_id');
}
var grRequest = new GlideRecord ("sc_request");
grRequest.initialize();
grRequest.u_requested_by = 'myusername';
grRequest.requested_for = 'myusername';
grRequest.short_description = 'test';
grRequest.description = 'test';
var requestSysId = grRequest.insert();
var grRequestItem = new GlideRecord ("sc_req_item");
grRequestItem.requested_for='myusername';
grRequestItem.short_description='test';
grRequestItem.description='test';
grRequestItem.parent = requestSysId;
grRequestItem.request = requestSysId;
grRequestItem.cat_item=catItmID; //had omited this line when I was setting it after the fact using the below commented code. has to do with the trick to get the workflow to fire off supposedly when the cat id is set after in an update...
var reqItmSysID = grRequestItem.insert();
gs.print(reqItmSysID);
//var RITMrec = new GlideRecord('sc_req_item');
// RITMrec.addQuery('sys_id', reqItmSysID);
// RITMrec.query();
// if(RITMrec.next()){
// //gs.print(rec.getValue('sys_id'));//7acce0fc4fa332c05d34fc828110c7fa
//
// RITMrec.cat_item=catItmID;
// RITMrec.update();
// gs.print(RITMrec.sys_id);
// }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-13-2021 01:13 AM
Hello Nate,
Have the same requirements. Any news on this one?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-13-2021 09:23 AM
Let me first apologize because I don't remember exactly why I was having issues. From reading my own post I guess the variables were not correctly populating. I can post the full script that I currently have and has been working for a few years now. Feel free to ask more specific questions and I might be able to help more specifically.
This is a method in an overall script include. we have another system which I send a JSON payload from and into a servicenow custom REST endpoint. The endpoint code just hands that JSON off to the script include method. the method then hands back some of the info about the created RITM.
And yes it's pretty sloppy with lots of commented out stuff etc... but it's what is working and some of the commented stuff might help to know certain things I was experimenting/testing with to figure out what was what.. who knows.
CreateNewCSR_RITM: function(jsonStr){
var newRITMSysID="";
var newRITMNum="";
var body = {};
try{
//gs.log("hasNext: " + Request.body.hasNext(), 'CSROnboarding');
var jsonObj = JSON.parse(jsonStr);
//gs.log(requestDataString,"csronboarding");
//var json = new JSON();
//var requestObj = json.decode(requestDataString);
//var parser = new JSONParser();
//var requestObj = parser.parse(Request.body.dataString);
//for (var key in jsonObj)
// gs.log("Key is: " + key + " and value is: " + jsonObj[key], "CSROnboarding");
//lookup supervisor throw error if no Supervisor
var supervisorSysID = '';
var suprec = new GlideRecord('sys_user');
suprec.addActiveQuery();
var supjsEmpID = jsonObj.supervisorEmpID;
gs.log("paddedSupID: " + this.zeroPadFront(supjsEmpID, 8),"CSROnboarding");
//var paddedSupID = jsonObj.supervisorEmpID.padStart(8, "0");
suprec.addQuery('employee_number',this.zeroPadFront(supjsEmpID, 8));
suprec.query();
var supCount = 0;
while(suprec.next()){
supCount++;
supervisorSysID = suprec.getValue('sys_id');
}
if(supCount > 1)
throw 'duplicate SupervisorRecords in ServiceNow';
if(supCount == 0)
throw 'No SupervisorRecord in ServiceNow';
gs.log('supSysID: ' + supervisorSysID, 'CSROnboarding');
var catItmID = '';
var rec = new GlideRecord('sc_cat_item');
rec.addQuery('name', 'CSR Onboarding');
//rec.addQuery('name', 'Contingent Worker Onboarding');
rec.query();
if(rec.next()){
catItmID = rec.getValue('sys_id');
}
var cart = new Cart();
// add in cart, substitute your cat item sys_id
var item = cart.addItem(catItmID);
// set requested for, substitute your requested for
//Set Variables in your Cart Item
cart.setVariable(item, 'requested_for', 'natec');
cart.setVariable(item, 'request_short_description', 'test');
cart.setVariable(item, 'request_description', 'test');
cart.setVariable(item, 'first_name',jsonObj.firstName);
cart.setVariable(item, 'last_name',jsonObj.lastName);
cart.setVariable(item, 'middle_initial',jsonObj.midInitial);
cart.setVariable(item, 'employee_id',jsonObj.EmpID);
cart.setVariable(item, 'slt_job_title',jsonObj.jobTitle);
cart.setVariable(item, 'department',jsonObj.departmentName);
cart.setVariable(item, 'cost_center_expense_code',jsonObj.costCenter);
cart.setVariable(item, 'division',jsonObj.divisionName);
cart.setVariable(item, 'location',jsonObj.locationName);
cart.setVariable(item, 'country',jsonObj.country);
cart.setVariable(item, 'start_date',jsonObj.startDate);
cart.setVariable(item, 'preferred_first_name',jsonObj.preferredName);
cart.setVariable(item, 'line_of_business',jsonObj.lob);
cart.setVariable(item, 'positionNumber',jsonObj.positionNumber);
cart.setVariable(item, 'Action', jsonObj.Action);
cart.setVariable(item, 'supervisor', supervisorSysID);
cart.setVariable(item, 'PhoneEXT', jsonObj.Phone);
cart.setVariable(item, 'tempToHire', jsonObj.tempToHire);
cart.setVariable(item, 'supervisorLevel', jsonObj.supervisorLevel);
cart.setVariable(item, 'csrbatchid',jsonObj.Batch);
//var cartmsg = "received from: " + email.origemail + "\n\n" + email.body_text;
//cart.setVariable(item,'comments',cartmsg);
var catReq = cart.placeOrder();
gs.log("cartReqItemInfo- sys_id:" + catReq.sys_id + " number:" + catReq.number, "CSROnboarding");
//newRITMSysID = catReq.sys_id;
//newRITMNum = catReq.number;
//--further get data about the created RITM
var grReqItem = new GlideRecord('sc_req_item');
grReqItem.addActiveQuery(); //just adds the isactive filter..
grReqItem.addQuery('request',catReq.getValue('sys_id'));
grReqItem.query();
if(grReqItem.next()) {
newRITMSysID = grReqItem.getValue('sys_id');
newRITMNum = grReqItem.getValue('number');
//grReqItem.assignment_group = assn_group_sid;
//grReqItem.update();
}
if(newRITMSysID == ''){
throw "No RITM seems to have been created for: " + jsonObj.firstName + " " + jsonObj.lastName;
}
}catch(ex){
gs.log('Error creating RITM see log for raw JSON passed in. Exception: ' + ex.massage,'CSROnboarding');
body.Status = "ERROR";
body.Data = ex.message;
return body; //'{"Status":"ERROR","Data":"'+ex.message+'"}';
}
body.Status = "OK";
var dataObj = {};
dataObj.RITM_SysID = newRITMSysID;
dataObj.RITM_Number = newRITMNum;
body.Data = dataObj;
return body; //'{"Status":"OK","Data":{"RITM_SysID":"'+ newRITMSysID +'","RITM_Number","'+newRITMNum+'"}}';
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎05-27-2021 04:57 AM
Thanks Nate! Appreciate this one!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎07-10-2018 02:53 PM
This is the complete solution: I used this to have one request item form generate another and assign it to a different assignment group
To generate a ticket for a request item from within a workflow
Try to remember I am not a programmer by trade, so be forgiving of poor coding practise, my strategy has always been – if it works, its good code. If you would like to improve it, please do, I would be grateful for the education.
Define the problem and the Goal:
The problem: I need to generate a ticket from inside another original ticket: The ticket that is to be generated will need to contain all the variables associated with the first ticket and will need to have the same requestor and requested_for user as found on the first ticket. The new ticket needs to be assigned to a different assignment group.
How did I achieve this.
The way I approached the problem was to borrow code from several sources and then customized it within the workflow to create the new ticket when the old ticket status was changed to closed. (I wait for the ticket to close, so that I know all the variables have been populated and can generate the new ticket using this information)
At the start of the workflow I need to gather the specific information I will need later in the workflow
So at the start I gather the details of the initial requestor and requested_for users details etc. Run the following code to gather this info and store it in the workflow scratchpad variables.
SCRIPT 1A: (load this within a script activity at the start of the workflow)
Run this script activity as the workflow starts:
// find the parent record associated with this request item and extract the users details.
var req = new GlideRecord('sc_request');
if (req.get(current.request)) {
workflow.scratchpad.u_requestor = req.u_requestor.toString();
workflow.scratchpad.u_requested_for = req.requested_for.toString();
workflow.scratchpad.opened_by = req.opened_by.toString();
gs.log(' (****) current.u_requestor.toString() sc_request ' + workflow.scratchpad.u_requestor );
gs.log(' (****) current.request.opened_by sc_request ' + workflow.scratchpad.opened_by);
gs.log(' (****) current.u_requested_for sc_request ' + workflow.scratchpad.u_requested_for );
}
//If any of the details are missing from this (above) attempt then gather information from the current sc_req_item tickets fields. In the log file you will see the (****) flag for all the sc_request data accumulated and (####) for all the sc_req_item data accumulated on this issue.
if (!workflow.scratchpad.u_requestor) {
workflow.scratchpad.u_requestor = current.u_requestor.toString();
gs.log(' (####) current.u_requestor.toString() Current rec ' + workflow.scratchpad.u_requestor );
}
if (!workflow.scratchpad.u_requested_for) {
workflow.scratchpad.u_requested_for = current.u_requested_for.toString();
gs.log(' (####) current.request.opened_by Current rec ' + workflow.scratchpad.opened_by);
}
if (!workflow.scratchpad.opened_by) {
workflow.scratchpad.opened_by = current.opened_by.toString();
gs.log(' (####) current.u_requested_for Current rec ' + workflow.scratchpad.u_requested_for );
}
//identify the currently called parent record’s sys_id and display it in the log so we can test which sc_request header is being targeted.
gs.log (' current request calling: ' + current.request);
-------------------------------------------------------------------------------------------------------------------
END SCRIPT 1A:
-------------------------------------------------------------------------------------------------------------------
SCRIPT 1B: (within a script activity (end of workflow) after all data has been loaded in the primary ticket)
=============== Create the brand new ticket record with all the old variable data loaded up.
// Load the current tickets sys_id into the scratchpad. This is the primary sc_req_item record
workflow.scratchpad.orig_sysid = current.sys_id;
gs.log(' the original sys_id is ' + workflow.scratchpad.orig_sysid);
// Create the new sc_req_item through the cart and add the current data from the original request form.
var cartId = GlideGuid.generate(null);
var cart = new Cart(cartId);
// identify the cart item to use with the sys_id of a new form you created which can be a duplicate of the original. It is different from the // original in that it is using a new workflow. We don’t want this form generating yet another endless series of new request items.
var item = cart.addItem('10840dc44f7913004bf3eefe0310c71e');
// Add the individual variables taken from the original form and this populates the new form cart.setVariable(item,'cg_include_jde',current.variables.cg_include_jde);
cart.setVariable(item,'cg_label',current.variables.cg_label);
cart.setVariable(item,'cg_industrial',current.variables.cg_industrial);
cart.setVariable(item,'cg_municipal',current.variables.cg_municipal);
cart.setVariable(item,'cg_system_comp',current.variables.cg_system_comp);
//Customer Group variable set information
cart.setVariable(item,'gs_customer_trading',current.variables.gs_customer_trading);
cart.setVariable(item,'gs_customer_legal_entity_name',current.variables.gs_customer_legal_entity_name);
cart.setVariable(item,'gs_customer_abn',current.variables.gs_customer_abn);
cart.setVariable(item,'gs_number_cust_site_acct',current.variables.gs_number_cust_site_acct);
cart.setVariable(item,'gs_user_identifier',current.variables.gs_user_identifier);
cart.setVariable(item,'gs_cust_local_national',current.variables.gs_cust_local_national);
// GroupCode variable set Details
cart.setVariable(item,'gc_group_code',current.variables.gc_group_code);
cart.setVariable(item,'gc_group_code_description',current.variables.gc_group_code_description);
var rc = cart.placeOrder();
// find the new tickets sys id and then apply this to temp scratchpad variable for later use
workflow.scratchpad.new_sysid = rc.sys_id;
// attempt to store the details you captured in the start of this workflow i.e. from SCRIPT 1A
rc.u_opened_by = workflow.scratchpad.opened_by;
rc.u_requester = workflow.scratchpad.opened_by;
rc.update();
gs.log(' New record number is =: ' + rc.number);
// need to ensure you are picking up the new sys_id of the new record
var chk2 = workflow.scratchpad.new_sysid;
gs.log(' the New record sys id is ' + chk2);
// check you have the correct sys_id by searching for the record and testing it is the only one.
var ritm = new GlideRecord('sc_req_item');
ritm.addQuery('request',chk2);
ritm.query();
while (ritm.next()) {
// retrieve the single sc_req_item record in the parent record)
workflow.scratchpad.screqitemx=ritm.sys_id;
gs.log(' The new record created by the automatic system is: ' + workflow.scratchpad.screqitemx );
}
// load the new screq_itm rec and process the data
var headerreq=''; // this will be used soon to get the sys_id of the header record of the new sc_req_item record as we want to be able to update this with the new user details from the original ticket.
var screqitem = new GlideRecord('sc_req_item');
screqitem.addQuery('sys_id',workflow.scratchpad.screqitemx);
screqitem.query();
while (screqitem.next()) {
screqitem.assignment_group = '57e4b633ed9bd10006532768e1b2cd72';
screqitem.description = 'Update JDE with VRP Group Code and Code Description as shown';
gs.log(' The final assignment hit as ' + workflow.scratchpad.screqitemx);
screqitem.opened_by = workflow.scratchpad.opened_by;
screqitem.u_requestor = workflow.scratchpad.u_requestor;
screqitem.u_requested_for = workflow.scratchpad.u_requested_for;
// As we are inside the new sc_req_items record we can populate the sys_id of the new header record
headerreq = screqitem.request; // load the new sc_request record header into the variable system
screqitem.update();
}
// This section (below) should call the new tickets header record so that we can update this with the correct calling requestor and requested_for users details
var req = new GlideRecord('sc_request');
if (req.get(headerreq)){ //get the parent request record i.e. use the new header var and pop new sc_request header record.
req.u_requestor = workflow.scratchpad.u_requestor;
req.requested_for = workflow.scratchpad.u_requested_for;
req.opened_by = workflow.scratchpad.opened_by;
req.update();
}
// provide log details of the header records sys_id so we can compare with he log from earlier call.
gs.log(' current request from main record: ' + current.request);
// Getattachmnt. Load all the attachments to the new ticket as well.
var grAttachments = new GlideRecord('sys_attachment');
grAttachments.addQuery('table_sys_id', workflow.scratchpad.orig_sysid);
grAttachments.query();
var vAttachmentSys_id = '';
// Loop through all attachments.
while (grAttachments.next()) {
// Prep the primary attachment record.
grAttachments.table_name = 'sc_req_item';
grAttachments.table_sys_id = workflow.scratchpad.newrec_sysid;
//gs.log(' rcsysid ::: ' + workflow.scratchpad.newrec_sysid);
// Find all secondary attachment records.
var grAttachmentDocuments = new GlideRecord('sys_attachment_doc');
grAttachmentDocuments.addQuery('sys_attachment', grAttachments.sys_id);
grAttachmentDocuments.query();
// Duplicate the primary attachment record.
vAttachmentSys_id = grAttachments.insert();
// Loop through all secondary attachment records.
while (grAttachmentDocuments.next()) {
// Duplicate the current secondary attachment record.
grAttachmentDocuments.sys_attachment = vAttachmentSys_id;
grAttachmentDocuments.insert();
//gs.log(' process record attachments :::' + vAttachmentSys_id );
}
}
==========================================end ======================================
This is working and creates the new tickets with all the details of the first, assigns the requestor and requested_for user from the old (original) ticket. If you make changes or corrections to this - let me know. its always good to hear from the experts.
Regards TK.