How do I edit the AssetAndCISynchronizer to include a newly created field?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-25-2016 03:22 PM
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'
};