ServiceNow

var payload = (new global.JSON().encode(request.body.data));
(async () => {
  let threshold = 1000; // only show load times for widgets higher than this value (in milliseconds)
  var wa = $("div [widget='widget']").css("border", "1px solid red").css("padding-top", "20px").css("position", "relative")
  let widgetTable = [];
  let wmk = [];
  for (var i = 0; i < wa.length; i++) {
    let widgetEntry = {};
    $0 = wa[i]
    let scope = $($0).scope();
    try{
      var widget = scope.widget;
    } catch(e){
      console.error(e);
      continue;
    }
    var timing = 0;
    let elem = $("<div style='position: absolute; top: 1px; left: 1px'><a target='_blank' href='/$sp.do?id=widget_editor&sys_id=" + widget.sys_id + "'> " + widget.name + "</a>&nbsp;&nbsp;</div>");
    var printScope = $("<a href='javascript:void(0);'>Print scope </a>").on('click', function() {
      console.info(scope);
    });
    elem.append(printScope);
    widgetEntry.name = widget.name;
    widgetEntry.rectangle = widget.rectangle_id || 'undefined';
    widgetEntry.sys_id = widget.sys_id;
    let id = scope.widget.rectangle_id + "_" + scope.$id

    // if this is not a nested widget, go ahead and refresh it.
    if (!scope.$parent || !scope.$parent.widget) {
      var widget_name = widget.name;
      var t0 = performance.now();
      await scope.server.refresh();
      var t1 = performance.now();
      timing = "<div style='float:right;color:red;' id='" + id + "'> Load Time: " + parseInt(t1 - t0) + " ms.</div>";
      widgetEntry.load_time_ms = parseInt(t1 - t0) || 0;
      elem.append(timing);
    }
    // add a button to refresh manually.
    var loadTime = $("<button style='border-radius: 50%;'> ⟳ </button>").on('click', function() {
      var widget_name = scope.widget.name;
      let id = scope.widget.rectangle_id + "_" + scope.$id
      var t0 = performance.now();
      scope.server.refresh().then(() => {
        var t1 = performance.now();
        timing = "<div style='float:right;color:red;' id='" + id + "'> Load Time: " + parseInt(t1 - t0) + " ms.</div>";
        widgetEntry.load_time_ms = parseInt(t1 - t0) || 0;
        if ($('#' + id)) {
          $('#' + id).remove();
        }

        elem.append(timing);
        console.log("Call to " + widget_name + " took " + (t1 - t0) + " ms.");
      });
    });

    elem.append(loadTime);
    $($0).append(elem);
    widgetTable.push(widgetEntry);
  }
  widgetTable.sort((a, b) => (a.load_time_ms > b.load_time_ms) ? 1 : -1);
  var slow = widgetTable.filter((e, i, w) => {
    return e.load_time_ms >= threshold;
  });

  let mkdn = `|Name|sys_id|rectangle_id|Load Time Ms|
|:---:|:---:|:---:|:---:|
${slow.map((widgetEntry, i, widgetTable) => {
return `|${widgetEntry.name}|${widgetEntry.sys_id}|${widgetEntry.rectangle}|${widgetEntry.load_time_ms}|`;
}).join("\n")}`;
  var doCopy = function() {
    var el = document.createElement('textarea');
    el.value = mkdn;
    el.setAttribute('readonly', '');
    el.style = {
      position: 'absolute',
      left: '-9999px'
    };
    document.body.appendChild(el);
    el.select();
    document.execCommand('copy');
    document.body.removeChild(el);
  }
  var elem = `<div style="float: right;
z-index: 1;
position: relative;
left: -50%; /* or right 50% */
text-align: left;
padding:10px">
<h2>${(slow.length > 0)?"Slow Widgets:" : "No Slow Widgets Found!"}</h2>
<table style="padding:3px; display:${(slow.length > 0)?"table":"none"}">
<tr><td style="padding:3px;" >Name</td><td style="padding:3px;">sys_id</td><td style="padding:3px;">rectangle id</td><td style="padding:3px;">load time ms</td></tr>
${slow.map((widgetEntry, i, widgetTable) => {
return `<tr><td style="padding:3px;">${widgetEntry.name}</td><td style="padding:3px;">${widgetEntry.sys_id}</td><td style="padding:3px;">${widgetEntry.rectangle}</td><td style="padding:3px;">${widgetEntry.load_time_ms}</td></tr>`;
}).join(" ")}
</table>
<button onClick=${doCopy()} style="display:${(slow.length > 0)?"table":"none"}">Copy Markdown</button>
</div>`;
  $('body').append(elem);
})();
this.XMLHelper = (new x_hca2_mh_intg.MHXMLUtils());

var responseBody = response.getBody();
var prettyXML = this.XMLHelper.prettifyXML(responseBody);


var MHXMLUtils = Class.create();
MHXMLUtils.prototype = {

    initialize: function() {
    },

    parseXMLNode: function (xml, node) {
        var xmlDoc = new XMLDocument2();
        xmlDoc.parseXML(xml);
        return (xmlDoc.getNodeText(node));
    },

    prettifyXML: function (xmlString) {
        var formatted = '';
        var reg = /(>)(<)(/)/g;
        xmlString = xmlString.replace(reg, '$1\r\n$2$3');
        var pad = 0;
        var nodes = xmlString.split('\r\n');
        nodes.forEach(function(node, index) {
            var indent = 0;
            if (node.match( /.+</\w[^>]>$/ ))
                indent = 0;
            else if (node.match( /^</\w/ )) {
                if (pad != 0) {
                    pad -= 1;
                }
            } else if (node.match( /^<\w[^>][^/]>.$/ ))
                indent = 1;
            else
                indent = 0;

            var padding = '';
            for (var i = 0; i < pad; i++)
                padding += '    ';

            formatted += padding + node + '\r\n';
            pad += indent;
        });
        return formatted;
    },

    type: 'MHXMLUtils'
};
// opens a new u_error_reporting record from an sc_task record
function openOverlay(overlayID, overlayTitle, iframeURI, height, width) {
	// Instantiate the GlideOverlay
	// Note: GlideOverlay extends GlideBox, which contains the close() method
	var overlayWindow = new GlideOverlay({
		                                     id:             overlayID,
		                                     title:          overlayTitle,
		                                     iframe:         iframeURI,
		                                     allowOverflowX: true,
		                                     closeOnEscape:  true,
		                                     height:         height,
		                                     width:          width
	                                     });
	overlayWindow.render();
	// Get the element containing the iframe document.
	var overlayDocument = overlayWindow._box.getElementsByClassName('gb_iframe')[0];
	// Add a listener for when the document in the iframe finishes loading, and run some code when it does.
	// Without this, our code would not have a "document" in which to execute, and wouldn't do anything.
	overlayDocument.onload = function() {
		// Get all of the "buttons" (button UI actions) in the document in the iframe -- that is, on the form in the GlideOverlay.
		var overlayG_form = overlayDocument.contentWindow.g_form;
		var buttonsInOverlayWindow = overlayDocument.contentWindow.document.getElementsByClassName('form_action_button');
		// Iterate over each UI action button on the form.
		for (var i in buttonsInOverlayWindow) {
			// Standard check to make sure that the element (still) exists.
			if (buttonsInOverlayWindow.hasOwnProperty(i)) {
				// Adding an event listener to each UI action button. This executes a function when the button is clicked.
				buttonsInOverlayWindow[i].addEventListener('click', function() {
					// When a UI action button is clicked, we first call setTimeout. We pass in only a very small timeout timer, since
					// even a timeout of 0 will cause the code passed into the setTimeout function to execute after all other scripts
					// have finished running as a result of that click (such as the form being submitted).
					setTimeout(function() {
						// Finally, after all other code has executed as a result of the user clicking the UI action button, we call
						// a function to check if any mandatory fields have not been filled out. If we're good, then we close the overlay.
						if (!(overlayG_form.getMissingFields().length > 0)) {
							overlayWindow.close();
							console.warn(!(overlayG_form.getMissingFields().length > 0) + 'CLOSING');
						} else {
							console.warn(!(overlayG_form.getMissingFields().length > 0) + 'NOT CLOSING');
						}
					}, 500);
				});
			}
		}
	};
}
var gr = new GlideRecord('sc_item_option_mtom');
gr.addQuery('sc_item_option.item_option_new.name','item_name');
gr.addQuery('sc_item_option.value','item_value');
gr.query();

while (gr.next()) {
       gs.addInfoMessage(gr.request_item.number);
}

User Object Cheat Sheet
N

o matter what system you’re working in, it is always critical to be able to identify information about the user who is accessing that system. Being able to identify who the user is, what their groups and/or roles are, and what other attributes their user record has are all important pieces of information that allow you to provide that user with a good experience (without giving them information they don’t need to have or shouldn’t have). ServiceNow gives administrators some pretty simple ways to identify this information in the form of a couple of user objects and corresponding methods. This article describes the functions and methods you can use to get information about the users accessing your system.



GlideSystem User Object

The GlideSystem (gs) user object is designed to be used in any server-side JavaScript (Business rules, UI Actions, System security, etc.). The following table shows how to use this object and its corresponding functions and methods.

Function/Method	Return Value	Usage
gs.getUser()	Returns a reference to the user object for the currently logged-in user.	var userObject = gs.getUser();
gs.getUserByID()	Returns a reference to the user object for the user ID (or sys_id) provided.	var userObject = gs.getUser().getUserByID('employee');
gs.getUserName()	Returns the User ID (user_name) for the currently logged-in user.
e.g. 'employee'	var user_name = gs.getUserName();
gs.getUserDisplayName()	Returns the display value for the currently logged-in user.
e.g. 'Joe Employee'	var userDisplay = gs.getUserDisplayName();
gs.getUserID()	Returns the sys_id string value for the currently logged-in user.	var userID = gs.getUserID();
getFirstName()	Returns the first name of the currently logged-in user.	var firstName = gs.getUser().getFirstName();
getLastName()	Returns the last name of the currently logged-in user.	var lastName = gs.getUser().getLastName();
getEmail()	Returns the email address of the currently logged-in user.	var email = gs.getUser().getEmail();
getDepartmentID()	Returns the department sys_id of the currently logged-in user.	var deptID = gs.getUser().getDepartmentID();
getCompanyID()	Returns the company sys_id of the currently logged-in user.	var companyID = gs.getUser().getCompanyID();
getCompanyRecord()	Returns the company GlideRecord of the currently logged-in user.	var company = gs.getUser().getCompanyRecord();
getLanguage()	Returns the language of the currently logged-in user.	var language = gs.getUser().getLanguage();
getLocation()	Returns the location of the currently logged-in user.	var location = gs.getUser().getLocation();
getDomainID()	Returns the domain sys_id of the currently logged-in user (only used for instances using domain separation).	var domainID = gs.getUser().getDomainID();
getDomainDisplayValue()	Returns the domain display value of the currently logged-in user (only used for instances using domain separation).	var domainName = gs.getUser().getDomainDisplayValue();
getManagerID()	Returns the manager sys_id of the currently logged-in user.	var managerID = gs.getUser().getManagerID();
getMyGroups()	Returns a list of all groups that the currently logged-in user is a member of.	var groups = gs.getUser().getMyGroups();
isMemberOf()	Returns true if the user is a member of the given group, false otherwise.	Takes either a group sys_id or a group name as an argument.

if(gs.getUser().isMemberOf(current.assignment_group)){
//Do something...
}

var isMember = gs.getUser().isMemberOf('Hardware');

To do this for a user that isn't the currently logged-in user...

var user = 'admin';
var group = "Hardware";
if (gs.getUser().getUserByID(user).isMemberOf(group)){
gs.log( gr.user_name + " is a member of " + group);
}

else{
gs.log( gr.user_name + " is NOT a member of " + group);
}
gs.hasRole()	Returns true if the user has the given role, false otherwise.	if(gs.hasRole('itil')){ //Do something... }
gs.hasRole()	Returns true if the user has one of the given roles, false otherwise.	if(gs.hasRole('itil,admin')){
//If user has 'itil' OR 'admin' role then Do something...
}
hasRoles()	Returns true if the user has any roles at all, false if the user has no role (i.e. an ess user).	if(!gs.getUser().hasRoles()){
//User is an ess user...
}
It is also very simple to get user information even if the attribute you want to retrieve is not listed above by using a ‘gs.getUser().getRecord()’ call as shown here…

//This script gets the user's title
gs.getUser().getRecord().getValue('title');


g_user User Object

The g_user object can be used only in UI policies and Client scripts. Contrary to its naming, it is not truly a user object. g_user is actually just a handful of cached user properties that are accessible to client-side JavaScript. This eliminates the need for most GlideRecord queries from the client to get user information (which can incur a fairly significant performance hit if not used judiciously).

g_user Property or Method	Return value
g_user.userName	User name of the current user e.g. employee
g_user.firstName	First name of the current user e.g. Joe
g_user.lastName	Last name of the current user e.g. Employee
g_user.userID	sys_id of the current user e.g. 681ccaf9c0a8016400b98a06818d57c7
g_user.hasRole()	True if the current user has the role specified, false otherwise. ALWAYS returns true if the user has the 'admin' role.

Usage: g_user.hasRole('itil')
g_user.hasRoleExactly()	True if the current user has the exact role specified, false otherwise, regardless of 'admin' role.

Usage: g_user.hasRoleExactly('itil')
g_user.hasRoles()	True if the current user has at least one role specified, false otherwise.

Usage: g_user.hasRoles('itil','admin')
It is often necessary to determine if a user is a member of a given group from the client as well. Although there is no convenience method for determining this from the client, you can get the information by performing a GlideRecord query. Here’s an example…

//Check to see if assigned to is a member of selected group
var grpName = 'YOURGROUPNAMEHERE';
var usrID = g_form.userID; //Get current user ID
var grp = new GlideRecord('sys_user_grmember');
grp.addQuery('group.name', grpName);
grp.addQuery('user', usrID);
grp.query(groupMemberCallback);
   
function groupMemberCallback(grp){
//If user is a member of selected group
    if(grp.next()){
        //Do something
        alert('Is a member');
    }
    else{
        alert('Is not a member');
    }
}
To get any additional information about the currently logged-in user from a client-script or UI policy, you need to use a GlideRecord query. If at all possible, you should use a server-side technique described above since GlideRecord queries can have performance implications when initiated from a client script. For the situations where there’s no way around it, you could use a script similar to the one shown below to query from the client for more information about the currently logged in user.

//This script gets the user's title
var gr = new GlideRecord('sys_user');
gr.get(g_user.userID);
var title = gr.title;
alert(title);


Useful Scripts

There are quite a few documented examples of some common uses of these script methods. These scripts can be found on the ServiceNow wiki.
Fear Not; There is a Better Workaround
...and I do mean workaround. This is by no means to be considered a fix. The secret is in the browser cookies. We know that many plugins contain UI Scripts. These applications are updated from time to time (including the UI Scripts) and that works fine. What's the difference? Activating a plugin triggers a forced cache update for the users' browsers. The difference is that updating a UI Script doesn't trigger this. Not even a cache.do triggers it. It simply forces the server to update cache. Installing/updating plugins seems to be the sole trigger that forces the browser to ask the server for updated cache for UI Scripts.

So how do you force this cache update?
The check for building new cache in this instance is controlled by a cookie on the client browser that ServiceNow creates. The cookie is controlled by a property in ServiceNow called glide.lastupdate. To force this update to happen, all you have to do is set that property to a newer dateTime than it currently is (e.g. the current timestamp). You can do this manually, but that can also be a form of kicking the can down the road. You will be back here soon. At Walmart, we wrote a Business Rule to update this whenever a ui_script is updated:

(function executeRule(current, previous /*null when async*/) {
	
	var gdt = new Date();
	var gdtString = gdt.toString().replace(/ /g,'_').replace(/:/g,'_');
	var timeZone = gdtString.replace(/.*[(](.*)[)].*/,'$1');
	var dateFinal = gdtString.slice(0,25) + timeZone;
	gs.addInfoMessage('System Property glide.lastplugin updated. ' + 
					  'Please be sure to push this updated property with the rest of your code. ' +
					  'This will ensure that the JavaScript cache is updated on the client browser.');
	gs.setProperty('glide.lastplugin', dateFinal);
	
})(current, previous);
I have attached an export of this business rule for any who are interested. The info message reminds developers to ensure this updated property is included in their update set, since business rules are not triggered on update commit.


I have seen few questions wherein users require a VIP Icon for catalog variable when the user is a VIP user..

Use case: Consider you have a Variable which refers to "sys_user" table. When the Request Item form loads or Catalog Task form loads and if the User variable holds a VIP User then vip icon should be visible besides the variable.

Approach:

1) Create an onLoad Catalog Client Script which is set to "Applies on Requested Items" and "Applies on Catalog Tasks"

2) Use Script mentioned below; ensure you give question value in script inside the Contains filter and not the name. Using g_form.getControl() doesn't work on sc_req_item and sc_task tables.

3) Ensure Isolate Script field is set to False for the above Catalog Client Script; this field can be edited from List

Script:

function onLoad() {
	//Type appropriate comment here, and begin script below
	var user = g_form.getReference('user', callBackMethod);
}

function callBackMethod(user){

	if(user.vip.toString() == 'true'){
		var variableQuestionValue = 'User';
		$j("<img src='images/icons/vip.gif'>" ).insertAfter("span.sn-tooltip-basic:contains(" + variableQuestionValue + ")");
	}
}
Screenshots:

1) Variable Question with Value as User being used inside the script



2) Catalog Client Script: Isolate Script -> False



3) RITM Form when User is VIP showing the icon



4) TASK Form when User is VIP showing the icon



5) User "Abel Tuter" is VIP User



Note: If you would like to test this; try changing the value to a user who is not VIP and the icon should not show up

Additionally you can also highlight the background in red/orange color as below

g_form.getDisplayBox('user').style.backgroundColor =  'orange';
You can also show the text in red color as below

g_form.getDisplayBox('user').style.color= 'red';
Thanks for reading the blog and do provide your inputs/suggestions if any.
 /* SW • Added 01/12/2021
    ** This was added to check for any non-interactive users (service accounts used for integrations)
    ** to ensure they only have access to attachments in which the record it is attached to is the
    ** same company as the service account.
    */
    
    // Remove Prefix
    var tableName = current.table_name;
    if (tableName.startsWith("invisible."))
        tableName = tableName.substring(10);
    else if (tableName.startsWith("ZZ_YY"))
        tableName = tableName.substring(5);

    var parentRecord = new GlideRecord(tableName);
    parentRecord.setWorkflow(false);
    parentRecord.get(current.table_sys_id)

    if (!gs.getSession().isInteractive())
        return verifyReadAccessFromNonInteractiveUsers(parentRecord);

    function verifyReadAccessFromNonInteractiveUsers(parentRecord) {
      if ((gs.hasRole("snc_platform_rest_api_access")) && (parentRecord.canRead()) && (parentRecord.company == gs.getUser().getCompanyID()))
        return true;
      return false;
    }

/*
Client callable script include used for filtering sys_user lists
to identify duplication email users
name: duplicateEmail
active: true
client callabe: true
*/
function duplicateEmail() {
    var xx = new GlideAggregate('sys_user');
    xx.addAggregate('COUNT', 'email');
    xx.addHaving('COUNT', 'email', '>', '1');
    xx.query();
    var answer = new Array();
    while (xx.next()) {
        answer.push(xx.getValue('email'));
    }
    return answer;
}
var O365OutageSync = Class.create(); 

O365OutageSync.prototype = { 

    initialize: function() { 

    }, 

    refreshO365OutageRecords: function(token){ 

        var date_now = gs.nowDateTime(); 

        var parser = new JSONParser(); 

        var json_responseBody = "failed to load"; 

        try {  

            var r = new sn_ws.RESTMessageV2('Microsoft Azure', 'Get Service Status'); 

            r.setStringParameterNoEscape('TenantID', gs.getProperty('AzureAccessToken.TenantID')); 

            r.setStringParameterNoEscape('Token', token); 

            var response = r.execute(); 

            var httpStatus = response.getStatusCode(); 

            if(httpStatus == '200'){ 

                //Success 

                var str_responseBody = response.getBody(); 

                json_responseBody = parser.parse(str_responseBody); 

            } else { 

                gs.log("Error requesting O365 Service Status.  httpStatus:" + httpStatus); 

            } 

        } catch(ex) { 

            var message = ex.message; 

            gs.log("Error requesting O365 Service Status.  Error Message:" + message); 

        } 

         

        if(json_responseBody != "failed to load"){ 

            for (s = 0; s < json_responseBody.value.length; s++) { 

                //gs.log(json_responseBody.value[s].WorkloadDisplayName + " : " + json_responseBody.value[s].StatusDisplayName); 

                var str_bs_sys_id = ""; 

                 

                //***Create Business Service Record if it does not already exist*** 

                var gr_bs = new GlideRecord('cmdb_ci_service'); 

                gr_bs.addQuery('name', 'O365 - ' + json_responseBody.value[s].WorkloadDisplayName); 

                gr_bs.query(); 

                if(gr_bs.next()){ 

                    str_bs_sys_id = gr_bs.sys_id + ""; 

                } else if (json_responseBody.value[s].IncidentIds.length > 0){ 

                    //Doesnt exist, create it 

                    var gr_new_bs = new GlideRecord('cmdb_ci_service'); 

                    gr_new_bs.initialize(); 

                    gr_new_bs.setValue('name', 'O365 - ' + json_responseBody.value[s].WorkloadDisplayName); 

                    gr_new_bs.setValue('used_for', 'Production'); 

                    str_bs_sys_id = gr_new_bs.insert(); 

                } 

                 

                 

                //***Create Outages for open incidents*** 

                var arr_openOutages = []; 

                for (i = 0; i < json_responseBody.value[s].IncidentIds.length; i++) { 

                    arr_openOutages.push(json_responseBody.value[s].IncidentIds[i]); 

                    var gr_existing_outage = new GlideRecord('cmdb_ci_outage'); 

                    gr_existing_outage.addQuery('u_number',json_responseBody.value[s].IncidentIds[i]); 

                    gr_existing_outage.query(); 

                    if(gr_existing_outage.next()){ 

                        //Set Outage Status for existing Outage Record 

                        switch(json_responseBody.value[s].Status){ 

                            case 'ServiceDegradation': 

                                gr_existing_outage.setValue('type', 'degradation'); 

                                break; 

                            case 'ServiceInterruption': 

                                gr_existing_outage.setValue('type', 'outage'); 

                                break; 

                        } 

                        gr_existing_outage.update(); 

                         

                         

                    } else { 

                        var gr_new_outage = new GlideRecord('cmdb_ci_outage'); 

                        gr_new_outage.initialize(); 

                        gr_new_outage.setValue('u_number', json_responseBody.value[s].IncidentIds[i]); 

                        gr_new_outage.setValue('cmdb_ci', str_bs_sys_id); 

                        gr_new_outage.begin = date_now; 

                         

                        //Set Outage Status for existing Outage Record 

                        switch(json_responseBody.value[s].Status){ 

                            case 'Investigating': 

                                gr_new_outage.setValue('type', 'degradation'); 

                                break; 

                            case 'ServiceDegradation': 

                                gr_new_outage.setValue('type', 'degradation'); 

                                break; 

                            case 'ServiceInterruption': 

                                gr_new_outage.setValue('type', 'outage'); 

                                break; 

                            case 'RestoringService': 

                                gr_new_outage.setValue('type', 'degradation'); 

                                break; 

                            case 'ExtendedRecovery': 

                                gr_new_outage.setValue('type', 'degradation'); 

                                break; 

                            case 'VerifyingService': 

                                gr_new_outage.setValue('type', 'degradation'); 

                                break; 

                        } 

                        gr_new_outage.insert(); 

                    } 

                } 

                     

                     

                //***End Outages for resolved incidents*** 

                //gs.log("Closing incidents for :" + json_responseBody.value[s].WorkloadDisplayName +", cisysid:" + str_bs_sys_id +  "Status:" + json_responseBody.value[s].Status + ", open outages:" + arr_openOutages.join(',')); 

                if(str_bs_sys_id.length > 0){ 

                    var arr_closedcodes = ['ServiceRestored', 'PostIncidentReportPublished', 'ServiceOperational', 'FalsePositive']; 

                    var arrUtil = new ArrayUtil(); 

                    var gr_active_outage = new GlideRecord('cmdb_ci_outage'); 

                    gr_active_outage.addQuery('cmdb_ci', str_bs_sys_id); 

                    gr_active_outage.addNullQuery('end'); 

                    gr_active_outage.query(); 

                    while(gr_active_outage.next()){ 

                        if((arrUtil.indexOf(arr_closedcodes, json_responseBody.value[s].Status) >= 0)||(arrUtil.indexOf(arr_openOutages, gr_active_outage.u_number) < 0)){ 

                            //Service is fully operational. 

                            //Close out all active outages 

                            gr_active_outage.end = date_now; 

                            gr_active_outage.update(); 

                        } else { 

                            

                        } 

                    } 

                } 

            } 

        }         

    }, 

    refreshO365OutageMessages: function(token){ 

        //***Pull Down Outage Messages*** 

        var parser = new JSONParser(); 

        var json_responseBody = "failed to load"; 

        try {  

            var r = new sn_ws.RESTMessageV2('Microsoft Azure', 'Get All Messages'); 

            r.setStringParameterNoEscape('TenantID', gs.getProperty('AzureAccessToken.TenantID')); 

            r.setStringParameterNoEscape('Token', token); 

            var response = r.execute(); 

            var httpStatus = response.getStatusCode(); 

            if(httpStatus == '200'){ 

                //Success 

                var str_responseBody = response.getBody(); 

                json_responseBody = parser.parse(str_responseBody); 

            } else { 

                gs.log("Error requesting O365 Service Messages.  httpStatus:" + httpStatus); 

            } 

        } catch(ex) { 

            var message = ex.message; 

            gs.log("Error requesting O365 Service Messages.  Error Message:" + message); 

        } 

        if(json_responseBody != "failed to load"){ 

            for (i = 0; i < json_responseBody.value.length; i++) { 

                if(json_responseBody.value[i].Messages.length > 0){ 

                    this.updateOutage(json_responseBody.value[i].Id, json_responseBody.value[i].Messages[json_responseBody.value[i].Messages.length-1].MessageText + "<BR><BR><u>Last Updated: " + json_responseBody.value[i].Messages[json_responseBody.value[i].Messages.length-1].PublishedTime + "</u>"); 

                } else { 

                    this.updateOutage(json_responseBody.value[i].Id, json_responseBody.value[i].ImpactDescription); 

                } 

            } 

        } 

    }, 

    updateOutage: function(str_number, str_details){ 

        var gr_outage = new GlideRecord('cmdb_ci_outage'); 

        gr_outage.addQuery('u_number', str_number); 

        gr_outage.query(); 

        if(gr_outage.next()){ 

            gr_outage.setValue('details', str_details); 

            gr_outage.update(); 

        } 

    }, 

    getAzureAPIAccessToken: function(){ 

        var token = ""; 

        try {  

            var r = new sn_ws.RESTMessageV2('Microsoft Azure', 'Get Access Token'); 

            r.setStringParameterNoEscape('ClientSecret', gs.getProperty('AzureAccessToken.ClientSecret')); 

            r.setStringParameterNoEscape('ClientID', gs.getProperty('AzureAccessToken.ClientID')); 

            r.setStringParameterNoEscape('TenantID', gs.getProperty('AzureAccessToken.TenantID')); 

            var response = r.execute(); 

            var httpStatus = response.getStatusCode(); 

            if(httpStatus == '200'){ 

                //Success 

                var str_responseBody = response.getBody(); 

                var parser = new JSONParser(); 

                var json_responseBody = parser.parse(str_responseBody); 

                token = json_responseBody.access_token; 

            } else { 

                gs.log("Error requesting Azure API Token.  httpStatus:" + httpStatus); 

            } 

        } catch(ex) { 

            var message = ex.message; 

            gs.log("Error requesting Azure API Token.  Error Message:" + message); 

        } 

             

        return token; 

    },     

    type: ‘O365OutageSync’ 

}; 
/* This will come in the body at XML but the header will be text/plain, which is why  
all this is happening manually to get this read from the stream.  
*/  
var reqHeaders = request.headers;
gs.info("CPSNS: reqHeaders content-type" + reqHeaders['content-type']);
if (reqHeaders['content-type'] == "text/plain; charset=UTF-8") {
    var stream = request.body.dataStream;
    var reader = new GlideTextReader(stream);
    var input = "";
    var ln = "";
    while ((ln = reader.readLine()) != null) {
        input += ln;
    }
    gs.info("CPSNS: SUB" + input);
} else {
    var body = {};
    var data = request.body.data;

    gs.info("CPSNS: req.body data" + data);

}
​//Search a value with incorrect spaces.. 

var input = 'gu ara nteed rate';
var table = 'core_company';
var field = 'name';

var searchName = input.replace(/\s/g, '').toLowerCase();
var gr = new GlideRecord(table);
gr.addEncodedQuery(field + 'ISNOTEMPTY');
gr.query();
while (gr.next()) {
  	var fieldString = gr.getValue(field).replace(/\s/g, '').toLowerCase();
 
    if (fieldString.indexOf(searchName) != -1)
        gs.info('FOUND: "' + gr[field].getDisplayValue() + '"');
}
/*
Example:

2021-03-15T18:05:40.674Z: FOUND: "Guaranteed Rate Insurance"
2021-03-15T18:05:40.677Z: FOUND: "Guaranteed Rate, Inc2"
2021-03-15T18:05:40.678Z: FOUND: "Guaranteed Rate, Inc."
2021-03-15T18:05:40.680Z: FOUND: "Guaranteed Rate, Inc"
2021-03-15T18:05:40.682Z: FOUND: "Guaranteed Rate Affinity"

*/

Similiar Collections

Python strftime reference pandas.Period.strftime python - Formatting Quarter time in pandas columns - Stack Overflow python - Pandas: Change day - Stack Overflow python - Check if multiple columns exist in a df - Stack Overflow Pandas DataFrame apply() - sending arguments examples python - How to filter a dataframe of dates by a particular month/day? - Stack Overflow python - replace a value in the entire pandas data frame - Stack Overflow python - Replacing blank values (white space) with NaN in pandas - Stack Overflow python - get list from pandas dataframe column - Stack Overflow python - How to drop rows of Pandas DataFrame whose value in a certain column is NaN - Stack Overflow python - How to drop rows of Pandas DataFrame whose value in a certain column is NaN - Stack Overflow python - How to lowercase a pandas dataframe string column if it has missing values? - Stack Overflow How to Convert Integers to Strings in Pandas DataFrame - Data to Fish How to Convert Integers to Strings in Pandas DataFrame - Data to Fish create a dictionary of two pandas Dataframe columns? - Stack Overflow python - ValueError: No axis named node2 for object type <class 'pandas.core.frame.DataFrame'> - Stack Overflow Python Pandas iterate over rows and access column names - Stack Overflow python - Creating dataframe from a dictionary where entries have different lengths - Stack Overflow python - Deleting DataFrame row in Pandas based on column value - Stack Overflow python - How to check if a column exists in Pandas - Stack Overflow python - Import pandas dataframe column as string not int - Stack Overflow python - What is the most efficient way to create a dictionary of two pandas Dataframe columns? - Stack Overflow Python Loop through Excel sheets, place into one df - Stack Overflow python - How do I get the row count of a Pandas DataFrame? - Stack Overflow python - How to save a new sheet in an existing excel file, using Pandas? - Stack Overflow Python Loop through Excel sheets, place into one df - Stack Overflow How do I select a subset of a DataFrame? — pandas 1.2.4 documentation python - Delete column from pandas DataFrame - Stack Overflow python - Convert list of dictionaries to a pandas DataFrame - Stack Overflow How to Add or Insert Row to Pandas DataFrame? - Python Examples python - Check if a value exists in pandas dataframe index - Stack Overflow python - Set value for particular cell in pandas DataFrame using index - Stack Overflow python - Pandas Dataframe How to cut off float decimal points without rounding? - Stack Overflow python - Pandas: Change day - Stack Overflow python - Clean way to convert quarterly periods to datetime in pandas - Stack Overflow Pandas - Number of Months Between Two Dates - Stack Overflow python - MonthEnd object result in <11 * MonthEnds> instead of number - Stack Overflow python - Extracting the first day of month of a datetime type column in pandas - Stack Overflow
MySQL MULTIPLES INNER JOIN How to Use EXISTS, UNIQUE, DISTINCT, and OVERLAPS in SQL Statements - dummies postgresql - SQL OVERLAPS PostgreSQL Joins: Inner, Outer, Left, Right, Natural with Examples PostgreSQL Joins: A Visual Explanation of PostgreSQL Joins PL/pgSQL Variables ( Format Dates ) The Ultimate Guide to PostgreSQL Date By Examples Data Type Formatting Functions PostgreSQL - How to calculate difference between two timestamps? | TablePlus Date/Time Functions and Operators PostgreSQL - DATEDIFF - Datetime Difference in Seconds, Days, Months, Weeks etc - SQLines CASE Statements in PostgreSQL - DataCamp SQL Optimizations in PostgreSQL: IN vs EXISTS vs ANY/ALL vs JOIN PostgreSQL DESCRIBE TABLE Quick and best way to Compare Two Tables in SQL - DWgeek.com sql - Best way to select random rows PostgreSQL - Stack Overflow PostgreSQL: Documentation: 13: 70.1. Row Estimation Examples Faster PostgreSQL Counting How to Add a Default Value to a Column in PostgreSQL - PopSQL How to Add a Default Value to a Column in PostgreSQL - PopSQL SQL Subquery - Dofactory SQL IN - SQL NOT IN - JournalDev DROP FUNCTION (Transact-SQL) - SQL Server | Microsoft Docs SQL : Multiple Row and Column Subqueries - w3resource PostgreSQL: Documentation: 9.5: CREATE FUNCTION PostgreSQL CREATE FUNCTION By Practical Examples datetime - PHP Sort a multidimensional array by element containing date - Stack Overflow database - Oracle order NULL LAST by default - Stack Overflow PostgreSQL: Documentation: 9.5: Modifying Tables PostgreSQL: Documentation: 14: SELECT
PostgreSQL POSITION() function PostgresQL ANY / SOME Operator ( IN vs ANY ) PostgreSQL Substring - Extracting a substring from a String How to add an auto-incrementing primary key to an existing table, in PostgreSQL PostgreSQL STRING_TO_ARRAY()function mysql FIND_IN_SET equivalent to postgresql PL/pgSQL Variables ( Format Dates ) The Ultimate Guide to PostgreSQL Date By Examples Data Type Formatting Functions PostgreSQL - How to calculate difference between two timestamps? | TablePlus Date/Time Functions and Operators PostgreSQL - DATEDIFF - Datetime Difference in Seconds, Days, Months, Weeks etc - SQLines CASE Statements in PostgreSQL - DataCamp SQL Optimizations in PostgreSQL: IN vs EXISTS vs ANY/ALL vs JOIN PL/pgSQL Variables PostgreSQL: Documentation: 11: CREATE PROCEDURE Reading a Postgres EXPLAIN ANALYZE Query Plan Faster PostgreSQL Counting sql - Fast way to discover the row count of a table in PostgreSQL - Stack Overflow PostgreSQL: Documentation: 9.1: tablefunc PostgreSQL DESCRIBE TABLE Quick and best way to Compare Two Tables in SQL - DWgeek.com sql - Best way to select random rows PostgreSQL - Stack Overflow How to Add a Default Value to a Column in PostgreSQL - PopSQL How to Add a Default Value to a Column in PostgreSQL - PopSQL PL/pgSQL IF Statement PostgreSQL: Documentation: 9.1: Declarations SQL Subquery - Dofactory SQL IN - SQL NOT IN - JournalDev PostgreSQL - IF Statement - GeeksforGeeks How to work with control structures in PostgreSQL stored procedures: Using IF, CASE, and LOOP statements | EDB PL/pgSQL IF Statement How to combine multiple selects in one query - Databases - ( loop reference ) DROP FUNCTION (Transact-SQL) - SQL Server | Microsoft Docs SQL : Multiple Row and Column Subqueries - w3resource PostgreSQL: Documentation: 9.5: CREATE FUNCTION PostgreSQL CREATE FUNCTION By Practical Examples datetime - PHP Sort a multidimensional array by element containing date - Stack Overflow database - Oracle order NULL LAST by default - Stack Overflow PostgreSQL: Documentation: 9.5: Modifying Tables PostgreSQL: Documentation: 14: SELECT
כמה עוד נשאר למשלוח חינם גם לעגלה ולצקאאוט הוספת צ'קבוקס לאישור דיוור בצ'קאאוט הסתרת אפשרויות משלוח אחרות כאשר משלוח חינם זמין דילוג על מילוי כתובת במקרה שנבחרה אפשרות איסוף עצמי הוספת צ'קבוקס לאישור דיוור בצ'קאאוט שינוי האפשרויות בתפריט ה-סידור לפי בווקומרס שינוי הטקסט "אזל מהמלאי" הערה אישית לסוף עמוד העגלה הגבלת רכישה לכל המוצרים למקסימום 1 מכל מוצר קבלת שם המוצר לפי ה-ID בעזרת שורטקוד הוספת כפתור וואטסאפ לקנייה בלופ ארכיון מוצרים הפיכה של מיקוד בצ'קאאוט ללא חובה מעבר ישיר לצ'קאאוט בלחיתה על הוספה לסל (דילוג עגלה) התראה לקבלת משלוח חינם בדף עגלת הקניות גרסה 1 התראה לקבלת משלוח חינם בדף עגלת הקניות גרסה 2 קביעה של מחיר הזמנה מינימלי (מוצג בעגלה ובצ'קאאוט) העברת קוד הקופון ל-ORDER REVIEW העברת קוד הקופון ל-ORDER REVIEW Kadence WooCommerce Email Designer קביעת פונט אסיסנט לכל המייל בתוסף מוצרים שאזלו מהמלאי - יופיעו מסומנים באתר, אבל בתחתית הארכיון הוספת כפתור "קנה עכשיו" למוצרים הסתרת אפשרויות משלוח אחרות כאשר משלוח חינם זמין שיטה 2 שינוי סימן מטבע ש"ח ל-ILS להפוך סטטוס הזמנה מ"השהייה" ל"הושלם" באופן אוטומטי תצוגת הנחה באחוזים שינוי טקסט "בחר אפשרויות" במוצרים עם וריאציות חיפוש מוצר לפי מק"ט שינוי תמונת מוצר לפי וריאציה אחרי בחירה של וריאציה אחת במקרה של וריאציות מרובות הנחה קבועה לפי תפקיד בתעריף קבוע הנחה קבועה לפי תפקיד באחוזים הסרה של שדות משלוח לקבצים וירטואליים הסתרת טאבים מעמוד מוצר הצגת תגית "אזל מהמלאי" בלופ המוצרים להפוך שדות ל-לא חובה בצ'קאאוט שינוי טקסט "אזל מהמלאי" לוריאציות שינוי צבע ההודעות המובנות של ווקומרס הצגת ה-ID של קטגוריות המוצרים בעמוד הקטגוריות אזל מהמלאי- שינוי ההודעה, תגית בלופ, הודעה בדף המוצר והוספת אזל מהמלאי על וריאציה הוספת שדה מחיר ספק לדף העריכה שינוי טקסט אזל מהמלאי תמונות מוצר במאונך לצד תמונת המוצר הראשית באלמנטור הוספת כפתור קנה עכשיו לעמוד המוצר בקניה הזו חסכת XX ש''ח לאפשר למנהל חנות לנקות קאש ברוקט לאפשר רק מוצר אחד בעגלת קניות
הודעת שגיאה מותאמת אישית בטפסים להפוך כל סקשן/עמודה לקליקבילית (לחיצה) - שיטה 1 להפוך כל סקשן/עמודה לקליקבילית (לחיצה) - שיטה 2 שינוי הגבלת הזיכרון בשרת הוספת לינק להורדת מסמך מהאתר במייל הנשלח ללקוח להפוך כל סקשן/עמודה לקליקבילית (לחיצה) - שיטה 3 יצירת כפתור שיתוף למובייל פתיחת דף תודה בטאב חדש בזמן שליחת טופס אלמנטור - טופס בודד בדף פתיחת דף תודה בטאב חדש בזמן שליחת טופס אלמנטור - טפסים מרובים בדף ביי ביי לאריק ג'ונס (חסימת ספאם בטפסים) זיהוי אלו אלמנטים גורמים לגלילה אופקית לייבלים מרחפים בטפסי אלמנטור יצירת אנימציה של "חדשות רצות" בג'ט (marquee) שינוי פונט באופן דינאמי בג'ט פונקציה ששולפת שדות מטא מתוך JET ומאפשרת לשים הכל בתוך שדה SELECT בטופס אלמנטור הוספת קו בין רכיבי התפריט בדסקטופ ולדציה למספרי טלפון בטפסי אלמנטור חיבור שני שדות בטופס לשדה אחד שאיבת נתון מתוך כתובת ה-URL לתוך שדה בטופס וקידוד לעברית מדיה קוורי למובייל לייבלים מרחפים בטפסי אלמנטור תמונות מוצר במאונך לצד תמונת המוצר הראשית באלמנטור הצגת תאריך עברי פורמט תאריך מותאם אישית