Name

global.ScrumAddSprintsAjaxProcessor

Description

No description available

Script

/**
* ScrumAddSprintAjaxProcessor
* Ajax Processor to create multiple sprints for a given release
*
* @author Chris Henson <chris.henson@service-now.com>
*/
var ScrumAddSprintsAjaxProcessor = Class.create();
ScrumAddSprintsAjaxProcessor.prototype = Object.extendsObject(AbstractAjaxProcessor,{
  initialize: function(request,responseXML,gc) {
      AbstractAjaxProcessor.prototype.initialize.call(this,request,responseXML,gc);
      this._log=(new GSLog("loglevel",this.type)).setLog4J();
      //this._log.setLevel(GSLog.DEBUG);
  },

  checkDuration: function() {
      var r = this.newItem();
      var params = this._getParams(r);

      // If we got the params OK, force the time component of the date to 00:00:00
      params.spStartDate = params.spStartDate.replace(/\d{2}:\d{2}:\d{2}/,"00:00:00");
      
      var spNum = parseInt(params.spNum); // Integer number of sprints
      var spd = parseInt(params.spDuration); //Integer duration

      var sd = new GlideDateTime();
      sd.setDisplayValue(params.spStartDate);
      
      var ed = new GlideDateTime();
      ed.setDisplayValue(params.spStartDate);
      ed.subtract(100);
      ed.addDays(spNum*spd);

      // So now we have the start and end dates for the total sprint duration we can compare to the release.

      var rls = new GlideRecord("rm_release_scrum");
      rls.addQuery("sys_id",'=',params._sysId);
      rls.query();

      if (rls.next()) {
          var rsd = rls.start_date.getGlideObject();
          var red = rls.end_date.getGlideObject();

          if (this._log.atLevel(GSLog.DEBUG)) {
              this._log.debug("[checkDuration] Release start date: " + rls.start_date + " Sprints start date: " + sd + " comparison: " + rsd.compareTo(sd));
              this._log.debug("[checkDuration] Release end date: " + rls.end_date + " Sprints end date" + ed + " comparison: " + red.compareTo(ed));
          }

          //Check the start date and end date.
          if (rsd.compareTo(sd) < 0 && red.compareTo(ed) > 0) {
              // Return success
              this._log.debug("[checkDuration] Release dates OK");
              r.setAttribute("result","success");
              return "success"; 
          }
      }

      // return fail
      this._log.debug("[checkDuration] Release dates out of bounds");
      r.setAttribute("result","failure");
      return "failure"; 
  },


  /**
   * addSprints(): Adds the sprints to the release and pushed out the release dates to accommodate the sprints.
   */
  addSprints: function() {
      // Set up the AJAX return
      var r = this.newItem();
      var params = this._getParams(r);

      // If we got the params OK, force the time component of the date to 00:00:00
      params.spStartDate = params.spStartDate.replace(/\d{2}:\d{2}:\d{2}/,"00:00:00");

      var spNum = parseInt(params.spNum); // Integer number of sprints
      var spd = parseInt(params.spDuration); //Integer duration
      var spsn = parseInt(params.spStartNum); //Integer start number

      var sd = new GlideDateTime();
      sd.setDisplayValue(params.spStartDate);
      var ed = new GlideDateTime();
      ed.setDisplayValue(params.spStartDate);
      ed.subtract(100);
      ed.addDays(spd);

      var rls = new GlideRecord("rm_release_scrum");
      rls.addQuery("sys_id",'=',params._sysId);
      rls.query();
     
      if (!rls.next()) {
          r.setAttribute("result","failure");
          r.setAttribute("reason","The scrum release for sysId <"+ params._sysId +"> could not be found");
      this._log.error("[addSprints] The scrum release for sysId <"+ params._sysId +"> could not be found");
          return null;
      }

      var rsd = rls.start_date.getGlideObject();
      var red = rls.end_date.getGlideObject();

      // We have a release here with possibly out of bounds dates. We need to push the release dates to accommodate the sprints.
      var fd = new GlideDateTime();
      fd.setDisplayValue(params.spStartDate);
      fd.subtract(100);
      fd.addDays(spNum*spd);

      if (this._log.atLevel(GSLog.DEBUG)){
          this._log.debug("[addSprints] Release start date: " + rsd + " Sprints start date: " + sd + " comparison: " + rsd.compareTo(sd) );
          this._log.debug("[addSprints] Release end date: " + red + " Sprints end date: " + fd + " comparison: " + red.compareTo(fd) );
      }

      var updated = false;
      if (rsd.compareTo(sd) > 0) {
          if (this._log.atLevel(GSLog.DEBUG))
              this._log.debug("[addSprints] Changing release start date to : " + sd);

          rls.start_date = sd;
          updated = true;
      }

      if (red.compareTo(fd) < 0) {
          if (this._log.atLevel(GSLog.DEBUG))
              this._log.debug("[addSprints] Changing release end date to : " + fd);

          rls.end_date = fd;
          updated = true;
      }

      if (this._log.atLevel(GSLog.DEBUG))
          this._log.debug("[addSprints] Update release?: "+updated);

      if (updated)
          rls.update();

      var spntNumbers = [];
  	
  	var addSprintMembersProcessor = new ScrumAjaxAddSprintTeamMembersProcessor();

      for (var i=0; i < spNum; i++) {
          // If his isn't the first run start adding the duration
          if (i > 0) {
              sd.addDays(spd);
              ed.addDays(spd);
          }
          // Cheeky bit of code to allow %D to be substituted for the sprint number in the name
          var spName = (params.spName.match(/%D/) ? params.spName.replace(/%D/,(i+spsn)+""):params.spName+" "+(i+spsn));

          // Build the Sprint record
          var spnt = new GlideRecord("rm_sprint");
          spnt.release = rls.getValue("sys_id");
          spnt.start_date = sd;
          spnt.end_date = ed;
          spnt.short_description = spName;
          spnt.sys_domain = rls.getValue("sys_domain");
          spnt.setWorkflow(false); //Prevent Business Rules
          spnt.insert();
  		
  		addSprintMembersProcessor.addDefaultSprintTeamMembers(spnt);

          spntNumbers.push(spnt.number+"");
      }

      // Set successful and return a list of the sprint numbers
      r.setAttribute("result","success");
      return spntNumbers.join(); 
  },
  
  /**
   * Prevent public access to this processor
   */
  isPublic: function() {
  	return false;
  },

  /**
   * _getParams(r): Internal method used to get the parameters
   *
   * r: The retrun values for the AJAX request
   *
   * 1. This method will check that the following parameters have been set:
   *    1.1 _tn         : Table name
   *    1.2 _sys_id     : The sys_id of the record
   *    1.3 spName      : The Name for the Sprint
   *    1.4 spDuration  : Duration of the Sprint
   *    1.5 spStartDate : Start Date of the Sprints
   *    1.6 spStartNum  : The starting number for the Sprints
   *    1.7 spNum       : The number of sprints to create
   */
  _getParams: function(r) {
      var params = {}; //Set up a simple nvp object for parameters

      // Required fields
      params._tn = this._getParam("_tn");
      params._sysId = this._getParam("_sys_id");
      params.spName = this._getParam("spName");
      params.spDuration = this._getParam("spDuration");
      params.spStartDate = this._getParam("spStartDate");
      params.spStartNum = this._getParam("spStartNum");
      params.spNum = this._getParam("spNum");

      if (this._log.atLevel(GSLog.DEBUG)) { 
          this._log.debug("[_getIdParams] Data Received:");
          this._log.debug("[_getIdParams]         _tn: " + params._tn);
          this._log.debug("[_getIdParams]      _sysId: " + params._sysId);
          this._log.debug("[_getIdParams]      spName: " + params.spName);
          this._log.debug("[_getIdParams]  spDuration: " + params.spDuration);
          this._log.debug("[_getIdParams] spStartDate: " + params.spStartDate);
          this._log.debug("[_getIdParams]  spStartNum: " + params.spStartNum);
          this._log.debug("[_getIdParams]       spNum: " + params.spNum);
      }

      // If we don't have any data for the parent record.
      if (JSUtil.nil(params._tn) || JSUtil.nil(params._sysId)) {
          r.setAttribute("result","failure");
          r.setAttribute("reason","The record's Sys Id and table name are required");
      this._log.error("[_getIdParams] Sys Id and table name are required");
          return null;
      }

      // If we don't have any of the other data
      if (JSUtil.nil(params.spName) || JSUtil.nil(params.spDuration) || JSUtil.nil(params.spStartDate) ||
          JSUtil.nil(params.spStartNum) || JSUtil.nil(params.spNum)) {
          r.setAttribute("result","failure");
          r.setAttribute("reason","The required parameters were not provided");
      this._log.error("[_getIdParams] the required parameters were not provided");
          return null;
      }


      return params;
  },

  /* _getParam(prmNm): Gets the parameter named prmNm, checks for spurious undefined and null values and
   *                   returns a string representation.  Returns null if undefined.
   */
  _getParam: function(prmNm) {
      var param = this.getParameter(prmNm)+"";

      if (typeof param === "undefined" || param == "undefined" || param == "null" || param == null || JSUtil.isNil(param))
          return null;

      return param;
  },

  type: 'ScrumAddSprintsAjaxProcessor'
});

Sys ID

154e6ee1c32030003d2ae219cdba8fcc

Offical Documentation

Official Docs: