How-To Build a custom application step by step
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-06-2007 08:44 AM
NOTE: I need to uload and link the images for this article. It is going to take some time. bare with me.
First: None of this would have been possible without the help of the service-now team members. Thanks for pushing me in the right direction! More then once.
This is a great case study on how to create your own custom application in service-now.com from start to finish. The techniques discussed in this article are used across the board to create new applications. We are currently on our 5th custom application and have proceeded through each one just like this.
Creating the new tables for the new application
First you need to create 2 new tables. Go to Tables & Columns to create the new table space. We called ours RMA because it is a replacement for our current Return Merchandise Authorization process. The second table is called Equipment Requests. Let me first explain the differences. The RMA table will be used for the movement of equipment that is already in place and needs repair or is being retired or moved from its current location. The Equipment Request application is used for the initial movement of a new piece of equipment. (i.e. We have a new piece of equipment that has been ordered and received. Now it needs to go to its new home.)
You need to go to System definition and then click the link for Tables & Columns

Place the information in the appropriate boxes at the bottom of the form.
Label = The name that will appear at the top of lists.
Table name = The actual table name. Follow the naming convention of the other tables
Extends base table = you can extend a table that has already been created sharing the characteristics it has in common with other tables or you can start a table from scratch by selecting none. We selected task as the new table would need to interact with the task table much like incident, problem, and change do.
Create new application = This is where you decide if you want a new application to appear in the navigation pain and you also decide on the name you want to give the application.
Create new module = This is where you decide where you want a new module to be located. It defaults to — The New One — Meaning it will create the new module in the new application you have specified above.
Create the new RMA table.

Label: RMA
Table name: rma
Extends base table: task
Create new application: Yes named Asset Movement Mgmt
Create new module: Yes in application — The New One —
Click Do It! YOU CAN NOT UNDO A TABLE ONCE YOU HAVE CREATED IT!!!
Hit F5 to refresh the screen.
When you create the second table you want to uncheck the "create new application" box as it will have already been created from the first table you created.
Repeat process for the second application.

Label: Equipment Request
Table name: equip_request
Extends base table: task
Create new application: NO and no name
Create new module: Yes in application Asset Movement Mgmt.
After you have created the 2 applications you should end up with something that looks like this in the navigation pain on the left.

And the applications will look like this. An almost blank slate that we will have to improve upon to reach the final result.
Rreferance:
Wiki that explains the creation of a new table.
http://wiki.service-now.com/index.php?title=How_to_create_your_own_tables
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-06-2007 08:44 AM
Ok now we have our new tables so it is time to add some new fields to the forms.
On both the RMA and the Equipment Request forms there were fields that the system put on the form when it was created. Some of the fields we will use and some we will not. Simply remove the ones we do not need. The fields we used and created are listed in the section below.
On the RMA form we needed to create and add the following fields. The fields that are blue and italicized are referenced from another table. There is a link to a Wiki on how to use fields from other forms in the reference area at the end of this section. Link to the finished form. Image 6
Caller ID: Image RMAdict1
RMA from Location: Image RMAdict2
Affected asset: Image RMAdict3
Affected asset — Locaiton:
Affected asset — Status
Affected asset — In RMA process
Affected asset — Name
Affected asset — Operational Status
Need replacement: Image RMAdict4
Receive date: Image RMAdict5
Received by: Image RMAdict6
Loc: Image RMAdict7
Incident number: Image RMAdict8
Alert: Image RMAdict9 the full element name is u_replacement_asset_text it gets cut of in the picture.
Replacement asset: Image RMAdict10
Replacement asset — Location
Replacement asset — Status
Replacement asset — Name
Shipped Date: Image RMAdict11
Shipping method: Image RMAdict12
Tracking number: Image RMAdict13
These fields are already supplied they just need to be added to the RMA form or left on the form if they were placed on the form when the system created the module.
Number
Short Description
Description
Last Updated
Last Updated by
Opened
Opened by
Task Activity
On the Equipment Request form you will need to add the following fields. Link to the finished form. Image 7
Asset to ship: Image EquipReqDict1
Asset to ship — Name
Asset to ship — Location
Asset to ship — Model Id
Asset to ship — Model number
Asset to ship — Status
Ship date: Image EquipReqDict2 the full element name is u_equip_request_shipped_date it gets cut off in the picture.
Tracking number: Image EquipReqDict3 the full element name is u_equip_request_tracking_numbe it gets cut of in the picture.
These fields are already supplied they just need to be added to the RMA form or left on the form if they were placed on the form when the system created the module.
Number
Location
Priority
Created
Created by
We also added 2 fields to the incident form to help out with the automation that will be discussed later. You will also need to have the configuration item field on the incident form. Make sure that configuration item is dependent on location and has that reference_qual: u_in_rma_process=false . This is so that you can only pull equipment from the proper location and that it is not in the RMA process already. Link to the finished form. Image 8
Location Alert: Image IncDict1
Needs Replacement: Image IncDict2
Configuration Item field Image with changes. Image IncDict2
Last we added 1 field to all the CMDB tables. Image 9
In RMA process: Img CMDBdict1
You also need to make sure you have the status and operations status on the CMDB tables.
References:
Wiki that helps demystify the customization of a form if you don't already know how to do it.
http://wiki.service-now.com/index.php?title=Personalizing_Forms
Wiki on how to add fields to a form.
http://wiki.service-now.com/index.php?title=Adding_Fields
Wiki on how to add fields from another table
http://wiki.service-now.com/index.php?title=Personalize_a_form_with_a_field_from_another_table
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-06-2007 08:45 AM
We need to make the number fields work like they do on the Incident, Problem, Change, and just about every other table in the system. To achieve this you may need to contact service-now and ask them to complete this step or have them turn on the Number Maintenance module in the System Definition application.
Go to system definition and click on the Number Maintenance application.

Click new to add the new number file. Image 11
Category = the name of the table you are creating the numbers for.
Number = the sequence of numbers you would like the numbers to start at. You can start at whatever numbers you would like.
Prefix = the letters you would like to have in front of the numbers you are creating. This can be whatever you would like. Try and keep it short though. 3 or 4 characters
Ok now that you know what you are looking at we need to create our new number systems for the RMA form.
Image 12
Category = rma
Number = 10,000
Prefix = RMA
Click Submit
Now when you create a new RMA the number field on the form will show as RMA10000 and then RMA10001 and so on.
Repeat the process from above. Click new and enter
Image 13
Cetegory = equip_request
Number = 5,000
Prefix = 1SHP Remember prefix it can be what ever you want. Our old process for moving new equipment was called 1 ships. So I added it in as a nostalgia point. You can never forget where you came from!
Click Submit
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-06-2007 08:47 AM
So we have our basic tables and, and our new fields on the tables. There is a lot of functionality at this stage that a lot of people could use but the reason we created this new application was to automate the process of moving equipment from one location to another. The automation is to help take out the human error and also to allow the equipment administrators to concentrate on the assets and not spending all day looking for an asset in the system so that they can move the equipment manually.
There are several scripts that are being used against both tables. Each one plays a role to help guide the user down the correct path and in turn the information on the form will be correct so that when the user submits the form the corresponding assets will be moved to the correct locations. Both client scripts and Business rules will be discussed in this section.
Let's start off with automation that was added to the incident form. The script below adds a button to the Incident form that will automatically create an RMA based on the configuration item that is selected.
Business Rule: Create RMA
BR1
**Script Code**
var vNeedRep = current.u_need_replacement;
var vConfigItem = current.cmdb_ci;
if (vNeedRep == "" || vConfigItem == "") {
gs.addInfoMessage("You need to select yes or no in the Needs Replacement field or pick a Configuration Item.");
var mySysID = current.update();
action.setRedirectURL(current);
} else {
var rma = new GlideRecord("rma");
rma.short_description = current.short_description;
rma.u_affected_asset = current.cmdb_ci;
rma.u_rma_caller_id = current.caller_id;
rma.u_rma_location = current.location;
gs.log("Just Before GR");
var affa = new GlideRecord("cmdb_ci");
affa.addQuery('sys_id', current.cmdb_ci.sys_id);
affa.query();
if (affa.next()) {
affa.u_in_rma_process = true;
affa.operational_status = 2;
affa.update();
gs.log("inside affa");
}
//rma.u_affected_asset.u_in_rma_process = true;
rma.u_original_location = current.cmdb_ci.location;
rma.u_need_replacement = current.u_need_replacement;
rma.u_incident_id = current.sys_id.toString();
var sysID = rma.insert();
var mySysID = current.update();
gs.addInfoMessage("RMA " + rma.number + " created");
action.setRedirectURL(rma);
action.setReturnURL(current);
rma.u_incident_id = current.sys_id;
}
NOTE: All CLIENT SCRIPTS are disabled for admin. I like disabling them so that the admins have full control over the form. If you want to disable that functionality remove the && !isAdmin from the if statements.
This script is used to force the users to fill in a location on the incident form so that the proper configuration items can be pulled. Remember my scripts are disabled for admin.
Client Script: BCF Incident disable config item
CS1
**Script Code**
//Script created by Jeff Bloyer
//February 10 2007
// This script is used to force the users to fill in a location on the incident form so that the proper configuration items can be pulled.
function onChange(control, oldValue, newValue) {
//variables that check the users roles
var isAdmin = g_user.hasRole('admin');
//variables that check the element ID. These are used to disable the fields in the script.
var idLocation = document.getElementById('incident.location');
var idConfigItem = document.getElementById('incident.cmdb_ci');
//variables that check the value in the specific files listed in the arguments
var vLocation = g_form.getValue('location');
//Hide the fields that should not be filled in unless affected asset is filled in.
if (newValue == "" && !isAdmin) {
g_form.setVisible('cmdb_ci', false);
g_form.setVisible('u_need_replacement', false);
g_form.setVisible('u_pick_location_alert', true);
} if (newValue != "" && !isAdmin) {
g_form.setVisible('cmdb_ci', true);
g_form.setVisible('u_need_replacement', true);
g_form.setVisible('u_pick_location_alert', false);
}
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎06-06-2007 08:49 AM
Ok now onto the scripts to automate the RMA form.
All of the scripts below work in conjunction with each other to achieve a proper work flow for the movement of an asset.
On the RMA form when someone enters the received date this script will adjust the location, operational status, and install status of the affected asset in the CMDB. CMDB record will reflect the automated changes that were specified by the asset team. In this when an Affected asset is received and the received date is entered on the RMA form the Affected Assets Location changes to our repair location, the operational status moves to Pending repair, and the Install status moves to Non Operational.
Client Script: BCF RMA change receive date CS2
**Script Code**
//Script created by Jeff Bloyer and support form the Service-now teams
//Apr 16 2007
//This script changes the affected asset location, operational status, and install status when a receive date is filled in on the form.
function onChange(control, oldValue, newValue) {
//Variables that get control so that values can be set without proper roles.
var gcInstalStat = g_form.getControl('u_affected_asset.install_status');
var gcOperStat = g_form.getControl('u_affected_asset.operational_status');
var gcLocation = g_form.getControl('u_affected_asset.location');
//checks the old value against the new value
if (oldValue != newValue) {
//simple test alert for testing purposes. This is disabled when not testing
//alert ("running a test script");
//sets the install status, operational status, and in rma process values
g_form.setValue('u_affected_asset.install_status', '5', 'Pending Repair');
g_form.setValue('u_affected_asset.operational_status', '3', 'Repair in Progress');
g_form.setValue('u_affected_asset.u_in_rma_process', false);
//check to make sure affected value is not null or empty
if (g_form.getValue('u_affected_asset') != null && g_form.getValue('u_affected_asset') != "") {
//this portion of the script gets the location code for To Be Repaired – EWP4287 and then sets that value in the Affected Asset Location field
var table_name = 'cmn_location';
var display_value = 'To Be Repaired - EWP4287';
var script = "GetIDValue('" + table_name + "','" + display_value + "')";
var answer = AJAXEvaluateSynchronously(script);
g_form.setValue('u_affected_asset.location', answer, display_value);
//this sets the received by field to mandatory
g_form.setMandatory('u_received_by', true);
}
}
}
On the RMA form when someone enters the ship date this script will take the location code and writes it to the location of the replacement asset. The location code is the location the Affected asset is coming from. This change is represented on the RMA form but in essence it is changing the data in the CMDB record. It also changes the status to installed.
Client Script: BCF RMA change ship date CS3
**Script Code**
//Script created by Jeff Bloyer and support form the Service-now teams
//Apr 16 2007
//This script takes the location code in the original location field and sets the location code of the replacement asset to match once a ship date is filled in on the RMA form.
function onChange(control, oldValue, newValue) {
//checks for a change in the value
if (oldValue != newValue) {
var table_name = 'cmn_location';
//gets control of the fields
var gcRepAssetLoc = g_form.getControl('u_replacement_asset.location');
var gcRepAssetInstStat = g_form.getControl('u_replacement_asset.install_status');
//gets control of the field and then gets the value
var gcOrigValue = g_form.getControl('u_original_location');
var vOrigValue = g_form.getValue('u_original_location');
//simple test alert to view values. This is disabled when not testing.
//alert(vOrigValue);
//takes the location code and retrieves the display value for the code.
var sysid = vOrigValue;
var script = "GetLocDisplayValue('" + table_name + "','" + sysid + "')";
var answer = AJAXEvaluateSynchronously(script);
//simple test alert to view values. This is disabled when not testing.
//alert(answer);
//sets the location code and display value to the replacement asset location
g_form.setValue('u_replacement_asset.location', vOrigValue, answer);
//sets the install status to the specified value
g_form.setValue('u_replacement_asset.install_status', '1');
}
}
This script was created so that it would write the location of the Affected asset once an RMA was submitted. This is the same location code that is important in the script above. While most RMA's will be created from an incident using the create RMA button script there will be times that equipment administrators will issue an RMA directly from the RMA form. When the RMA is submitted we need to grab the code of the original location and store it for use when we ship out the replacement asset.
Client Script: BCF RMA copy location onsubmit CS4
**Script Code**
//Script created by Jeff Bloyer and support form the Service-now teams
//Apr 16 2007
//This script copy's the location of the affected asset on submission and stores it in the original location field.
function onSubmit() {
//variables that get control of fileds and then get the value
var gcAffAssetLoc = g_form.getControl('u_affected_asset.location');
var vAffAssetLoc = g_form.getValue('u_affected_asset.location');
var gcOrigLoc = g_form.getControl('u_original_location');
var vOrigLoc = g_form.getValue('u_original_location');
var gcInRMAproc = g_form.getControl('u_affected_asset.u_in_rma_process');
var vInRMAproc = g_form.getValue('u_affected_asset.u_in_rma_process');
//retrieves the sysid for location
var table_name = 'cmn_location';
var display_value = vAffAssetLoc;
var script = "GetIDValue('" + table_name + "','" + display_value + "')";
var answer = AJAXEvaluateSynchronously(script);
//checks to see if Origional location is empty
if (vOrigLoc == "") {
//test alert used for testing. disabled when not testing.
//alert ("in rma is = " + vInRMAproc);
//sets the location code from the affected asset and saves it in original location field
g_form.setValue('u_original_location', answer);
//sets the rma process field to true so that the asset can not be rma'ed again.
g_form.setValue('u_affected_asset.u_in_rma_process', "true");
}
}