Name

global.ConditionChecks

Description

This class is used to check for matching conditions, such as for Contract expirations and License Compliance - defined in the clm_condition_check table.

Script

//This class handles checking for any condition checks that are defined on a contract
gs.include("PrototypeServer");

var ConditionChecks = Class.create();
ConditionChecks.prototype = {
  
  initialize: function() {
      this.checks = new Array(); // 2 dimension array [field].[check]
      this.tableNames = {};
      this.debug = false;
  },
  
  /**
   * Check conditions for the specified table
   */
  check: function(tableName) {
      this._getChecks(tableName);
  	var enableBatching = gs.getProperty('contract_compliance_check_job.batching');
  	if(enableBatching === 'true') {
  		var batchSize = gs.getProperty('contract_compliance_check_job.batchSize');
  		this.processInBatches(tableName, batchSize);
  	} else {
  		//Process each record individually
  		var gr = new GlideRecord(tableName);
  		if (gr.isValid()) {
  			gr.query();
  			while (gr.next()) {
  					this._checkRecord(gr);
  			}
  		}
  	}
  },
  
  /**
   * Check conditions for all tables specified in the clm_condition_check table
   */
  checkAll: function() {
      this._getTableNames();
      for (tableName in this.tableNames) {
          this.check(tableName);
      }
  },
  
  
  /**
   * Check the condition for a single record, record should be an instanceOf(tb)
   */
  checkRecord: function(gr, cls) {
      if (JSUtil.nil(gr))
          return;
      
      if (cls == undefined){
          this._getChecks( gr.getTableName());
      } else {
          if (!gr.instanceOf(cls)) {
              gs.log("***** ERROR *****: The GlideRecord passed to checkRecord has to be the instance of the class passed as parameter");
              return;
          }
          this._getChecks(cls);
      }
      this._checkRecord(gr);
  },
  
  /**
   * Check the condition for a single record when we have already read the condition checks for the table
   * DSZ - checks are grouped by check.field and executed until the first check for the field is triggered
   *
   */
  _checkRecord: function(gr) {
      var check = null;
      var checksLen = 0;
      var fieldType = '';
      
      // loop through the field name array
      for (var f in this.checks) {
          checksLen = this.checks[f].length;
          // loop through the checks for field and stop at first natching
          for (var j = 0; j < checksLen; j++) {
              check = this.checks[f][j];
               if (this._checkFilter(gr, check.table, check.filter)){
                  //if (check.matcher.match(gr, true)) {
                      this.updateRecord(check, gr);
                      break;
                  }
              } // for through checks
          } // for through field
      },

      _checkFilter: function(gr, table, filter) {
          var cr = new GlideRecord(table);
          cr.addEncodedQuery(filter);
          cr.addQuery('sys_id', gr.sys_id);
          cr.query();
          if (cr.getRowCount() == 1)
              return true;
          else
              return false;
      },

      /**
       * Get all of the tables that are specified in the expiration definition
       */
      _getTableNames: function() {
          this.tableNames = {};
          var gr = new GlideRecord("clm_condition_check");
          gr.query();
          while (gr.next()) {
              this.tableNames[gr.table.toString()] = true;
          }
      },
      
      /**
       * Get the condition checks for the specified table
       * DSZ - added the loop if many checks for the same table
       */
      _getChecks: function(tableName) {
          this.checks = [];
          var eventName = '';
          // see if the condition has an overall event name
          var gr = new GlideRecord('clm_condition_check');
          gr.initialize();
          gr.addQuery('table', tableName);
          gr.orderBy('order');
          gr.query();
          while (gr.next()) {
              eventName = gr.event_name.toString();
              checkSysId = gr.sys_id.toString();
              var fieldName = gr.condition_field.toString();
              this.checks[fieldName] = new Array();
              // now get the checks and put them in sub-array
              var grCh = new GlideRecord('clm_condition_checker');
              grCh.initialize();
              grCh.addQuery('condition_check', checkSysId);
              grCh.orderBy('order');
              grCh.query();
              while (grCh.next()) {
                  var check = {}; //create new object
  				check.name = grCh.name.toString();
                  check.sys_id = (check.name == '')? '' : grCh.sys_id.toString();
                  check.field = fieldName;
                  check.table = grCh.table;
                  check.filter = grCh.condition.toString();
                  check.matcher = new GlideFilter(grCh.condition, "condition");
                  if (grCh.event_name) {
                      check.event_name = grCh.event_name.toString();
                  } else {
                      check.event_name = eventName;
                  }
                  this.checks[fieldName].push(check);
              }
          }
      },
  	
  	/**
       * Process the table record in batches
       */
  	processInBatches: function(tableName, batchSize) {
  		var count = 0;
  		var contractArray = [];
  		var cGr = new GlideRecord(tableName);
  		cGr.query();
  		while(cGr.next()) {
  			contractArray.push(cGr.getUniqueValue());
  			count = count + 1;
  			if(count == batchSize)
  			{
  				this.processPerCheck(tableName,contractArray);
  				count = 0;
  				contractArray = [];
  				//break;
  			}
  		}
  		if(contractArray.length>0) {
  			this.processPerCheck(tableName,contractArray);
  		}
  	},

  	/**
       * Process the batch and run all the checks on them
       */
  	processPerCheck: function(tableName, contractArray) {
  		var check = null;
  		var checksLen = 0;
  		var fieldType = '';
  		var gr;
  		var recordsToProcess = [];
  		// loop through the field name array
  		for (var f in this.checks) {
  			checksLen = this.checks[f].length;
  			recordsToProcess = [];
  			recordsToProcess = contractArray.slice();
  		
  			for (var j = 0; j < checksLen; j++) {
  				check = this.checks[f][j];
  				gr = new GlideRecord(tableName);
  				gr.addEncodedQuery(check.filter);
  				gr.addQuery('sys_id', 'IN', recordsToProcess);
  				gr.query();
  				while(gr.next()) {
  					recordsToProcess.splice(recordsToProcess.indexOf(gr.getUniqueValue()), 1);
  					this.updateRecord(check, gr);
  				}
  			}
          }
      },
      
  	updateRecord: function(check, gr) {
  		var fieldType = gr[check.field].getED().getInternalType();
  		if (fieldType == 'reference' && gr[check.field] != check.sys_id) {
  			gr[check.field] = check.sys_id;
  			gr.update();
  			// Notify email notifications
  			if (check.event_name) {
  				gs.eventQueue(check.event_name, gr, check.sys_id, check.name);
  			}
  		} else if(fieldType != 'reference' && gr[check.field] != check.name) {
  			gr[check.field] = check.name;
  			gr.update();
  			// Notify email notifications
  			if (check.event_name) {
  				gs.eventQueue(check.event_name, gr, check.sys_id, check.name);
  			}
  		}
  	},

      z: null
  };

Sys ID

48806fec0a258102008850ee3f896a05

Offical Documentation

Official Docs: