How do I edit the AssetAndCISynchronizer to include a newly created field?

stephaniet
Kilo Expert

I created a new field in both the CMDB and the Asset tables called u_firmware_version.   I would like to add it to the AssetAndCISynchronizer script include so that it updates just like all the other fields do.   Our AssetAndCISynchronizer script is below.   I tried just adding "changes += this._syncField('u_firmware_version', source, destination);"   under the tag "   // synchronize data for fields that have the same name in both tables" but that didn't work.     How do I do this?   Thanks!

var AssetAndCISynchronizer = Class.create();

AssetAndCISynchronizer.prototype = {

  initialize : function() {

  },

  /*

  * Synchronize data between related asset and CI records Record linked to

  * source record in the destination table will get updated

  */

  syncRecords : function(source, destinationBaseTable) {

  var destination = new GlideRecord(destinationBaseTable);

  var foreignKey = (destinationBaseTable == 'alm_asset') ? 'asset' : 'ci';

  var destinationId = source[foreignKey].toString();

  destination = null;

  if ('cmdb_ci' == destinationBaseTable) {

  // when synchronizing to a CI, we have to check first for hardware

  // because

  // some status fields exist only on hardware table

  destination = new GlideRecord('cmdb_ci_hardware');

  // fast forward glide record to proper destination ci,

  // reset to null if no hardware ci found and proceed with base ci

  destination.query("sys_id", destinationId);

  if (!destination.next())

  destination = null;

  }

  if (destination == null) {

  destination = new GlideRecord(destinationBaseTable);

  // fast forward glide record to proper destination record

  // abandon processing if no such record found

  destination.query("sys_id", destinationId);

  if (!destination.next())

  return;

  }

  var changes = this.syncRecordsWithoutUpdate(source, destination,

  destinationBaseTable, false);

  if (changes > 0) {

  destination.skip_sync = true;

  destination.update();

  }

  },

  /*

  * Update the fields of destination record with information from source

  * record but do not trigger an update of the destination record itself

  * if asynchUpdate, destination will be modified even if source hasn't changed

  */

  syncRecordsWithoutUpdate : function(source, destination,

  destinationBaseTable, asyncUpdate) {

  var changes = 0;

  // Sanity protection

  var me = source.getValue('sys_id') + '';

  if ('cmdb_ci' == destinationBaseTable) {

  // Check that we are pointing at ourselves

  var back = destination.getValue('asset') + '';

  if ( back != me) {

  gs.log('Aborting Asset to CI sync due to pointer mismatch');

  return 0;

  }

  }

  if ('alm_asset' == destinationBaseTable) {

  // Check that we are pointing back at ourselves

  var back = destination.getValue('ci') + '';

  if ( back != me) {

  gs.log('Aborting CI to Asset sync due to pointer mismatch');

  return 0;

  }

  }

  // synchronize data for fields that have the same name in both tables

  changes += this._syncField('location', source, destination);

  changes += this._syncField('asset_tag', source, destination);

  changes += this._syncField('serial_number', source, destination);

  changes += this._syncField('assigned_to', source, destination);

  changes += this._syncField('assigned', source, destination);

  changes += this._syncField('checked_in', source, destination);

  changes += this._syncField('checked_out', source, destination);

  changes += this._syncField('company', source, destination);

  changes += this._syncField('cost_center', source, destination);

  changes += this._syncField('delivery_date', source, destination);

  changes += this._syncField('department', source, destination);

  changes += this._syncField('due_in', source, destination);

  changes += this._syncField('due', source, destination);

  changes += this._syncField('gl_account', source, destination);

  changes += this._syncField('invoice_number', source, destination);

  changes += this._syncField('justification', source, destination);

  changes += this._syncField('lease_id', source, destination);

  changes += this._syncField('managed_by', source, destination);

  changes += this._syncField('order_date', source, destination);

  changes += this._syncField('owned_by', source, destination);

  changes += this._syncField('support_group', source, destination);

  changes += this._syncField('supported_by', source, destination);

  changes += this._syncField('vendor', source, destination);

  changes += this._syncField('warranty_expiration', source, destination);

  changes += this._syncField('po_number', source, destination);

  changes += this._syncField('purchase_date', source, destination);

  changes += this._syncField('install_date', source, destination);

  changes += this._syncField('sys_domain', source, destination);

  // fields that differ slightly

  changes += this._syncModel(destinationBaseTable, source, destination);

  changes += this._syncCost(destinationBaseTable, source, destination, asyncUpdate);

  // fields that differ wildly

  changes += this._syncState(destinationBaseTable, source, destination, asyncUpdate);

  return changes;

  },

  /*

  * Simple synchronization: fields have the same name in both tables and

  * value simply need to be carried over

  */

  _syncField : function(fieldName, source, destination) {

  if (source.getElement(fieldName) != destination.getElement(fieldName)) {

  if (!source.getElement(fieldName).hasValue())

  destination.setValue(fieldName, '');

  else

  destination.setValue(fieldName, source.getValue(fieldName));

  return 1;

  }

  return 0;

  },

  /*

  * Model synchronization: model fields are named differently but should hold

  * the same value

  */

  _syncModel : function(destinationBaseTable, source, destination) {

      if ('alm_asset' == destinationBaseTable) {

  if (source.model_id != destination.model) {

  destination.model = source.model_id;

  return 1;

  }

  return 0;

  }

  if ('cmdb_ci' == destinationBaseTable) {

  if (source.model != destination.model_id) {

  destination.model_id = source.model;

  return 1;

  }

  return 0;

  }

  return 0;

  },

  /*

  * Cost synchronization: cost fields are named differently and have

  * different data format

  */

  _syncCost : function(destinationBaseTable, source, destination, asyncUpdate) {

  if ('alm_asset' == destinationBaseTable) {

  if (source.cost.changes() || source.cost_cc.changes() || asyncUpdate) {

  //cost fields are informational only on ci side and cannot be modified

  return 0;

  }

  return 0;

  }

  if ('cmdb_ci' == destinationBaseTable) {

  if (source.cost.changes() || asyncUpdate) {

  var field = source.getElement('cost');

  destination.cost = field.getCurrencyValue();

  destination.cost_cc = field.getCurrencyCode();

  return 2;

  }

  return 0;

  }

  return 0;

  },

  /*

  * State fields are a different in name, number and data format. Careful

  * mapping needs to be done.

  */

  _syncState : function(destinationBaseTable, source, destination, asyncUpdate) {

  if (destinationBaseTable == 'alm_asset')

  return this._inferAssetStatuses(source, destination, asyncUpdate);

  else if (destinationBaseTable == 'cmdb_ci')

  return this._inferCIStatuses(source, destination, asyncUpdate);

  return 0;

  },

  /*

  * Infer asset state fields from ci state fields and update as appropriate

  */

  _inferAssetStatuses : function(ci, asset, asyncUpdate) {

  // HW statuses take precedence over CI statuses

  if (this._isHardwareCI(ci)) {

  if (!ci.hardware_status.changes() && !ci.hardware_substatus.changes() && !asyncUpdate)

  return 0;

  return this._inferAssetStatusesHardware(ci, asset);

  } else {

  if (!ci.install_status.changes() && !asyncUpdate)

  return 0;

  return this._inferAssetStatusesBase(ci, asset);

  }

  },

  /*

  * Infer asset ci fields from asset state fields and update as appropriate

  */

  _inferCIStatuses : function(asset, ci, asyncUpdate) {

  if (!asset.install_status.changes() && !asset.substatus.changes() && !asyncUpdate)

  return 0;

  var changes = this._inferCIStatusesBase(asset, ci);

  if (this._isHardwareCI(ci))

  changes += this._inferCIStatusesHardware(asset, ci);

  return changes;

  },

  /*

  * Look for clues that the ci is a hardware ci

  */

  _isHardwareCI : function(ci) {

  return (ci.hardware_status != undefined);

  },

  /*

  * Figure out what CI install status should be based on asset's state and

  * substate

  */

  _inferCIStatusesBase : function(asset, ci) {

  var status = asset.install_status.toString();

  var substatus = asset.substatus.toString();

  switch (status) {

  case '6':

  ci.install_status = this

  ._inferCIStatusForInStockOrInTransitAsset(substatus);

  return 1;

  case '8':

  ci.install_status = this._inferCIStatusForMissingAsset(substatus);

  return 1;

  case '9':

  ci.install_status = this

  ._inferCIStatusForInStockOrInTransitAsset(substatus);

  return 1;

  default:

  ci.install_status = status;

  return 1;

  }

  },

  /*

  * Figure out what hardware CI status and substatus should be based on

  * asset's state and substate

  */

  _inferCIStatusesHardware : function(asset, ci) {

  var status = asset.install_status.toString();

  var substatus = asset.substatus.toString();

  switch (status) {

  case '1':

  ci.hardware_status = 'installed';

  ci.hardware_substatus = 'in_use';

  return 2;

  case '2':

  ci.hardware_status = 'on_order';

  ci.hardware_substatus = '';

  return 2;

  case '3':

  ci.hardware_status = 'in_maintenance';

  ci.hardware_substatus = '';

  return 2;

  case '6':

  ci.hardware_status = this

  ._inferHardwareCIStatusForInStockAsset(substatus);

  ci.hardware_substatus = this

  ._inferHardwareCISubtatusForInStockAsset(substatus);

  return 2;

  case '7':

  ci.hardware_status = 'retired';

  ci.hardware_substatus = this

  ._inferHardwareCISubtatusForRetiredAsset(substatus);

  return 2;

  case '8':

  if ('lost' == substatus) {

  ci.hardware_status = 'retired';

  ci.hardware_substatus = 'lost';

  } else {

  ci.hardware_status = 'stolen';

  ci.hardware_substatus = '';

  }

  return 2;

  case '9':

  ci.hardware_status = 'in_transit';

  ci.hardware_substatus = this

  ._inferHardwareCISubtatusForInTransitAsset(substatus);

  return 2;

  default:

  return 0;

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferHardwareCIStatusForInStockAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'available':

  case 'reserved':

  return 'in_stock';

  case 'pending_disposal':

  return 'in_disposition';

  default:

  return assetSubstatus;

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferHardwareCISubtatusForInStockAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'available':

  case 'reserved':

  return assetSubstatus;

  default:

  return '';

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferHardwareCISubtatusForRetiredAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'disposed':

  return 'scrapped';

  case 'vendor_credit':

  return 'credit';

  default:

  return assetSubstatus;

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferHardwareCISubtatusForInTransitAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'defective':

  return 'repairable';

  case 'pending_disposal':

  return 'disposable';

  case 'pending_install':

  return 'reserved';

  default:

  return assetSubstatus;

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferCIStatusForInStockOrInTransitAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'pending_install':

  return '4';

  case 'pending_repair':

  case 'defective':

  return '5';

  default:

  return '6';

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferCIStatusForMissingAsset : function(assetSubstatus) {

  switch (assetSubstatus) {

  case 'stolen':

  return '8';

  default:

  return '100'; // lost

  }

  },

  /*

  * Figure out what asset state and substate should be based on ci's install

  * status

  */

  _inferAssetStatusesBase : function(ci, asset) {

  var status = '';

  var substatus = '';

  status = ci.install_status.toString();

  switch (status) {

  case '4':

  asset.install_status = '6';

  asset.substatus = 'pending_install';

  return 2;

  case '5':

  asset.install_status = '6';

  asset.substatus = 'pending_repair';

  return 2;

  case '6':

  asset.install_status = '6';

  asset.substatus = 'available';

  return 2;

  case '8':

  asset.install_status = '8';

  asset.substatus = 'stolen';

  return 2;

  case '100':

  asset.install_status = '8';

  asset.substatus = 'lost';

  return 2;

  default:

  asset.install_status = ci.install_status;

  asset.substatus = '';

  return 2;

  }

  },

  /*

  * Figure out what asset state and substate should be based on hardware ci's

  * state and substate

  */

  _inferAssetStatusesHardware : function(ci, asset) {

  var status = '';

  var substatus = '';

  var hwStatus = ci.hardware_status.toString();

  var hwSubstatus = ci.hardware_substatus.toString();

  switch (hwStatus) {

  case 'installed':

  asset.install_status = '1';

  asset.substatus = '';

  return 2;

  case 'in_maintenance':

  asset.install_status = '3';

  asset.substatus = '';

  return 2;

  case 'in_stock':

  asset.install_status = '6';

  asset.substatus = this._inferAssetSubstatusFromHWStatusFields(

  hwStatus, hwSubstatus);

  return 2;

  case 'in_transit':

  asset.install_status = '9';

  asset.substatus = this._inferAssetSubstatusFromHWStatusFields(

  hwStatus, hwSubstatus);

  return 2;

  case 'defective':

  asset.install_status = '6';

  asset.substatus = 'defective';

  return 2;

  case 'in_disposition':

  asset.install_status = '6';

  asset.substatus = 'pending_disposal';

  return 2;

  case 'retired':

  // duplicate error is irrelevant for asset -> no change

  if ('duplicate_error' == hwSubstatus)

  return 0;

  // valid retirement reasons

  asset.install_status = this

  ._inferAssetStatusFromHWSubstatusForRetiredCI(hwSubstatus);

  asset.substatus = this._inferAssetSubstatusFromHWStatusFields(

  hwStatus, hwSubstatus);

  return 2;

  case 'on_order':

  asset.install_status = '2';

  asset.substatus = '';

  return 2;

  case 'pending_transfer':

  asset.install_status = '6';

  asset.substatus = 'pending_transfer';

  return 2;

  case 'stolen':

  asset.install_status = '8';

  asset.substatus = 'stolen';

  return 2;

  case 'pending_install':

  asset.install_status = '6';

  asset.substatus = 'pending_install';

  return 2;

  case 'pending_repair':

  asset.install_status = '6';

  asset.substatus = 'pending_repair';

  return 2;

  case 'out_of_stock':

  // out of stock is irrelevant for asset -> no change

  return 0;

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferAssetStatusFromHWSubstatusForRetiredCI : function(hwSubstatus) {

  switch (hwSubstatus) {

  case 'lost':

  case 'stolen':

  return '8';

  default:

  return '7';

  }

  },

  /*

  * Helper to reduce the depth of switch statement

  */

  _inferAssetSubstatusFromHWStatusFields : function(hwStatus, hwSubstatus) {

  switch (hwSubstatus) {

  case 'in_use':

  case 'received':

  return 'available';

  case 'repairable':

  if ('in_transit' == hwStatus)

  return 'defective';

  return 'pending_repair';

  case 'disposable':

  return 'pending_disposal';

  case 'credit':

  return 'vendor_credit';

  case 'scrapped':

  return 'disposed';

  case 'donated':

  return 'donated';

  case 'reserved':

  case 'lost':

  case 'sold':

  case 'available':

  case 'stolen':

  return hwSubstatus;

  default:

  return '';

  }

  },

  type : 'AssetAndCISynchronizer'

};