Order Guide Archives - ServiceNow Guru https://servicenowguru.com/tag/order-guide/ ServiceNow Consulting Scripting Administration Development Tue, 28 May 2024 20:19:03 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.2 https://servicenowguru.com/wp-content/uploads/2024/05/cropped-SNGuru-Icon-32x32.png Order Guide Archives - ServiceNow Guru https://servicenowguru.com/tag/order-guide/ 32 32 Exporting Service Catalog Items in One Step https://servicenowguru.com/system-definition/exporting-service-catalog-items-step/ https://servicenowguru.com/system-definition/exporting-service-catalog-items-step/#comments Thu, 26 Jan 2012 17:54:23 +0000 https://servicenowguru.wpengine.com/?p=4277 This post comes in response to a request I received from some of my colleagues at ServiceNow to be able to export a catalog item definition to XML and transport it between instances. I’ve written before about how you can quckly export and import data between ServiceNow instances using the XML export/import context menus. While

The post Exporting Service Catalog Items in One Step appeared first on ServiceNow Guru.

]]>
This post comes in response to a request I received from some of my colleagues at ServiceNow to be able to export a catalog item definition to XML and transport it between instances. I’ve written before about how you can quckly export and import data between ServiceNow instances using the XML export/import context menus. While this works great for a lot of situations, it doesn’t work so great for data that resides in multiple tables, but really makes sense to be exported as a single unit. The components that make up a Catalog item definition are actually stored in over 21 separate tables! It is possible to export a catalog item but you have to do at least 21 separate exports to do it. In this post, I’ll show you how you can set up a UI action to export information from all 21+ tables that make up a catalog item definition…in one click!

Export Full Catalog Item

21+ tables worth of information…in ONE click!

The catalog item export will work for any table extending the ‘sc_cat_item’ table…catalog items, record producers, content items, and order guides! It DOES NOT export associated workflows, delivery plans, or wizard definitions. Workflows can be exported by following the instructions in the Graphical Workflow Export article. The following table information is included.

  • Variables (including question choices)
  • Variable sets (including associated variables, client scripts, and UI policies
  • Client scripts
  • UI policies
  • Additional categories
  • Approved by user and group
  • Available for/Not Available for lists
  • Order guide rule base

The first step is to set up a ‘Processor’ record to handle the export. ServiceNow actually has some built-in code to handle exports like this. You just have to know how to leverage it. Here’s how you would set up a processor for the catalog item export.

‘ExportCatalogItem’ Processor
Name: ExportCatalogItem
Type: Script
Path: export_catalog_item
Script:

(function process(g_request, g_response, g_processor) {
var sysid = g_request.getParameter('sysparm_sys_id');
gs.log('** Exporting Catalog Item ' + sysid);//Name all the related lists
var exporter = new ExportWithRelatedLists('sc_cat_item', sysid);
exporter.addRelatedList('item_option_new', 'cat_item');
exporter.addRelatedList('catalog_script_client', 'cat_item');
exporter.addRelatedList('catalog_ui_policy', 'catalog_item');
exporter.addRelatedList('sc_cat_item_category', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_catalog', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_user_criteria_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_user_criteria_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_group_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_group_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_company_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_company_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_dept_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_dept_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_location_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_location_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_user_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_user_no_mtom', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_app_group', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_app_user', 'sc_cat_item');
exporter.addRelatedList('sc_cat_item_guide_items', 'guide');
exporter.addRelatedList('pc_vendor_cat_item', 'product_catalog_item');

var catalogID = '';
var categoryID = '';
var vsrelID = '';
var vsID = '';
var vID = '';
var qcID = '';
var uipID = '';
var actID = '';
var csID = '';

//Query for Catalogs
var catalog = new GlideRecord('sc_cat_item_catalog');
catalog.addQuery('sc_cat_item', sysid);
catalog.query();
while(catalog.next()){
//Get Catalog IDs
catalogID = catalogID + ',' + catalog.sc_catalog.sys_id.toString();
}

//Query for Categories
var category = new GlideRecord('sc_cat_item_category');
category.addQuery('sc_cat_item', sysid);
category.query();
while(category.next()){
//Get Category IDs
categoryID = categoryID + ',' + category.sc_category.sys_id.toString();
}

//Query for variables to get question choices
var item = new GlideRecord('item_option_new');
item.addQuery('cat_item', sysid);
item.query();
while(item.next()){
//Query for question choices
var qc = new GlideRecord('question_choice');
qc.addQuery('question', item.sys_id.toString());
qc.query();
while(qc.next()){
//Add the variable question sys_id to the variable question string
qcID = qcID + ',' + qc.sys_id.toString();
}
}

//Query for ui catalog ui policies to get policy actions
var catpol = new GlideRecord('catalog_ui_policy');
catpol.addQuery('catalog_item', sysid);
catpol.query();
while(catpol.next()){
//Query for ui policy actions
var uipact = new GlideRecord('catalog_ui_policy_action');
uipact.addQuery('ui_policy', catpol.sys_id.toString());
uipact.query();
while(uipact.next()){
//Add the ui policy action sys_id to the ui policy action string
actID = actID + ',' + uipact.sys_id.toString();
}
}

//Query for variable set relationships
var vsrel = new GlideRecord('io_set_item');
vsrel.addQuery('sc_cat_item', sysid);
vsrel.query();
while(vsrel.next()){
//Add the item set relationship sys_id to the item set string
vsrelID = vsrelID + ',' + vsrel.sys_id.toString();
//Get the variable set
var vs = vsrel.variable_set.getRefRecord();
if(vs){
//Add the variable set sys_id to the variable set string
vsID = vsID + ',' + vs.sys_id.toString();
//Query for variables in the set
var v = new GlideRecord('item_option_new');
v.addQuery('variable_set', vs.sys_id);
v.query();
while(v.next()){
//Add the variable sys_id to the variable string
vID = vID + ',' + v.sys_id.toString();
//Query for variable question choices
var vqc = new GlideRecord('question_choice');
vqc.addQuery('question', v.sys_id.toString());
vqc.query();
while(vqc.next()){
//Add the variable question sys_id to the variable question string
qcID = qcID + ',' + vqc.sys_id.toString();
}
}

//Query for ui policies in the set
var uip = new GlideRecord('catalog_ui_policy');
uip.addQuery('variable_set', vs.sys_id.toString());
uip.query();
while(uip.next()){
//Add the ui policy sys_id to the ui policy string
uipID = uipID + ',' + uip.sys_id.toString();
//Query for ui policy actions
var uipa = new GlideRecord('catalog_ui_policy_action');
uipa.addQuery('ui_policy', uip.sys_id.toString());
uipa.query();
while(uipa.next()){
//Add the ui policy action sys_id to the ui policy action string
actID = actID + ',' + uipa.sys_id.toString();
}
}

//Query for client scripts in the set
var cs = new GlideRecord('catalog_script_client');
cs.addQuery('variable_set', vs.sys_id.toString());
cs.query();
while(cs.next()){
//Add the client script sys_id to the client script string
csID = csID + ',' + cs.sys_id.toString();
}
}
}

exporter.addQuerySet('sc_catalog', 'sys_idIN' + catalogID);
exporter.addQuerySet('sc_category', 'sys_idIN' + categoryID);
exporter.addQuerySet('io_set_item', 'sys_idIN' + vsrelID);
exporter.addQuerySet('item_option_new_set', 'sys_idIN' + vsID);
exporter.addQuerySet('item_option_new', 'sys_idIN' + vID);
exporter.addQuerySet('question_choice', 'sys_idIN' + qcID);
exporter.addQuerySet('catalog_ui_policy', 'sys_idIN' + uipID);
exporter.addQuerySet('catalog_ui_policy_action', 'sys_idIN' + actID);
exporter.addQuerySet('catalog_script_client', 'sys_idIN' + csID);
exporter.exportRecords(g_response);
})(g_request, g_response, g_processor);

Once you have your processor set up, you just need to call it. The processor above is called by its path name ‘export_catalog_item’ followed by ‘.do’. It also needs to know what to export so you need to pass it the sys_id of the top-level record that you want to export…in this case, the sys_id of the ‘Catalog item’ record.

‘Export Catalog Item’ UI Action
Name: Export Catalog Item
Table: Catalog Item (sc_cat_item)
Order: 200
Form link: True
Show insert: False
Show update: True
Client True
Hint: Export catalog item definition to .xml file
Onclick callExportCatalogItem();
Condition: gs.hasRole(“admin”)
Script:

function callExportCatalogItem() {
var url = new GlideURL('export_catalog_item.do');
url.addParam('sysparm_sys_id', gel("sys_uniqueValue").value);
var frame = top.gsft_main;
if (!frame){
frame = top;
}frame.location = url.getURL();
}

Once you’re done with this, you should have an ‘Export Catalog Item’ UI action context menu item on your ‘Catalog Item’ forms that you can use to transport catalog items, record producers, and order guides in the event that they don’t get captured in an update set.

The post Exporting Service Catalog Items in One Step appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/exporting-service-catalog-items-step/feed/ 44
Control the Execution Order of Request Items in an Order Guide https://servicenowguru.com/system-definition/order-request-items-order-guide/ https://servicenowguru.com/system-definition/order-request-items-order-guide/#comments Tue, 23 Aug 2011 12:43:18 +0000 https://servicenowguru.wpengine.com/?p=3952 Lately I’ve been doing some service catalog work for a couple of clients and I’ve come across a requirement that I really haven’t had to address before. The requirement deals with order guides…specifically with the ability to control the execution order of individual items within an order guide. You’re probably aware that ServiceNow provides complete

The post Control the Execution Order of Request Items in an Order Guide appeared first on ServiceNow Guru.

]]>
Lately I’ve been doing some service catalog work for a couple of clients and I’ve come across a requirement that I really haven’t had to address before. The requirement deals with order guides…specifically with the ability to control the execution order of individual items within an order guide. You’re probably aware that ServiceNow provides complete control over the ordering of tasks within a catalog item, but what do you do with an order guide that needs to have one item complete before the next 2 items can start? There’s not a simple way to control this behavior by default so I came up with a way and I’ll share it here.

Initial setup

All of this depends on having the ability to identify whether or not an order guide is associated with an item that has been ordered, and which order guide that is. As such, your first step will be to make sure that you are recording the order guide used against the parent request record. This setup is not provided by default but you can add it by following the instructions in this article.

NOTE: This is recorded for you automatically in the Helsinki release and beyond! The instructions below reflect these changes as of the Helsinki release.

Establishing an execution order

Once you’ve validated that the order guide is being populated correctly you’re ready to set up the execution order for your items within that order guide. The solution is actually pretty simple and only requires 2 pieces, both of which are implemented in the workflow for the respective items within an order guide.

Example:
In order to illustrate this setup, I’ll use a simple example. Let’s say that you have an order guide for new hires that includes 2 items; ‘Computer Workstation’ and ‘Computer Software’. Both of these items need to be ordered and delivered as part of the new hire process, but they need to be delivered in a specific order. The ‘Computer Software’ item cannot be started until the ‘Computer Workstation’ item has finished because we need to have a workstation to be able to install the software.

The first step is to modify the graphical workflow associated with item 1 (the ‘Computer Workstation’ catalog item). The workflow should run through the same process whether or not the item is ordered as part of an order guide, but at some point in the workflow (probably right before the end) we need to check if the item is associated with an order guide and then tell the next item to start. The next item in this case is ‘Computer Software’.

We don’t have direct access to the next item, but we can easily set up a ‘Run script’ workflow activity to query for that item and set a value there telling the item that it can start. I’ve found that the simplest way of doing this is to set the ‘State’ field on the next request item record to ‘Work in Progress’. The script below can be used in your ‘Run script’ activity in your workflow. Just replace the name of the ‘Computer Software’ item below with the name of the item in your system.

‘Start next item’ Run script workflow activity
Name: Start next item
Script:

//If item is part of an order guide then start next item(s)
if(!current.order_guide.nil()){ //Change to 'current.request.u_order_guide' for pre-Helsinki
//Start the 'Computer Software' item next
itemStart('Computer Software');
}function itemStart(nextItemName){
//Query for the item that should start next
var item = new GlideRecord('sc_req_item');
item.addQuery('request', current.request);
item.addQuery('cat_item.name', nextItemName);
item.query();
while(item.next()){
//Set the item to 'Work in Progress' to initiate the item workflow (requires 'Wait for' activity in item workflow)
item.state = 2;
item.update();
}
}

 

This script works great, but it’s only part of the puzzle! Unless you tell item 2 (Computer Software) to wait for item 1 (Computer Workstation) then your script isn’t going to work the way you need it to. So, the second configuration change you’ll need to make is to add a ‘Wait for’ activity to the graphical workflow associated with item 2 (Computer Software). The ‘Wait for’ activity placement should probably be the first activity in the item 2 workflow, but will depend on your specific workflow. It should only apply if an order guide is associated with the parent request and the state is ‘Work in Progress.

Order Guide Wait For Activity

If you’ve followed the instructions above correctly, you should now be able to order your order guide item and execute the items in the order you’ve specified in the workflows. You can handle any order guide execution order scenario by repeating the same steps in the workflow for each item. If you have multiple items that need to start when item 1 is finished, then simply add those items to the script from item 1 and add the wait for condition to items 2, 3, 4, etc…

Bonus! Copying variable values from one item to another

Because your items are associated under a single order guide, it might also be necessary to pass variable values from one item to another. In order to do this, you’ll need to make sure that each item sharing variable values this way has an identically-named variable to place the value in. Once you’ve got that you could execute the following script inside a workflow ‘Run script’ activity.

copyVariables();

function copyVariables(){
//Copy the matching variables from this item to the other item(s) in this request
//Query the item option table for item variables
var rec = new GlideRecord('sc_item_option_mtom');
rec.addQuery('request_item', current.sys_id);
rec.query();
while(rec.next()){
//Query for the same variable associated with the parent Request's items
var itemVars = new GlideRecord('sc_item_option_mtom');
itemVars.addQuery('request_item', '!=', current.sys_id);
itemVars.addQuery('request_item.request', current.request);
itemVars.addQuery('sc_item_option.item_option_new.name', rec.sc_item_option.item_option_new.name.toString());
itemVars.query();

//If we find a matching variable in another item update its value
while(itemVars.next()){
//Get the variable value record
var itemVar = new GlideRecord('sc_item_option');
itemVar.get(itemVars.sc_item_option);
itemVar.value = rec.sc_item_option.value.toString();
itemVar.update();
}
}
}

The post Control the Execution Order of Request Items in an Order Guide appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/order-request-items-order-guide/feed/ 15
Populate Order Guide on Request Ticket https://servicenowguru.com/system-definition/populate-order-guide-request-ticket/ https://servicenowguru.com/system-definition/populate-order-guide-request-ticket/#comments Thu, 24 Feb 2011 15:25:46 +0000 https://servicenowguru.wpengine.com/?p=3396 UPDATE: As of the Helsinki ServiceNow release, this is tracked for you automatically in a new ‘Order Guide’ field on the ‘Requested Item’ table! This solution should be discontinued in Helsinki releases and beyond. Order guides are a service catalog concept that allow you to set up an initial form to ask the user certain

The post Populate Order Guide on Request Ticket appeared first on ServiceNow Guru.

]]>
UPDATE: As of the Helsinki ServiceNow release, this is tracked for you automatically in a new ‘Order Guide’ field on the ‘Requested Item’ table! This solution should be discontinued in Helsinki releases and beyond.

Order guides are a service catalog concept that allow you to set up an initial form to ask the user certain questions in order to determine a collection of catalog items they need to order. The classic use case for an order guide is the ‘New Employee Hire’ item that ServiceNow provides in the out-of-box demo data. While order guides are really a front-end routing concept, it can sometimes be useful to report on requests that were generated for a particular order guide. This functionality doesn’t exist out-of-box in ServiceNow, but it is very easy to add. Here’s a good tip that I recently learned from Sean Grison and Valor Poland about how to populate the order guide used to generate a particular request.

While this solution gets you as close as possible to populating the correct order guide used to generate a request, you may still notice some false positives due to system behavior we can’t control. Any time people click on an order guide item in the catalog (even if they don’t end up completing the order guide), the order guide is populated on the cart and will be populated on the next request. Another issue is that people can work through an order guide and then delete certain contents of the request on the confirmation screen, and then go back to the catalog and add more items unrelated to the order guide. Unfortunately, there’s not any way to guarantee that the order guide will be populated correctly 100% of the time because of these factors.

The script below mitigates some of these issues by checking to make sure that at least one of the items from the order guide rule base is included in the order if we are populating the Order guide field on the request. It also does a second check to verify that any order guide rule base entry with NO condition (meaning it always ends up being added to the order guide) MUST be included in the order.

Even with these additional checks in place, the system behavior might still result in requests where somebody clicked on an order guide, then ordered one of the items in the guide as a standalone item instead. The best way to guard against this is to make sure you have at least one item with no conditions in the rule base, ensuring that it will always have to be part of the order if we’re going to populate an order guide.

Only three steps are necessary to record the order guide used to generate a request…

  1. Create a new reference field called ‘Order guide’ on the ‘Request (sc_request)’ table. The field needs to reference the ‘Order guide (sc_cat_item_guide)’ table. You may also choose to secure write access to this field using an ACL since it really shouldn’t need to be changed by any user.
  2. Create a new business rule on the ‘Request (sc_request)’ table with the following settings…
    ‘Populate Order Guide’ Business Rule
    Name: Populate Order Guide
    When: Before
    Insert: True
    Script:

    var c = new GlideRecord('sc_cart');
    c.get('user', gs.getUserID());
    if(c.current_guide){
       var isOrderGuide = true;
       var foundItemCount = 0;
       //Query the order guide rule base
       var og = new GlideRecord('sc_cat_item_guide_items');
       og.addQuery('guide', c.current_guide);
       og.query();
       while(og.next()){
          var mustHave = false;
          var foundItem = false;
          //If the condition is empty then item must be ordered
          if(og.condition.nil()){
             mustHave = true;
          }
          //Check to see if the rule matches at least one item in the cart
          var itm = new GlideRecord('sc_cart_item');
          itm.addQuery('cart', c.sys_id);
          itm.addQuery('cat_item', og.item.sys_id.toString());
          itm.query();
          if(itm.hasNext()){
             foundItem = true;
             foundItemCount++;
          } 
          if(mustHave && !foundItem){
             //Do not update order guide
             isOrderGuide = false;
             break;
          }
       }
       if(isOrderGuide && foundItemCount > 0){
          //If actual order guide items are included populate the order guide field
          current.u_order_guide = c.current_guide;
       }
    }
    
  3. Set up a ‘Write’ ACL on your new ‘Order guide’ field to restrict access to the field. This field should only be modified by the system as part of the ordering process so you should set up an ACL to limit those permissions. The simplest way to do this is to set up a write ACL for ‘sc_request.u_order_guide’ with the ‘nobody’ role and un-check the ‘Admin override’ checkbox.

Now when users order an item using a record producer, the record producer will be referenced in the ‘Order guide’ field you created on the request table!

Knowing the order guide used to generate a request allows you to do all sorts of cool things including…

  • Reporting against the request table to see how often each order guide is used
  • Controlling the execution order of requested items within an order guide
  • Using the ‘Order guide’ field value as a key to separate workflow logic for an item that can be ordered as a standalone item or as part of an order guide

Request Order Guide

The post Populate Order Guide on Request Ticket appeared first on ServiceNow Guru.

]]>
https://servicenowguru.com/system-definition/populate-order-guide-request-ticket/feed/ 35