Round-Robin (Auto Assignment of new incidents and tasks)

magoo
Kilo Expert

HI All,

 

I was asked to create a round-robin type approach (Auto Assignment) for any incidents/tasks that come into our two level1 groups. What we are looking for is that if its sent to team A's group it will auto assign to the next team member in line, and same with Team B.   I have searched the forums and found a post back from 2008 but it had been deleted by ServiceNow in 2010.   Our company is new to ServiceNow (a couple months now), and I am guessing this is more of a script that would need to run, but currently do not have much experience in scripting.   Has anyone had any luck with doing something like this?   Any suggestions would be greatly appreciated!

 

Thanks!

1 ACCEPTED SOLUTION

justin_drysdale
Mega Guru

We have this in our instance.   Here's the breakdown:



On sys_user, create a date/time field to track last ticket assigned. Also create a checkbox that will be used to determine if the user can receive a ticket.   This can be your vacation exclusion logic.



1. Make an array (associative, key-value) to contain your users that will receive tickets and their corresponding last ticket assigned timestamp.


2. Find your assignment group, and query it's users.


3. Push those users and timestamp into the user array from 1.   You can conditionalize here with the checkbox to make sure you are only pushing 'active' users into the array.


4. Sort the array by timestamp, return the user that has the oldest timestamp.


4.5. Update the user's timestamp.


5. assigned_to = returned user.



Please let me know if you have any questions.


View solution in original post

102 REPLIES 102

Hi,


i am looking at implementing this and like the sound of your display solution, i don't suppose you could elaborate a little on how you configured it.


cheers


Having implemented this some time ago, with much success, I was able to implement a control panel for this too.   Here's what mine looks like:



Screen Shot 11-19-15 at 11.30 AM.JPG



I also have it logging each user that logs in and out of RoundRobin and can be reported on.   Let me know if you're interested and I'll dump all my code and scripts to help you get on your way.


Wow, that looks great, David! I'd be very interested in seeing your work. Thanks!


Here's my "round_robin_widget" UI Page (XML)



<?xml version="1.0" encoding="utf-8" ?>


<j:jelly trim="false" xmlns:j="jelly:core" xmlns:g="glide" xmlns:j2="null" xmlns:g2="null">




      <g2:client_script type="user" />




      <g:evaluate jelly="true">


              var gr1 = new GlideRecord('sys_user_grmember');


              gr1.addQuery('group', '8a4cd5b36fd3d1000fd9122cbb3ee48f'); // "Service Desk" group sys_id.


              gr1.orderBy('user.u_last_ticket_assigned');


              gr1.query();


      </g:evaluate>




        <g:evaluate jelly="true">


              var gr2 = new GlideRecord('sys_user_grmember');


              gr2.addQuery('group', '8a4cd5b36fd3d1000fd9122cbb3ee48f'); // "Service Desk" group sys_id.


              gr2.orderBy('user.u_last_ticket_assigned');


              gr2.query();


      </g:evaluate>




      <script>


              var activeCount = 0;


              var inactiveCount = 0;


              var totalTicketsForTheDay = 0;


              var timeArray = [];




              function add(val)


              {


                      if (val == "a")


                              activeCount++;


                      else if (val == "i")


                              inactiveCount++;


              }


              function ttftd(val)


              {


                      if (parseInt(val) > 0)


                              totalTicketsForTheDay += parseInt(val);


              }


              function getTimeVal(val_ID, val_time)


              {


                      var tm = val_time.split(" ");


                      val_ID = val_ID + "_dt";


                      timeArray.push({ id: val_ID, time: tm[1] });


              }


              function cleanName(val)


              {


                      console.log("LOOK:");


                      console.log(val);


                      var techName = val.replace(/'/g, "\\'");


                      return techName;


              }


      </script>




      <style>


              .trHover tr:hover td {background:#d7d7d7}


      </style>


              <div id="tick"></div>


              <table>


                      <tr>


                              <td>


                                      <table class="trHover">


                                              <div id="stats">


                                              </div>


                                              <tr>


                                                      <td colspan="3" align="center" style="background:#d7d7d7">


                                                              ACTIVE&#160;(<span id="act"></span>)


                                                      </td>


                                              </tr>


                                              <tr id="head">


                                                      <td width="135">


                                                              <span style="text-decoration: underline;">Technician</span>


                                                      </td>


                                                      <td width="25">


                                                              <span style="text-decoration: underline;">#</span>


                                                      </td>


                                                      <td>


                                                              <span style="text-decoration: underline;">Last ticket</span>


                                                      </td>


                                              </tr>


                                              <j:while test="${gr1.next()}">


                                                      <j:if test="${gr1.user.u_round_robin_active}">


                                                      <tr>


                                                              <td>


                                                                      <a target="_top" href="nav_to.do?uri=sys_user.do?sys_id=${gr1.user.sys_id}">


                                                                              <j:if test="${gs.getUserID() != gr1.user.sys_id}">


                                                                                      <span style="font-weight: bold;">${gr1.user.name}</span>


                                                                              </j:if>


                                                                              <j:if test="${gs.getUserID() == gr1.user.sys_id}">


                                                                                      <span style="background-color: #5CE65C; font-weight: bold;">${gr1.user.name}</span>


                                                                              </j:if>


                                                                              <script> add("a"); </script>


                                                                      </a>


                                                              </td>


                                                              <td id="${gr1.user.sys_id}">


                                                                      <g:evaluate jelly="true">


                                                                              var gdt = new GlideDateTime();


                                                                              var month = gdt.getMonth();


                                                                              var year = gdt.getYear();


                                                                              var day = gdt.getDayOfMonth();




                                                                              var gr3 = new GlideRecord('u_round_robin');


                                                                              gr3.addQuery('u_year', year);


                                                                              gr3.addQuery('u_month', month);


                                                                              gr3.addQuery('u_day_of_month', day);


                                                                              gr3.addQuery('u_user_sys_id', gr1.user.sys_id);


                                                                              gr3.orderBy('u_timestamp');


                                                                              gr3.query();


                                                                      </g:evaluate>


                                                                      <j:if test="${gr3.next()}">


                                                                              ${gr3.u_daily_tickets_assigned}


                                                                              <script>ttftd(parseInt("${gr3.u_daily_tickets_assigned}"));</script>


                                                                      </j:if>


                                                              </td>


                                                              <td id="${gr1.user.sys_id}_dt">


                                                                      <script>getTimeVal("${gr1.user.sys_id}", "${gr1.user.u_last_ticket_assigned.getDisplayValue()}");</script>


                                                              </td>


                                                              <j:if test="${gs.getUserID() == '398232ca6ff191007906db3bbb3ee4ae'}"> <!-- // Corey Boyd (ADMIN) -->


                                                                      <td>


                                                                              <button type="button" onclick="adminDisableRR('${gr1.user.sys_id}', &quot;${gr1.user.name}&quot;)">Disable</button>


                                                                      </td>


                                                              </j:if>


                                                              <j:if test="${gs.getUserID() == '8a7232ca6ff191007906db3bbb3ee412'}"> <!-- // Joseph Romanini (ADMIN) -->


                                                                      <td>


                                                                              <button type="button" onclick="adminDisableRR('${gr1.user.sys_id}', &quot;${gr1.user.name}&quot;)">Disable</button>


                                                                      </td>


                                                              </j:if>


                                                              <j:if test="${gs.getUserID() == 'b6d861232b4bbd00df6426e405da1523'}"> <!-- David Dunn (ADMIN) -->


                                                                      <td>


                                                                              <button type="button" onclick="adminDisableRR('${gr1.user.sys_id}', &quot;${gr1.user.name}&quot;)">Disable</button>


                                                                      </td>


                                                              </j:if>


                                                      </tr>


                                                      </j:if>


                                              </j:while>


                                      </table>


                              </td>


                      </tr>


                      <tr>


                              <td>&#160;</td>


                      </tr>


                      <tr>


                              <td>


                                      <table class="trHover" width="100%">


                                              <tr>


                                                      <td colspan="3" align="center" style="background:#d7d7d7">


                                                              <i>INACTIVE</i>&#160;(<span id="inact"></span>)


                                                      </td>


                                              </tr>


                                              <j:while test="${gr2.next()}">


                                                      <j:if test="${!gr2.user.u_round_robin_active}">


                                                              <tr>


                                                                      <td colspan="3">


                                                                              <a target="_top" href="nav_to.do?uri=sys_user.do?sys_id=${gr2.user.sys_id}">


                                                                                      <i>${gr2.user.name}</i>


                                                                                      <script> add("i"); </script>


                                                                              </a>


                                                                      </td>


                                                              </tr>


                                                              <g:evaluate jelly="true">


                                                                      var gdt2 = new GlideDateTime();


                                                                      var month2 = gdt2.getMonth();


                                                                      var year2 = gdt2.getYear();


                                                                      var day2 = gdt2.getDayOfMonth();




                                                                      var gr4 = new GlideRecord('u_round_robin');


                                                                      gr4.addQuery('u_year', year2);


                                                                      gr4.addQuery('u_month', month2);


                                                                      gr4.addQuery('u_day_of_month', day2);


                                                                      gr4.addQuery('u_user_sys_id', gr2.user.sys_id);


                                                                      gr4.orderBy('u_timestamp');


                                                                      gr4.query();


                                                              </g:evaluate>


                                                              <j:if test="${gr4.next()}">


                                                                      <script>ttftd(parseInt("${gr4.u_daily_tickets_assigned}"));</script>


                                                              </j:if>


                                                      </j:if>


                                              </j:while>


                                      </table>


                              </td>


                      </tr>


              </table>


</j:jelly>




















Here's the Client Script for this:



var tot = activeCount + inactiveCount;


document.getElementById("act").innerHTML = activeCount;


document.getElementById("inact").innerHTML = inactiveCount;




if (activeCount == 0)


      document.getElementById("head").innerHTML = "<td>Everyone went home!</td>";


else


      document.getElementById("tick").innerHTML = parseInt(totalTicketsForTheDay) + "<i> tickets auto-assigned today.</i>";




for (var x = 0; x < timeArray.length; x++)


{


      document.getElementById(timeArray[x].id).innerHTML = timeArray[x].time;


}




function adminDisableRR(sysID, techName)


{


      var gaj = new GlideAjax('admin_RoundRobin_Toggle');


      gaj.addParam('sysparm_name','adminDisableRR');


      gaj.addParam('sysparm_userSysID', sysID);


      gaj.addParam('sysparm_userName', techName);


      gaj.getXMLWait();


      var ans = gaj.getAnswer();


      console.log(ans);


}











Here's the "admin_RoundRobin_Toggle" Script Include for the GlideAjax() call in the adminDisableRR() function:



var admin_RoundRobin_Toggle = Class.create();




admin_RoundRobin_Toggle.prototype = Object.extendsObject(AbstractAjaxProcessor, {


adminDisableRR: function() {




      var userSysID = this.getParameter('sysparm_userSysID');


      var userName = this.getParameter('sysparm_userName');




      var gr = new GlideRecord('sys_user');


      gr.addQuery('sys_id', userSysID);


      gr.query();




      if (gr.next())


      {


              var act = 99;


              if (gr.u_round_robin_active == true)


              {


                      gs.addInfoMessage("Successfully set to inactive.   Refresh the page to view the result.");


                      gr.u_round_robin_active = false;


                      act = 0;


              }




              gr.update();




              var nowdt = gs.nowDateTime();




              var gdt = new GlideDateTime();


              var month = gdt.getMonth();


              var year = gdt.getYear();


              var day = gdt.getDayOfMonth();




              var gr2 = new GlideRecord('u_round_robin');


              gr2.initialize();


              gr2.u_user_sys_id = userSysID;


              gr2.u_user = userName;


              gr2.u_year = year;


              gr2.u_month = month;


              gr2.u_day_of_month = day;


              gr2.u_timestamp = nowdt;




              if (act == 0)


              {


                      gr2.u_action = "[admin] Toggled INACTIVE";


              }


              else if (act == 99)


              {


                      gr2.u_timestamp = '';


              }




              gr2.insert();


      }


}


});

























Here is whay my Table, "u_round_robin", looks like, that keeps a running log of the login's and logout's:



Screen Shot 11-19-15 at 11.48 AM.JPG



This is quite a bit of info to chew on, so if there's more data I'm missing to implement this, or you have any questions as to how/why something works, just ask!  


Hi david, this is awesome thanks for posting. It's all working perfectly for me, except the number of tickets assigned counts, my coding skills letting me down! Can you clarify which lines of the code update this and if its coming from the round robin or user table.


cheers