Name

sn_cmdb_int_util.MakeAndModelAndNumberJs

Description

No description available

Script

//test call:gs.info(new sn_cmdb_int_util.MakeAndModelAndNumberJs().fromNames("Made up Company", "Model1", "modelnumber1", "hardware").model_id_name);

//in order for the de-duplication code to work on all cmdb_model children and on cmdb_model on itself select the "can delete" flag
// on application access then run the following scripts as global:
//GlideTableManager.invalidateTable("cmdb_hardware_product_model");
//GlideCacheManager.flushTable("cmdb_hardware_product_model");
//GlideTableManager.invalidateTable("cmdb_model");
//GlideCacheManager.flushTable("cmdb_model");
//GlideTableManager.invalidateTable("sys_db_object");
//GlideCacheManager.flushTable("sys_db_object");

var MakeAndModelAndNumberJs = Class.create();

/**
*/
MakeAndModelAndNumberJs.prototype = {
  initialize: function(checkFlipNameNumber, checkModelNumberOnlyNoConflicts, checkModelNumberOnly, checkNameOnlyNoConflicts, checkNameOnly, updateEmptyNameFromName, updateEmptyModelNumberFromModelNumber, overwriteIncompleteOnFlipMatch, overwriteOnCurrentModelNumberMatchesName, updateEmptyModelNameFromModelNumber, updateEmptyModelNumberFromName) {

      if (gs.nil(checkFlipNameNumber)) {
          this.MODEL_LOOKUP_FLIP_NAME_NUMBER = gs.getProperty('sn_cmdb_int_util.model_lookup_flip_name_number', 'true') == "true";
      } else {
          this.MODEL_LOOKUP_FLIP_NAME_NUMBER = ("true" == checkFlipNameNumber || true == checkFlipNameNumber);
      }

      //these checkModelNumber and checkName flags relate to the recieved data, not the db table
      if (gs.nil(checkModelNumberOnlyNoConflicts)) {
          this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS = gs.getProperty('sn_cmdb_int_util.model_lookup_check_model_number_only_no_conflicts', 'true') == "true";
      } else {
          this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS = ("true" == checkModelNumberOnlyNoConflicts || true == checkModelNumberOnlyNoConflicts);
      }

      if (gs.nil(checkModelNumberOnly)) {
          this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY = gs.getProperty('sn_cmdb_int_util.model_lookup_check_model_number_only', 'true') == "true";
      } else {
          this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY = ("true" == checkModelNumberOnly || true == checkModelNumberOnly);
      }

      if (gs.nil(checkNameOnlyNoConflicts)) {
          this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS = gs.getProperty('sn_cmdb_int_util.model_lookup_check_name_only_no_conflicts', 'true') == "true";
      } else {
          this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS = ("true" == checkNameOnlyNoConflicts || true == checkNameOnlyNoConflicts);
      }

      if (gs.nil(checkNameOnly)) {
          this.MODEL_LOOKUP_CHECK_NAME_ONLY = gs.getProperty('sn_cmdb_int_util.model_lookup_check_name_only', 'true') == "true";
      } else {
          this.MODEL_LOOKUP_CHECK_NAME_ONLY = ("true" == checkNameOnly || true == checkNameOnly);
      }

      if (gs.nil(updateEmptyNameFromName)) {
          this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME = gs.getProperty('sn_cmdb_int_util.model_update_empty_name_with_name', 'true') == "true";
      } else {
          this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME = ("true" == updateEmptyNameFromName || true == updateEmptyNameFromName);
      }

      if (gs.nil(updateEmptyModelNumberFromModelNumber)) {
          this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER = gs.getProperty('sn_cmdb_int_util.model_update_empty_model_number_with_model_number', 'true') == "true";
      } else {
          this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER = ("true" == updateEmptyModelNumberFromModelNumber || true == updateEmptyModelNumberFromModelNumber);
      }

      if (gs.nil(overwriteIncompleteOnFlipMatch)) {
          this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_incomplete_on_flip_match', 'true') == "true";
      } else {
          this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH = ("true" == overwriteIncompleteOnFlipMatch || true == overwriteIncompleteOnFlipMatch);
      }

      if (gs.nil(overwriteOnCurrentModelNumberMatchesName)) {
          this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_on_current_name_model_number_match', 'true') == "true";
      } else {
          this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = ("true" == overwriteOnCurrentModelNumberMatchesName || true == overwriteOnCurrentModelNumberMatchesName);
      }

      if (gs.nil(updateEmptyModelNameFromModelNumber)) {
          this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = gs.getProperty('sn_cmdb_int_util.model_update_overwrite_on_current_name_model_number_match', 'true') == "true";
      } else {
          this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH = ("true" == updateEmptyModelNameFromModelNumber || true == updateEmptyModelNameFromModelNumber);
      }

      if (gs.nil(updateEmptyModelNameFromModelNumber)) {
          this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER = gs.getProperty('sn_cmdb_int_util.model_update_empty_name_with_model_number', 'true') == "true";
      } else {
          this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER = ("true" == updateEmptyModelNameFromModelNumber || true == updateEmptyModelNameFromModelNumber);
      }

      if (gs.nil(updateEmptyModelNumberFromName)) {
          this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME = gs.getProperty('sn_cmdb_int_util.model_update_empty_model_number_with_name', 'false') == "true";
      } else {
          this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME = ("true" == updateEmptyModelNumberFromName || true == updateEmptyModelNumberFromName);
      }

      this.NAME = 'name';
      this.MANUFACTURER = 'manufacturer';
      this.MODEL_NUMBER = 'model_number';
      this.UNDEFINED = "undefined";
      this.SYS_CLASS_NAME = 'sys_class_name';
      this.SYS_ID = 'sys_id';
      this.CREATED_DATE = "sys_created_on";
      this.TABLE = "table";
      this.FIELD = "field";
      this.DISCOVERED_NAME_HASH = "discovered_name_hash";

      this.CMDB_MODEL = 'cmdb_model';
      this.CMDB_TABLE_NAME_PREFIX = 'cmdb_';
      this.CORE_COMPANY = "core_company";

      this.CMDB_HARDWARE_PRODUCT_MODEL = "cmdb_hardware_product_model";
      this.CMDB_CONSUMABLE_PRODUCT_MODEL = "cmdb_consumable_product_model";
      this.CMDB_SOFTWARE_PRODUCT_MODEL = "cmdb_software_product_model";
      this.CMDB_APPLICATION_PRODUCT_MODEL = "cmdb_application_product_model";

      this.CANONICAL_CLIENT_PLUGIN = "com.glide.data_services_canonicalization.client";

      this.CANONICAL_PROPERTY_COMPANY_ENABLED = "glide.cmdb.canonical.company.enabled";
      this.CANONICAL_PROPERTY_DEBUG = "glide.cmdb.canonical.debug";
      this.CANONICAL_PROPERTY_DISCOVERY_ENABLED = "glide.cmdb.canonical.discovery.enabled";
      this.CANONICAL_PROPERTY_ALWAYS_RUN = "glide.cmdb.canonical.always_run";

      this.SYSCACHE_CANONICAL_NAME = "syscache_canonical_name";
      this.SYSCACHE_CANONICAL_NAME_ID = "syscache_canonical_name_id";

      //Tables
      this.CDS_CLIENT_STAGING = "cds_client_staging";
      this.CDS_CLIENT_MAPPING = "cds_client_mapping";
      this.CDS_CLIENT_NAME = "cds_client_name";

      //Fields
      this.STATE = "state";
      this.SOURCE_FIELD = "source_field";
      this.SOURCE_TABLE = "source_table";
      this.FREQUENCY = "frequency";

      this.DISCOVERED_NAME = "discovered_name";
      this.DISCOVERED_NAME_HASH = "discovered_name_hash";
      this.CANONICAL_NAME = "canonical_name";
      this.CANONICAL_NAME_NAME = this.CANONICAL_NAME + "." + this.NAME;
      this.CANONICAL = "canonical";
      this.HASH = "hash";
      this.CUSTOMER_OVERRIDE = "customer_override";

      //States
      this.READY = "ready";
      this.PROCESSED = "processed";
  },

  fromNames: function(make, model, modelNumber, modelType) {
      var modelTable = this._determineModelTableTableName(modelType);
      return this._fromNames(make, model, modelTable, modelNumber);
  },

  _fromNames: function(mfrName, modelName, modelTable, modelNumber, useCMDBHelperMode) {
      if (gs.nil(useCMDBHelperMode)) {
          useCMDBHelperMode = false;
      }

      var mfr = this._getManufacturerRec(mfrName, useCMDBHelperMode);
      var mfrID = !gs.nil(mfr) ? mfr.getUniqueValue() : null;
      var model = this._getModelRec(mfrID, modelName, modelNumber, modelTable);

      var answer = {};

      if (!gs.nil(model)) {
          answer.model_id_sys_id = model.getUniqueValue();
          answer.model_id_name = model.getValue(this.NAME);
      }

      answer.manufacturer_sys_id = mfrID;
      answer.manufacturer_name = !gs.nil(mfr) ? mfr.getValue(this.NAME) : null;

      return answer;

  },

  _directLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField) {
      var gr = new GlideRecord(modelTable);
      this._initModelTableQuery(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);

      gr.orderBy(this.MODEL_NUMBER);
      gr.query();

      if (!gr.next()) {
          return null;
      }

      return gr;
  },

  _singlePrimaryFieldLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField, primaryFieldWhenSorting) {
      if (gs.nil(primaryFieldWhenSorting)) {
          return this._directLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);
      }

      var gr = new GlideRecord(modelTable);
      this._initModelTableQuery(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField);

      // 2 main sorts
      // if update <non primary field> == true
      //   1. where <non primary field> is empty
      //   2. where current name != number
      //   3. where current name == number
      // else
      //   1. where current name != number (and both non-null)
      //   2. where current name == number
      //   3. where <non primary field> is empty

      var secondaryField = primaryFieldWhenSorting === this.NAME ? this.MODEL_NUMBER : this.NAME;

      if (secondaryField === this.NAME && (this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME || this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER)) {
          gs.debug("Sorting for case when updating empty name");
          return this._sortForUpdatingSecondaryField(gr, this.NAME, modelTable);
      }

      if (secondaryField === this.MODEL_NUMBER && (this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER || this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME)) {
          gs.debug("Sorting for case when updating empty model number");
          return this._sortForUpdatingSecondaryField(gr, this.MODEL_NUMBER, modelTable);
      }

      gs.debug("Sorting for case when not updating empty " + secondaryField);
      return this._sortForNotUpdatingSecondaryField(gr, secondaryField, modelTable);
  },

  _sortForNotUpdatingSecondaryField: function(gr, field, modelTable) {
      gr.orderByDesc(field);
      gr.query();

      var targetRecordSysId = null;

      while (gr.next()) {

          // if the values aren't equal and 
          if (gr.getValue(this.NAME) !== gr.getValue(this.MODEL_NUMBER) && !gs.nil(gr.getValue(this.NAME)) && !gs.nil(gr.getValue(this.MODEL_NUMBER))) {

              return gr;
          }

          // possible match
          if (gr.getValue(this.NAME) === gr.getValue(this.MODEL_NUMBER)) {
              targetRecordSysId = gr.getUniqueValue();
          }

          // if we hit a null then we take the previous best match 
          if (gs.nil(gr.getValue(field))) {

              if (gs.nil(targetRecordSysId)) {
                  return gr;
              }

              var answer = new GlideRecord(modelTable);
              answer.get(targetRecordSysId);
              return answer;
          }
      }

      if (!gs.nil(targetRecordSysId)) {

          var answer2 = new GlideRecord(modelTable);
          answer2.get(targetRecordSysId);
          return answer2;
      }
      return null;
  },

  _sortForUpdatingSecondaryField: function(gr, field, modelTable) {
      gr.orderBy(field);
      gr.query();

      var targetRecordSysId = null;

      while (gr.next()) {
          if (gs.nil(gr.getValue(field))) {
              return gr;
          }

          // possible match
          if (gr.getValue(this.NAME) === gr.getValue(this.MODEL_NUMBER)) {
              targetRecordSysId = gr.getUniqueValue();
          }
          // if they're not equal, return
          else {
              return gr;
          }
      }

      if (!gs.nil(targetRecordSysId)) {
          var answer = new GlideRecord(modelTable);
          answer.get(targetRecordSysId);
          return answer;
      }
      return null;
  },

  /**
   * do all of the lookups for a model on a single model table
   *
   * @return GlideRecord for the target record, else null if record can't be found
   */
  _multiLookupOnModelRec: function(mfrID, modelName, modelNumber, modelTable) {
      var haveModelName = !gs.nil(modelName);
      var haveModelNumber = !gs.nil(modelNumber);

      //conflicts are considered to be the following:
      //non-null does not conflict with null
      //non-null conflicts with non-null (assume different values)

      //lookup on target model table with manf, model_name, model_number (null == null)
      //if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop then lookup on manf, model_name, model_number (null === null) flip name and number
      //if no match && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS prop then lokup on manf and match only if name does not conflict
      //if no match && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY prop then lookup on manf, model_number
      //if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS then lookup on lookup on manf, model_name with model_number and no conflicts with name on model_number
      //if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_NAME_ONLY then lookup on lookup on manf, model_name with model_number
      //if no match && MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS prop then lookup on manf, name, and no conflict on model_number
      //if no match && MODEL_LOOKUP_CHECK_NAME_ONLY prop then lookup on manf, model_name
      //if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS then lookup on lookup on manf, model_number with name and no conflicts with model_number on name 
      //if no match && MODEL_LOOKUP_FLIP_NAME_NUMBER prop && MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY then lookup on lookup on manf, model_number with model_name

      var gr = this._directLookupOnModelRec(mfrID, modelName, modelNumber, modelTable);
  	
  	if (gr) {
              gs.debug("Model match on direct lookup");
          }
  	
      if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER) {
          gr = this._directLookupOnModelRec(mfrID, modelNumber, modelName, modelTable);
  		if (gr) {
              gs.debug("Model match on direct lookup flip");
          }
      }
      if (gr === null && haveModelNumber && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, 'MODEL_NUMBER', null);
          if (gr) {
              gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS");
          }
      }
      if (gr === null && haveModelNumber && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, null, modelNumber, modelTable, null, 'NAME', 'MODEL_NUMBER');
          if (gr) {
              gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY");
          }
      }
      if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, modelName, modelTable, 'NAME', null);
  		if (gr) {
              gs.debug("Model match on MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY_NO_CONFLICTS && MODEL_LOOKUP_FLIP_NAME_NUMBER");
          }
      }
      if (gr === null && haveModelNumber && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, null, modelTable, null, 'MODEL_NUMBER', 'NAME');
  		if (gr) {
              gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_MODEL_NUMBER_ONLY");
          }
      }
      if (gr === null && haveModelName && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, modelNumber, modelTable, 'NAME', null);
  		if (gr) {
              gs.debug("Model match on MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS");
          }
      }
      if (gr === null && haveModelName && this.MODEL_LOOKUP_CHECK_NAME_ONLY) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelName, null, modelTable, null, 'MODEL_NUMBER', 'NAME');
  		if (gr) {
              gs.debug("Model match on MODEL_LOOKUP_CHECK_NAME_ONLY");
          }
      }
      if (gr === null && haveModelName && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, modelNumber, modelName, modelTable, 'MODEL_NUMBER');
  		if (gr) {
              gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY_NO_CONFLICTS");
          }
      }
      if (gr === null && haveModelName && this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY) {
          gr = this._singlePrimaryFieldLookupOnModelRec(mfrID, null, modelName, modelTable, null, 'NAME', 'MODEL_NUMBER');
  		if (gr) {
              gs.debug("Model match on this.MODEL_LOOKUP_FLIP_NAME_NUMBER && this.MODEL_LOOKUP_CHECK_NAME_ONLY");
          }
      }

      return gr;
  },

  _determineModelTableTableName: function(modelType) {
      if (gs.nil(modelType))
          return this.CMDB_MODEL;

      if (modelType.indexOf(this.CMDB_TABLE_NAME_PREFIX) == 0)
          return modelType;

      var mtype = modelType.toLowerCase();
      var table = '';
      switch (mtype) {
          case "hardware":
              table = this.CMDB_HARDWARE_PRODUCT_MODEL;
              break;
          case "consumable":
              table = this.CMDB_CONSUMABLE_PRODUCT_MODEL;
              break;
          case "software":
              table = this.CMDB_SOFTWARE_PRODUCT_MODEL;
              break;
          case "application":
              table = this.CMDB_APPLICATION_PRODUCT_MODEL;
              break;
          default:
              table = this.CMDB_MODEL;
      }
      return table;
  },

  _insertModelRecord: function(mfrID, modelName, modelNumber, modelTable) {
      gs.debug("Creating model with name:" + modelName + " modelNumber:" + modelNumber + " on modelTable:" + modelTable);
      gr = new GlideRecord(modelTable);
      gr.initialize();
      gr.setValue(this.NAME, modelName);
      if (!gs.nil(mfrID)) {
          gr.setValue(this.MANUFACTURER, mfrID);
      }
      if (!gs.nil(modelNumber)) {
          gr.setValue(this.MODEL_NUMBER, modelNumber);
      }

      gr.insert();

      gr = this._doDuplicateCheckModel(gr);

      return gr;
  },

  _getModelRec: function(mfrID, modelName, modelNumber, modelTable) {

      var gr = this._multiLookupOnModelRec(mfrID, modelName, modelNumber, modelTable);

      // check the cmdb_model table
      if (gr === null && modelTable !== this.CMDB_MODEL) {
  					
          gr = this._multiLookupOnModelRec(mfrID, modelName, modelNumber, this.CMDB_MODEL);

          if (gr !== null) {
              // update to the current model table
              gr.setValue(this.SYS_CLASS_NAME, modelTable);
  			gr.update();
          }
      }

      // found a glide record and applying update flags
      if (gr !== null) {

          var lowerModelName = gs.nil(modelName) ? "" : modelName.toLowerCase();
          var lowerModelNumber = gs.nil(modelNumber) ? "" : modelNumber.toLowerCase();
          var lowerGrModelName = gs.nil(gr.getValue(this.NAME)) ? "" : gr.getValue(this.NAME).toLowerCase();
          var lowerGrModelNumber = gs.nil(gr.getValue(this.MODEL_NUMBER)) ? "" : gr.getValue(this.MODEL_NUMBER).toLowerCase();

          var updated = false;
          if (this.MODEL_UPDATE_OVERWRITE_INCOMPLETE_ON_FLIP_MATCH &&
              (lowerModelName === lowerGrModelNumber || lowerModelNumber === lowerGrModelName) &&
              (gs.nil(gr.getValue(this.MODEL_NUMBER)) || gs.nil(gr.getValue(this.NAME))) &&
              (lowerGrModelName !== lowerModelName || lowerGrModelNumber !== lowerModelNumber) &&
              !gs.nil(lowerModelName) && !gs.nil(lowerModelNumber)) {

              gs.debug("Updating record on name and model number flipped match to recieved data");
              gr.setValue(this.NAME, modelName);
              gr.setValue(this.MODEL_NUMBER, modelNumber);
              gr.update();
              updated = true;
          } else if (this.MODEL_UPDATE_OVERWRITE_ON_CURRENT_NAME_MODEL_NUMBER_MATCH &&
              lowerGrModelName === lowerGrModelNumber &&
              lowerModelName !== lowerModelNumber &&
              !gs.nil(lowerModelName) && !gs.nil(lowerModelNumber)) {

              gs.debug("Updating record on name and model number because current model number and name");
              gr.setValue(this.NAME, modelName);
              gr.setValue(this.MODEL_NUMBER, modelNumber);
              gr.update();
              updated = true;
          } else if (gs.nil(lowerGrModelName) && !gs.nil(modelName) && this.MODEL_UPDATE_EMPTY_NAME_WITH_NAME) {

              // first check to see if an update would cause a duplicate
              // if there is no name, then the match was on number == name (a flip)
              var tempNumber = gs.nil(modelNumber) ? modelName : modelNumber;
              var gr2 = this._directLookupOnModelRec(mfrID, modelName, tempNumber, modelTable);

              if (gr2 !== null) {
                  gr = gr2;
              } else {
                  gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with name:" + modelName);
                  gr.setValue(this.NAME, modelName);
                  gr.update();
                  updated = true;
              }
          } else if (gs.nil(lowerGrModelNumber) && !gs.nil(modelNumber) && this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_MODEL_NUMBER) {

              // first check to see if an update would cause a duplicate
              // if there is no name, then the match was on number == name (a flip)
              var tempName = gs.nil(modelName) ? modelNumber : modelName;
              var gr3 = this._directLookupOnModelRec(mfrID, tempName, modelNumber, modelTable);

              if (gr3 !== null) {
                  gr = gr3;
              } else {
                  gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelNumber);
                  gr.setValue(this.MODEL_NUMBER, modelNumber);
                  gr.update();
                  updated = true;
              }
          } else if (this.MODEL_UPDATE_EMPTY_NAME_WITH_MODEL_NUMBER && gs.nil(lowerGrModelName) && !gs.nil(lowerModelNumber)) {

              var gr4 = this._directLookupOnModelRec(mfrID, modelNumber, modelNumber, modelTable);

              if (gr4 !== null) {
                  gr = gr4;
              } else {
                  gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelNumber);
                  gr.setValue(this.NAME, modelNumber);
                  gr.update();
                  updated = true;
              }

          } else if (this.MODEL_UPDATE_EMPTY_MODEL_NUMBER_WITH_NAME && gs.nil(lowerGrModelNumber) && !gs.nil(lowerModelName)) {

              var gr5 = this._directLookupOnModelRec(mfrID, modelName, modelName, modelTable);

              if (gr5 !== null) {
                  gr = gr5;
              } else {
                  gs.info("Updating model with sys_id:" + gr.getUniqueValue() + " with model_number:" + modelName);
                  gr.setValue(this.MODEL_NUMBER, modelName);
                  gr.update();
                  updated = true;
              }
          }

          if (updated) {
              this._doDuplicateCheckModel(gr);
          }
      }
      // no record found, insert
      else if (gr === null) {
          gr = this._insertModelRecord(mfrID, modelName, modelNumber, modelTable);
      }

      return gr;
  },

  _doDuplicateCheckModel: function(gr) {

      var gr2 = new GlideRecord(gr.getTableName());
      gr2.addQuery(this.NAME, gr.getValue(this.NAME));
      gr2.addQuery(this.MANUFACTURER, gr.getValue(this.MANUFACTURER));
      gr2.addQuery(this.MODEL_NUMBER, gr.getValue(this.MODEL_NUMBER));
      gr2.orderBy(this.CREATED_DATE);
      gr2.query();

      var answer = gr;

      if (gr2.getRowCount() > 1) {
          gr2.next();
          var answerGr = new GlideRecord(gr.getTableName());
          answerGr.get(gr2.getUniqueValue());
          answer = answerGr;

          while (gr2.next()) {
              gr2.deleteRecord();
          }
      }

      return answer;
  },

  _doDuplicateCheckCompany: function(gr) {

      var gr2 = new GlideRecord(gr.getTableName());
      gr2.addQuery(this.NAME, gr.getValue(this.NAME));
      gr2.orderBy(this.CREATED_DATE);
      gr2.query();

      var answer = gr;

      if (gr2.getRowCount() > 1) {
          gr2.next();
          var answerGr = new GlideRecord(gr.getTableName());
          answerGr.get(gr2.getUniqueValue());
          answer = answerGr;

          while (gr2.next()) {
              gr2.deleteRecord();
          }
      }

      return answer;
  },

  _initModelTableQuery: function(gr, mfrID, modelName, modelNumber, modelTable, allowNonConflictMatchOnField, ignoreField) {

      gr.addQuery(this.SYS_CLASS_NAME, modelTable);

      if (!gs.nil(mfrID)) {
          gr.addQuery(this.MANUFACTURER, mfrID);
      } else {
          gr.addNullQuery(this.MANUFACTURER);
      }

      if ('NAME' !== ignoreField) {
          if (!gs.nil(modelName)) {
              if ('NAME' === allowNonConflictMatchOnField) {
                  gr.addEncodedQuery('name=' + modelName + '^ORnameISEMPTY');
              } else {
                  gr.addQuery(this.NAME, modelName);
              }
          } else {
              // if we allow non conflicts and this value is null then any value matches
              if ('NAME' !== allowNonConflictMatchOnField) {
                  gr.addNullQuery(this.NAME);
              }
          }
      }

      if ('MODEL_NUMBER' !== ignoreField) {
          if (!gs.nil(modelNumber)) {
              if ('MODEL_NUMBER' === allowNonConflictMatchOnField) {
                  gr.addEncodedQuery('model_number=' + modelNumber + '^ORmodel_numberISEMPTY');
              } else {
                  gr.addQuery(this.MODEL_NUMBER, modelNumber);
              }
          } else {
              // if we allow non conflicts and this value is null then any value matches
              if ('MODEL_NUMBER' !== allowNonConflictMatchOnField) {
                  gr.addNullQuery(this.MODEL_NUMBER);
              }
          }
      }
  },

  _getManufacturerRec: function(mfrName, useCMDBHelperMode) {
      if (gs.nil(mfrName)) {
          return '';
      }

      mfrName = mfrName.trim();

      // PRB1422465:  Need to cut down mfrName to match maximum length of table to prevent creating extra manufacturer records.
      var grInc = new GlideRecord('CORE_COMPANY');

      for (var i = 0; i < grInc.getElements().length; i++) {
          if (grInc.getElements()[i].getED().getName().toLowerCase() === 'name') {
              var nameMaxLength = grInc.getElements()[i].getED().getLength();
              if (mfrName.length() > nameMaxLength)
                  mfrName = mfrName.substring(0, nameMaxLength);
          }
          break;
      }

      var useCanonical = this._useCanonicalLookup();
      gs.debug("getManufacturerRec(): useCanonical=" + useCanonical + ",  mfrName=" + mfrName + ", useCMDBHelperMode=" + useCMDBHelperMode);
      // For performance, try to get rec without a mutex since it will usually exist.
      var gr = this._getManufacturerRecIfExists(mfrName, useCanonical);
      if (gr != null) {
          return gr;
      }

      if (useCanonical) {
          // Get canonical name.  If no canonical name exists, returns same name
          mfrName = this._normalizeCompany(mfrName, true);
      }

      gr = new GlideRecord(this.CORE_COMPANY);
      gr.setValue(this.NAME, mfrName);
      if (useCMDBHelperMode)
          gr.setValue(this.MANUFACTURER, true);

      gr.insert();

      gr = this._doDuplicateCheckCompany(gr);

      return gr;
  },

  _useCanonicalLookup: function() {
      // PRB1292140: Force DISCOVERY_ENABLED on if ALWAYS_RUN on
      return GlidePluginManager.isActive('com.glide.data_services_canonicalization.client') &&
          ((gs.getProperty('glide.cmdb.canonical.discovery.enabled') == "true") ||
              (gs.getProperty('glide.cmdb.canonical.always_run') == "true"));
  },

  _getManufacturerRecIfExists: function(mfrName, useCanonical) {
      var gr = new GlideRecord(this.CORE_COMPANY);
      if (useCanonical) {

          // Get sysid of canonical core_company rec if it exists
          var mfrSysID = this._normalizeCompany(mfrName, false);
          if (gs.nil(mfrSysID))
              return null;

          gr.addQuery(this.SYS_ID, mfrSysID);
          gr.query();
          if (gr.next()) {
              gs.debug("getManufacturerRec(): canconical rec for discovery name =" + mfrName + ", rec name/sysid=" + gr.getValue("name") + " / " + gr.getValue("sys_id"));
              return gr;
          }
      } else {
          // Return the core_company rec if it exists.
          gr.addQuery(this.NAME, mfrName);
          gr.orderBy(this.CREATED_DATE);
          gr.query();
          if (gr.next()) {
              return gr;
          }
      }
      return null; // rec not found
  },

  _normalizeCompany: function(discoveredName, returnName) {
      if (gs.nil(discoveredName))
          return "";

      //If plugin is not active or feature is disabled try to return default information
      if (!GlidePluginManager.isActive(this.CANONICAL_CLIENT_PLUGIN) ||
          !(gs.getProperty(this.CANONICAL_PROPERTY_COMPANY_ENABLED) == 'true')) {
          gs.debug("Returning with default values");

          if (returnName)
              return discoveredName;

          return this._getCoreCompanyId(discoveredName, false);
      }

      var companyName = "";
      var discoveredNameHash = this._getHash(discoveredName);
      if (gs.nil(discoveredNameHash)) {
          gs.warn("Canonical Hash came back empty or invalid for: '" + discoveredName + "'");

          if (returnName)
              return discoveredName;
          return null;
      }

      gs.debug("Canonical Lookup DiscoveredName: '" + discoveredName + "' hash: '" + discoveredNameHash + "'");
      var cacheName = "";

      //If it's not cached, find it and cache it
      if (gs.nil(cacheName)) {
          companyName = this._getCompanyName(discoveredName);
      } else {
          companyName = cacheName;
      }

      gs.info("Discovered Name: '" + discoveredName + "' Canonical is: '" + companyName + "'");
      if (returnName) {
          return companyName;
      }

      //Find the core_company record and return the sys_id
      var companyID = this._getCoreCompanyId(companyName, true);
      gs.info("Discovered Name: " + discoveredName + " core_company is: " + companyID);
      return companyID;
  },

  _getCompanyName: function(discoveredName) {
      return this._getConanicalName(discoveredName, this.CORE_COMPANY, this.NAME);
  },

  _getConanicalName: function(lookupName, tableName, fieldName) {
      var hash = this._getHash(lookupName);

      if (gs.nil(hash)) {
          return lookupName;
      }

      var mapping = new GlideRecord(this.CDS_CLIENT_MAPPING);
      if (!mapping.isValid()) {
          return lookupName;
      }

      mapping.addQuery(this.DISCOVERED_NAME_HASH, hash);
      mapping.addQuery(this.TABLE, tableName);
      mapping.addQuery(this.FIELD, fieldName);
      mapping.query();
      if (mapping.next()) {
          var canonicalName = mapping.canonical_name.name; //getValue(this.CANONICAL_NAME_NAME);

          gs.info("Found canonical name:" + canonicalName + " in Canonical db");

          if (!gs.nil(canonicalName)) {
              return canonicalName;
          }
      }

      gs.debug("DiscoveredName '" + lookupName + "' not found in Canonical db");
      return lookupName;
  },

  _getCoreCompanyId: function(companyName, useHash) {

      var companyNameHash = this._getHash(companyName);

      var coreCompany = new GlideRecord(this.CORE_COMPANY);
      //Use hash or regular name
      if (useHash) {
          coreCompany.addQuery(this.HASH, companyNameHash);
          coreCompany.addQuery(this.CANONICAL, true);
      } else
          coreCompany.addQuery(this.NAME, companyName);

      coreCompany.query();
      if (coreCompany.next()) {
          return coreCompany.getUniqueValue();
      }

      gs.debug("core_company entry not found for: " + companyName);
      return "";
  },

  _getHash: function(value) {
      if (gs.nil(value)) {
          return '';
      }
      return new GlideDigest().md5_digest(value);
  },

  type: 'MakeAndModelAndNumberJs'
};

Sys ID

47003a891b460550ebe09712b24bcb4f

Offical Documentation

Official Docs: