Here's the entire script include


var LoanerUtils = Class.create();




LoanerUtils.prototype = {


  /**********


    * Initialization stuff here...


    *


    **********/


  initialize : function() {


      this.overdueRemindTime = gs.getProperty('glide.loaner.overdue.remindtime', 24);


      this.pickupLeadTime       = gs.getProperty('glide.loaner.pickup.leadtime', 24) * -1; //paramm to gs.daysAgo()


      this.returnRemindTime   = gs.getProperty('glide.loaner.return.remindtime', 24) * -1;


  },




  /**********


    *


    * getOverdueRequests - retrieve a list of overdue records


    *


    * @param - None


    * @return: array of sys_ids


    *


    **********/


  getOverdueRequests : function() {




      var a = new Array();


      var gr = new GlideRecord('loaner_request');



      gr.addQuery('end_date', '<=', gs.nowDateTime());


      gr.addQuery('state', 17);


      gr.query();




      while (gr.next()) {


          a.push(gr.sys_id.toString());


      }


      return a;


  },




  /**********


    *


    * timeToRemindOverdue - Use the passed in ID to check if the record is time to remind again


    *


    * @param - id: sys_id of the loaner record to check


    * @return - boolean: true = time to remind


    *


    **********/


  timeToRemindOverdue : function(id) {




      var gr = new GlideRecord('loaner_request');




      if (!gr.get(id)) {


          gs.log('>>>DEBUG: LoanerUtils: timeToRemindOverdue(): FAILED TO RETRIEVE RECORD');


          return false;


      }


      var baseDate = (gr.last_overdue_reminder == '') ? gr.end_date : gr.last_overdue_reminder;




      return (baseDate <= gs.hoursAgo(this.overdueRemindTime)) ? true : false;


  },




  /**********


    *


    * sendOverdueReminder - Queue an event to send a reminder and update the necessary


    *                                             record fields to indicate they've been reminded


    *


    * @param - id: sys_id of the loaner record to check


    * @return - None


    *


    **********/


  sendOverdueReminder : function(id) {




      var gr = new GlideRecord('loaner_request');




      if (!gr.get(id)) {


          gs.log('>>>DEBUG: LoanerUtils: setLastOverdueReminder(): FAILED TO RETRIEVE RECORD');


          return;


      }


      ++gr.overdue_count;




      // Record the last time a reminder was sent


      gr.last_overdue_reminder = gs.nowDateTime();


      gr.update();




      // Send the overdue reminder


      gs.eventQueue('loaner.overdue', gr, gr.start_time, gr.end_time);


  },




  /**********


    *


    * getNullPickupReminders - Get a list of records in state 'Ready for Pickup'


    *                                                   that haven't been reminded before


    *


    * @param - None


    * @return - array of sys_ids


    *


    **********/


  getNullPickupReminders : function() {




      var a = new Array();


      var gr = new GlideRecord('loaner_request');




      gr.addQuery('state', 16);


      gr.addQuery('pickup_reminder', '');


      gr.addQuery('start_date', '<=', gs.hoursAgo(this.pickupLeadTime));


      gr.query();




      while (gr.next()) {


          a.push(gr.sys_id.toString());


      }


      return a;


  },




  /**********


    *


    * sendPickupReminder - Queue an event to send a reminder and update the pickup reminder field


    *


    * @param - id: sys_id of the loaner record to check


    * @return - None


    *


    **********/


  sendPickupReminder : function(id) {




      var gr = new GlideRecord('loaner_request');




      if (!gr.get(id)) {


          gs.log('>>>DEBUG: LoanerUtils: sendPickupReminder(): FAILED TO RETRIEVE RECORD');


          return;


      }




      // Log the time the pickup reminder was sent and avoid sending again


      gr.pickup_reminder = gs.nowDateTime();


      gr.update();




      // Send the pickup reminder


      gs.eventQueue('loaner.pickup', gr, gr.start_time, gr.end_time);


      return;


  },




  /**********


    *


    * getNullReturnReminders - Get a list of records that need reminding to bring their item back


    *


    * @param - None


    * @return - array of sys_ids


    *


    **********/


  getNullReturnReminders : function() {




      var a = new Array();


      var gr = new GlideRecord('loaner_request');




      gr.addQuery('state', 17);


      gr.addQuery('return_reminder', '');


      gr.addQuery('end_date', '<=', gs.hoursAgo(this.returnRemindTime));


      gr.query();




      while (gr.next()) {


          a.push(gr.sys_id.toString());


      }


      return a;


  },




  /**********


    *


    * setReturnReminder - Queue a return reminder and update field when reminder was sent


    *


    * @param - id: sys_id of the loaner record to check


    * @return - None


    *


    **********/


  sendReturnReminder : function(id) {




      var gr = new GlideRecord('loaner_request');




      if (!gr.get(id)) {


          gs.log('>>>DEBUG: LoanerUtils: sendReturnReminder(): FAILED TO RETRIEVE RECORD');


          return;


      }




      // Set this record to never remind again


      gr.return_reminder = gs.nowDateTime();


      gr.update();




      // Send the return reminder


      gs.eventQueue('loaner.return', gr, gr.start_time, gr.end_time);


  },




  /*********


    *


    * withdrawRequest - Update a request and all related bits


    *                                     (child tasks are handled by a standard bus. rule)


    *


    * @param lr - GlideRecord of the request


    * @return None


    *


    **********/


  withdrawRequest : function(lr) {




      var wf = new Workflow();




      wf.cancel(lr);


      lr.active=false;


      lr.state=7;


      lr.update();




      gs.addInfoMessage(gs.getMessage('loaner_withdraw'));


  },


   


  /*********


    *


    * isAvailable - check to see if there are no conflicts w/ci


    *                             being available between start and end times


    *                             and CI is "in" (loaner request state=Requested, Closed, Withdrawn)


    *


    * @param ci - GlideRecord or sys_id of the CI being requested


    * @param start - start date-time of the requested reservation


    * @param end - end date-time of the requested reservation


    * @return boolean - true=no conflicts


    *


    **********/


  isAvailable : function(ci, start, end) {




      var ci_id = ci;


      var count = 0;


      var lr       = new GlideAggregate('loaner_request');




      if (JSUtil.nil(ci))


          return false; // Null CI defaults to "not available"




      if (ci instanceof GlideRecord)


          ci_id = ci.sys_id;




      var myQuery = 'active=true^';


      myQuery += 'cmdb_ci=' + ci + '^';


      myQuery += 'start_date<' + end + '^';


      myQuery += 'end_date>' + start + '^';


      myQuery += 'NQ';


      myQuery += 'active=true^';


      myQuery += 'cmdb_ci=' + ci + '^';


      myQuery += 'end_date<' + gs.daysAgo(0);




      lr.addAggregate('COUNT');


      lr.addQuery(myQuery);


      lr.query();




      if (lr.next()) {


            count = lr.getAggregate('COUNT');


      }




      return (count == 0);


  },




  /**********


    *


    * availableCis - get a list of CIs in a class/depot that are available


    *


    * @param class_name - CI class


    * @param depot_name - Name of the pick up location


    * @param start - reservation start date


    * @param end - reservation end date


    * @return - comma separated list of sys_ids that are available at that time


    *


    **********/


  availableCis : function(class_name, depot_name, start, end) {




      var ci                                       = new GlideRecord('cmdb_ci');


      var installStatusProperty = gs.getProperty('glide.loaner.install_status');


      var checkAvailProperty       = gs.getProperty('glide.loaner.check_availability') == 'true';


      var availableItems               = [];


   


        gs.log("Test loaner class: " + class_name);


   


      if (!JSUtil.nil(installStatusProperty)) {


          ci.addQuery('install_status', 'IN', installStatusProperty);


      }


      ci.addQuery('loaner', true);


      ci.addQuery('sys_class_name', class_name);


      ci.addQuery('depot', depot_name);


      ci.query();




      while (ci.next()) {


          var id = ci.sys_id.toString();




          if (checkAvailProperty) {                   // Check only available matching items


              if (this.isAvailable(id, start, end))


                  availableItems.push(id);




          } else {                                                   // Take any matching items


              availableItems.push(id);


          }


      }




      return availableItems.join(',');


  },




  type: 'LoanerUtils'


}