ServiceNow Notifications and Parent/Child Inheritance

My initial expectation was that if I created a notification on a table, that the notification would be inherited by any child tables of the table where I’d defined the notification.

Upon further digging, it turns out that notifications aren’t inherited the way that business rules are, which actually makes more sense than my starting expectation.

If a child table inherited a parent’s notifications, then you’d be in a real pickle if you ever needed the child table not to inherit the parent’s notifications.

The way that it’s been coded up means that you may have to create a bunch more notifications to build the same functionality across different child tables, but that’s a better way to go than trying to figure out how to stop unwanted notifications from firing off.

ServiceNow Branching in Workflows

**Apologies for posting this a few days late. I’ve been doing some consulting work for the last several months. It has been great experience, and the extra money has been nice, but it’s meant that a lot of other things have had to be pushed to the back burner.

My posting schedule may still be a bit erratic for a while until the consulting is done, but I’ll do my best to keep it as close to the normal schedule as possible.

On to the subject at hand:

When using a branch and join construction in a ServiceNow workflow, my first instinct is to do the branch, and then do any if activities between the branch and the join.

However, this is always the wrong answer because the workflow will hang at the join as it waits for the flow to progress down the other side of the if activity.

The correct way to go about that is to do your if activity, and then run a branch off of the yes path, and another branch off of the no path.

It means that you end up having to copy a bunch of tasks so that they are on routes off of the if activity, but that way all of the routes into the relevant join reach it and flow can continue paste the point statement rather than hanging.

 

Divisible Sum Pairs (HackerRank Problem)

Hacker Rank problems can be fun, and I often find myself learning something interesting. I recently undertook the Divisible Sum Pairs problem.

In short, given an array of integers ar, and an integer k, find how many pairs of integers add up to a multiple of k.

The trivial solution is just a double for-loop that has an O(n^2) run-time.

I often find that by the time I’m done reading through the Hacker Rank problems and go start working through the actual code to solve the problem, that I’ve let a key detail slip. Such was the case this time, and my original solution found the total of the pairs of integers that added up to k rather than a multiple of k.

Because of that, my initial implementation used a hash table, and I decided to try and expand out my initial hash table solution to deal with multiples. Here is my solution:

function divisibleSumPairs(n, k, ar) {
     let myMap = new Map();
     let pairs = 0;
     let biggestValue = ar[0];

     for(let i=0;i<ar.length;i++) {
          let maxLookingFor = ar[i] + biggestValue;
          let iterations = Math.ceil(maxLookingFor/k);
               for(let j=1; j<=iterations;j++) {
                    let lookingFor = k*j-ar[i];
                    const mapValue = myMap.get(lookingFor)
                    if(mapValue) {
                         pairs += mapValue;
                    }
               }

               if(ar[i] > biggestValue) {
                    biggestValue = ar[i];
               }

               const mapValue = myMap.get(ar[i]);

               if(mapValue) {
                    myMap.set(ar[i], mapValue + 1);
               } else {
                    myMap.set(ar[i], 1);
               }
          }

     return pairs;
}

Here is the least efficient:

function divisibleSumPairs(n, k, ar) {
     let pairs = 0;
     for(let i=0;i<ar.length;i++) {
          for(let j=i+1;j<ar.length;j++) {
               let sum = ar[i] + ar[j];
                    if(!(sum%k)) { //!sum%k does !sum then %k's the !sum
                         pairs++;
                    }
          }
     }
     return pairs;
}

Here’s the most efficient solution:

function divisibleSumPairs(n, k, ar) {
     let numbers = [];
     for(let i=0;i<k;i++) {          numbers.push([]);     }
     for(let i=0;i<ar.length;i++) {          let remainder = ar[i]%k;          numbers[remainder].push(ar[i]);     }
     let count;
      //populate the zero row     let zeroQuantity = numbers[0].length;
     count = (zeroQuantity * (zeroQuantity -1)) / 2;
     let j = k -1;
      //populate the remaining rows
     for(let i=1; i<=j;i++) {
          if(i == j) {
               //remainders add to k
               let middleRowQuantity = numbers[i].length;
               count += (middleRowQuantity * (middleRowQuantity - 1)) / 2;
          } else {
               //remainder is exactly half k 
               count += numbers[i].length * numbers[j].length;
          }
          j--;
     }
     return count;
}

As k gets smaller, the range of numbers gets bigger, and the length of the array ar gets smaller, the ‘worst’ alogorithm will tend to do better compared to my solution. As k gets larger, the range of numbers gets smaller, and the size of the array gets larger, then my solution will tend to perform better.
 

The most efficient solution is obviously better than either of the other two. If we were talking a problem where the range of numbers in the array was very small, or the range was very small until the last step, k was very large, and we needed the pairs returned, then it’s possible that the generation of the pairs at the end of the efficient solution could take longer than my solution, but that’s a pretty extreme, narrow kind of edge case.

If I ever run into a similar problem in the wild, I’ll now know how to approach it thanks to the commenters in the discussion section on Hacker Rank.

ServiceNow – the “New” UI Button & URL’s

I recently had an issue where I needed to grant a specific role the ability to create a new record.

They needed to be able to click the ‘New’ button, enter in the relevant information on the record, and then save the record.

It turned out that there were two issues preventing that role from being able to create a new record.

The first was in the List Control under List v3:

I’m including a screenshot of the list control screen, and it’s worth pointing out that there are three different spots there where you can stop someone from seeing the ‘New’ button. If you skim over that screen and miss one of the three like I initially did, you’re likely to waste a lot of time banging your head against a wall.

There was also an ACL issue that was in play with this story, but theĀ  more interesting bit was some troubleshooting advice that I got in the SN Devs slack channel.

I explained my issue and that I’d checked everywhere I could think to check, and asked where else the ability to create new records might be being locked down. Someone there (I afraid I don’t remember who), told me to go to

https://myInstance.service-now.com/nav_to.do?uri=%2Fsys_user_group.do

They suggested that I do that because it pulled the ‘New’ button out of the picture and confirmed whether or not there was an ACL issue still giving me grief.

In the above url, sys_user_group.do is telling servicenow to go to the create record view for the sys_user_group table.

sys_user_group_list.do would take me to the list of groups.

There isn’t anything revolutionary there, but starting out in ServiceNow, one of the things that slowed me down was not understanding some of the small quality of life type things built into the platform.

That includes stuff like not knowing that I could right click in the form view and copy the sys_id of the record into my clipboard that way.

I also didn’t understand initially that I could get the table name right out of the url.

I’ve known how to get to a list of records in a table by typing the table name.list into the application navigator, but now I’ve got one more tool in my toolbox, for which I’m very grateful.