Name
global.ProcurementUtils
Description
Utilities to handle PO/POL and asset creation
Script
var ProcurementUtils = Class.create();
ProcurementUtils.CONSUME_ASSET_TASK_TABLE = 'consume_asset_task';
ProcurementUtils.TRANSFER_ORDER_LINE_TABLE = 'alm_transfer_order_line';
ProcurementUtils.PURCHASE_ORDER_LINE_ITEM_TABLE = 'proc_po_item';
ProcurementUtils.ASSET_OPERATIONS = {
CREATE: 'create',
DELETE: 'delete'
};
ProcurementUtils.prototype = {
METRIC_GROUP_MICROSOFT : "85253c9593222200caef14f1b47ffb02",
LICENSE_METRIC_MS_PER_CORE : "ef64c370534323005d74ddeeff7b1238",
LICENSE_METRIC_MS_PER_CORE_WITH_CAL : "22796ca493322200f2ef14f1b47ffb28",
initialize: function() {
this.failedAssets = [];
this.isSAMSActive = GlidePluginManager.isActive('com.snc.sams');
this.isHAMPActive = GlidePluginManager.isActive('com.sn_hamp');
this.isEAMActive = GlidePluginManager.isActive('com.sn_eam');
this.isITAMCommonActive = GlidePluginManager.isActive('com.sn_itam_common');
this.procurementIntegrationActive = GlidePluginManager.isActive('com.sn_asset_proc_int');
},
createPO: function(request, vendor, destination) {
var po = new GlideRecord('proc_po');
po.due_by = request.due_date;
po.init_request = request.sys_id;
po.requested_by = request.opened_by;
po.requested_for = request.requested_for;
po.location = request.location;
po.vendor = vendor;
po.ship_to = destination;
po.insert();
return po;
},
createPOLine: function(po, item, qty, vendor, consolidate, destination, vendorPrice, listPrice, metricGroup, licenseMetric, partNumber, model) {
if (po == '') {
po = this._findPO(item, vendor, consolidate, destination);
}
var pol = new GlideRecord('proc_po_item');
pol.purchase_order = po.sys_id;
// Keeping the existing code as is and updating part number only for stock orders
pol.part_number = item.cat_item.product_id;
if (gs.nil(pol.part_number)) {
pol.part_number = partNumber;
}
//Consider model variable for Stock order item
if(!item.cat_item.model.nil()){
pol.model = item.cat_item.model;
}
else if(this.isHAMPActive
&& sn_hamp.StockOrderUtils && sn_hamp.StockOrderUtils.isStockOrderItem
&& sn_hamp.StockOrderUtils.isStockOrderItem(item.cat_item.sys_id)) {
pol.model = item.variables.model;
pol.stock_order = true;
pol.part_number = partNumber;
}
else if(this.isEAMActive
&& sn_eam.StockOrderUtils && sn_eam.StockOrderUtils.isStockOrderItem
&& sn_eam.StockOrderUtils.isStockOrderItem(item.cat_item.sys_id)) {
pol.model = item.variables.model;
pol.stock_order = true;
pol.part_number = partNumber;
}
else {
// model varibale passed in arguments will be set as POL model
pol.model = model;
}
pol.product_catalog = item.cat_item;
if (vendor == '') {
pol.vendor = item.cat_item.vendor;
}
else {
pol.vendor = vendor;
}
qty = (qty == '' || qty == 0)? item.quantity : qty;
pol.ordered_quantity = qty;
pol.received_quantity = 0;
pol.remaining_quantity = qty;
pol.cost = (vendorPrice == null || vendorPrice == undefined)? '' : vendorPrice;
pol.list_price = (listPrice == null || listPrice == undefined || listPrice == 0)? pol.cost : listPrice;
pol.short_description = item.cat_item.short_description;
pol.request_line = item.sys_id;
pol.requested_for = item.request.requested_for; //PRB633017 - requested_for should be the requested_for of the Request not the purchase order
if (this.isSAMSActive && item.cat_item.model.sys_class_name == 'cmdb_software_product_model') {
if (metricGroup && licenseMetric) {
pol.metric_group = metricGroup;
pol.license_metric = licenseMetric;
//check if this is for Microsoft Per Core or Per Core(with CAL)
if ((metricGroup === this.METRIC_GROUP_MICROSOFT) &&
(licenseMetric === this.LICENSE_METRIC_MS_PER_CORE || licenseMetric === this.LICENSE_METRIC_MS_PER_CORE_WITH_CAL)) {
pol.rights_per_license_pack = 1;
pol.number_of_packs = qty;
}
} else {
gs.info('[ProcurementUtils] License Metric and Group not provided or invalid (' + metricGroup + ', ' + licenseMetric + ')');
}
}
return pol.insert();
},
createAsset: function(po) {
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.query();
while (pol.next()) {
this.createPOLineAssets(pol);
}
},
createPOLineAssets: function(pol) {
if (pol.status == 'canceled' || pol.status == 'received' || pol.status == 'pending') {
return;
}
var qty = pol.remaining_quantity;
var type = (new AssetUtils()).getAssetOrConsumable(pol.model);
if (type == 'consumable') {
this._createConsumable(pol.purchase_order, pol, qty, 2);
} else if (type == 'software') {
for (var x = 0; x < qty; x++) {
this._createSoftware(pol.purchase_order, pol, 2);
}
} else if (type == 'bundle' && this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils._createBundle) {
for (var x = 0; x < qty; x++) {
sn_hamp.HAMProcurementUtils._createBundle(pol.purchase_order, pol, 2);
}
}
else if (type == 'hardware' || type == 'asset') {
for (var x = 0; x < qty; x++) {
this._createAsset(pol.purchase_order, pol, 2);
}
}
},
hasHardwarePO: function(po){
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.query();
while (pol.next()){
if(this.hasHardwarePOLineItem(pol)) {
return true;
}
}
return false;
},
hasHardwarePOLineItem: function(pol, isStatusPendingAllowed){
var allowedStatuses = ['canceled', 'received'];
if(!isStatusPendingAllowed){
allowedStatuses.push('pending');
}
if (pol.status && allowedStatuses.indexOf(pol.status.toString()) == -1) {
var qty = pol.remaining_quantity;
var type = (new AssetUtils()).getAssetOrConsumable(pol.model);
if (type == 'hardware' || type =='asset') {
return true;
}
}
return false;
},
hasHardwareAssetsForPO: function(po){
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.query();
while (pol.next()){
if(this.hasHardwareAssetsForPOL(pol)) {
return true;
}
}
return false;
},
hasHardwareAssetsForPOL: function(pol){
var assetRec = new GlideRecord('alm_asset');
assetRec.addQuery("purchase_line", pol.sys_id);
assetRec.query();
if(assetRec.next())
return true;
else return false;
},
createHardwareAssetsPriorToDelivery: function(po){
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.query();
while (pol.next()) {
this.createPOLineHardwareAssetsPriorToDelivery(pol);
}
},
/* get number of in transit assets for the particular POL */
getNumInTransit: function(pol) {
var countInTransit = new GlideRecord('alm_asset');
countInTransit.addQuery('install_status', 9);
countInTransit.addQuery('purchase_line', pol.sys_id);
countInTransit.query();
return countInTransit.getRowCount();
},
createPOLineHardwareAssetsPriorToDelivery: function(pol, isStatusPendingAllowed) {
if (this.hasHardwarePOLineItem(pol, isStatusPendingAllowed)) {
var count = 0;
if (this.isHAMPActive || this.isEAMActive) {
count = this.getNumInTransit(pol);
}
var qty = pol.remaining_quantity;
for (var x = 0; x < (qty - count); x++) {
this._createAsset(pol.purchase_order, pol, 2);
}
}
},
poHasPurchaseOrderLineItems: function(po) {
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.query();
return pol.hasNext();
},
poHasReceivingSlip: function(po) {
var rsl = new GlideRecord('proc_rec_slip');
rsl.addQuery('purchase_order', po.sys_id);
rsl.query();
return rsl.hasNext();
},
polHasReceivingSlipLine: function(po1) {
var rs = new GlideRecord('proc_rec_slip_item');
rs.addQuery('purchase_line', po1.sys_id);
rs.query();
return rs.hasNext();
},
getPOStatusFromPOL: function(polRecord) {
var gr = new GlideRecord('proc_po');
if (gr.get(polRecord.purchase_order)) {
return gr.status;
}
return undefined;
},
updatePurchaseOrderQuantities: function(rsl) {
var pol = new GlideRecord('proc_po_item');
pol.get(rsl.purchase_line);
var relatedRSL = new GlideRecord('proc_rec_slip_item');
relatedRSL.addQuery('purchase_line', pol.sys_id);
relatedRSL.query();
pol.received_quantity = 0;
while (relatedRSL.next()) {
pol.received_quantity += relatedRSL.quantity;
}
pol.remaining_quantity = pol.ordered_quantity-pol.received_quantity;
if (pol.remaining_quantity < 0) {
pol.remaining_quantity = 0;
}
if (pol.remaining_quantity == 0) {
pol.status = "received";
}
pol.update();
},
createReceiptSlip: function(po, stockroom) {
var rs = new GlideRecord('proc_rec_slip');
rs.initialize();
rs.received = gs.nowDateTime();
rs.purchase_order = po.sys_id;
rs.stockroom = stockroom;
rs.insert();
return rs;
},
/* Same as Create Asset BR on Receiving Line */
_selectOrCreateAsset: function(rsl, assetSysIds, swAssetCount, reserve, assetDetails) {
if (!rsl.purchase_line.nil() &&
rsl.quantity > 0 &&
rsl.purchase_line.model.asset_tracking_strategy != 'do_not_track') {
var type = (new AssetUtils()).getAssetOrConsumable(rsl.purchase_line.model);
if (type == 'consumable') {
this.createRecSlipLineConsumables(rsl.purchase_line, rsl, rsl.quantity);
}
else if(type == 'software') {
/* Create software assets with same no of asset details with rights provided with asset details.
* Rights will get updated as part of Slip line creation */
this.createRecSlipLineAssets(rsl.purchase_line, rsl, swAssetCount, assetSysIds, reserve, assetDetails);
} else if (type == 'bundle' && this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.createRecSlipLineBundle) {
sn_hamp.HAMProcurementUtils.createRecSlipLineBundle(rsl.purchase_line, rsl, parseInt(rsl.quantity), assetSysIds, reserve, assetDetails);
} else {
var quantity = parseInt(rsl.quantity);
this.createRecSlipLineAssets(rsl.purchase_line, rsl, quantity, assetSysIds, reserve, assetDetails);
}
}
},
/* same as Update Purchase Order Line BR on Receiving Line */
_updatePOLine: function(rsl) {
if(!rsl.purchase_order.nil()) {
this.updatePurchaseOrderQuantities(rsl);
}
},
createReceiptSlipLineWithAssetDetails: function(rec_slip, pol, qty, costWithCurrency, requestedFor, assetDetails, reserve, isSoftwareItem) {
this.failedAssets = [];
var assetTable = 'alm_asset';
var hasAssetPregenerated = false;
/* By default create single software asset with rights equals to quantity requested.
* But user can split the license asset while define asset details, so consider it.*/
var swAssetCount = 1;
if (!gs.nil(assetDetails) && assetDetails.length > 1) {
swAssetCount = assetDetails.length;
}
if (isSoftwareItem) {
assetTable = 'alm_license';
}
/* Get sys_ids of details for specific sys_ids, if case of pre-created assets */
var assetSysids = [];
for (var i = 0; i < assetDetails.length; i++) {
if (!gs.nil(assetDetails[i]['sys_id'])) {
assetSysids.push(assetDetails[i]['sys_id']);
}
}
if (assetSysids.length > 0) {
hasAssetPregenerated = true;
}
var rsl = new GlideRecord('proc_rec_slip_item');
rsl.initialize();
rsl.purchase_line = pol.sys_id;
rsl.requested_for = requestedFor;
rsl.received = gs.nowDateTime();
rsl.received_by = gs.getUserID();
rsl.receiving_slip = rec_slip.sys_id;
rsl.quantity = qty;
rsl.setDisplayValue('cost', costWithCurrency);
rsl.setWorkflow(false); /* Avoid BR getting trigger in case of assets are pre-created */
var rslId = rsl.insert();
rsl = new GlideRecord('proc_rec_slip_item');
rsl.get(rslId);
/* Handle BRs work */
this._selectOrCreateAsset(rsl, assetSysids, swAssetCount, reserve, assetDetails);
rsl.quantity = rsl.quantity - this.failedAssets.length;
if (parseInt(rsl.quantity) === 0) {
rsl.deleteRecord();
return this.failedAssets;
} else {
rsl.update();
}
this._updatePOLine(rsl);
/* Handle asset tags, asset serials, and asset reservation */
var assetGR = new GlideRecord(assetTable);
assetGR.addQuery('receiving_line', rslId);
/* In case of pre-generated asset selection, restrict query to selcted assets only */
if (!gs.nil(assetSysids) && assetSysids.length > 0) {
assetGR.addQuery('sys_id', 'IN', assetSysids);
}
assetGR.query();
/* For every asset matching the receiving line (created assets for the POL) update details */
while (assetGR.next()) {
var details;
/* If assets are pre-generated then select asset as per user selection only */
if (hasAssetPregenerated) {
details = findAssetDetails(assetGR.sys_id);
} else { /* else sys ids are attached to assetDetails obj during creation. */
details = findAssetDetails(assetGR.sys_id);
}
if (!gs.nil(details) && !gs.nil(details[0])) {
updateAsset(assetGR, details[0], reserve, hasAssetPregenerated, requestedFor);
}
}
return this.failedAssets;
function updateAsset(assetGR, details, reserve, hasAssetPregenerated, requestedFor) {
var isHAMPActive = GlidePluginManager.isActive('com.sn_hamp');
/* Do not update Asset details if the assets are pre-generated, because the user is not allowed to
* provide any details. It is to avoid unncessary activity logs for respective Asset */
// Asset details are updated for pre-generated assets only when purchase order is received through mobile
if (!hasAssetPregenerated) {
// Software fields: license_key, rights
// Asset Tag and Serial Number
if (details.asset_tag) {
assetGR.setValue('asset_tag', details.asset_tag);
}
if (details.serial_number) {
assetGR.setValue('serial_number', details.serial_number);
}
if (isSoftwareItem) {
if (details.license_key) {
assetGR.setValue('license_key', details.license_key);
}
if (details.rights) {
assetGR.setValue('rights', details.rights);
}
assetGR.cost = assetGR.receiving_line.cost.getReferenceCurrencyCode() + ';' + String(parseFloat(assetGR.receiving_line.cost.getReferenceValue()) * assetGR.rights);
}
if (!isHAMPActive || !sn_hamp.HAMProcurementUtils || String(assetGR.sys_class_name) !== sn_hamp.HAMProcurementUtils.BUNDLE_TABLE) {
if (!gs.nil(details.reserved_for) && !gs.nil(details.reserved_for.value)) {
assetGR.setValue('reserved_for', details.reserved_for.value);
if (!isSoftwareItem) {
assetGR.setValue('substatus', "reserved");
}
} else if (reserve) {
// If reserve toggle in Receive screen is turned on, mark the asset as Reserved
assetGR.setValue('reserved_for', requestedFor);
}
}
}
if (isHAMPActive && sn_hamp.HAMProcurementUtils && String(assetGR.sys_class_name) === sn_hamp.HAMProcurementUtils.BUNDLE_TABLE) {
assetGR.setValue('substatus', "");
}
else if (reserve) {
assetGR.setValue('substatus', "reserved");
}
assetGR.salvage_value = pol.model.salvage_value;
assetGR.depreciation = pol.model.depreciation;
if (!gs.nil(assetGR.depreciation) && gs.nil(assetGR.depreciation_date)
&& AssetUtils.shouldUpdateDepreciationValues(assetGR.sys_class_name)) {
assetGR.depreciation_date = assetGR.receiving_line.received;
}
assetGR.update();
}
function findAssetDetails(sysId) {
var asset;
/* Find details of specific asset by sys_id */
for (var i = 0; i < assetDetails.length; i++) {
if (sysId == assetDetails[i].sys_id) {
asset = assetDetails.splice(i, 1);
break;
}
}
return asset;
}
},
createReceiptSlipLine: function(rec_slip, pol, qty, costWithCurrency, requestedFor, tags, serials, reserve, isSoftwareItem, rights, licenseKeys) {
var assetTable = 'alm_asset';
if (isSoftwareItem) {
assetTable = 'alm_license';
}
var rslGr = new GlideRecord('proc_rec_slip_item');
rslGr.initialize();
rslGr.purchase_line = pol.sys_id;
rslGr.requested_for = requestedFor;
rslGr.received = gs.nowDateTime();
rslGr.received_by = gs.getUserID();
rslGr.receiving_slip = rec_slip.sys_id;
rslGr.quantity = qty;
rslGr.setDisplayValue('cost', costWithCurrency);
var rslId = rslGr.insert();
// Handle asset tags, asset serials, and asset reservation
var asset = new GlideRecord(assetTable);
asset.addQuery('receiving_line', rslId);
asset.query();
for (var x = 0; x < qty; x++) {
var tag = '';
var serial = '';
var licenseKey = '';
if (tags && x < tags.length && tags[x]) {
tag = tags[x];
}
if (serials && x < serials.length && serials[x]) {
serial = serials[x];
}
if (licenseKeys && x < licenseKeys.length && licenseKeys[x]) {
licenseKey = licenseKeys[x];
}
if (asset.next()) {
if (licenseKey) { asset.license_key = licenseKey; }
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && String(asset.sys_class_name) === sn_hamp.HAMProcurementUtils.BUNDLE_TABLE) {
asset.substatus = "";
}
else if (reserve) {
asset.substatus = "reserved";
}
if (serial) { asset.serial_number = serial; }
if (rights) { asset.rights = rights; }
if (tag) { asset.asset_tag = tag; }
asset.salvage_value = pol.model.salvage_value;
asset.depreciation = pol.model.depreciation;
asset.update();
}
}
return rslId;
},
createReceiptSlipLineForSAMP: function(rec_slip, polGr, pol) {
var rslGr = new GlideRecord('proc_rec_slip_item');
rslGr.initialize();
rslGr.purchase_line = polGr.sys_id;
rslGr.requested_for = pol.requested_for.sys_id;
rslGr.received = gs.nowDateTime();
rslGr.received_by = gs.getUserID();
rslGr.receiving_slip = rec_slip.sys_id;
rslGr.quantity = pol.receiving_quantity;
rslGr.setDisplayValue('cost', pol.cost_with_currency);
var rslId = rslGr.insert(); // Inserting the Receiving Slip Line will call createRecSlipLineAssets() from a BR
// Handle asset tag, serial number
var licGr = new GlideRecord('alm_license');
licGr.addQuery('receiving_line', rslId);
licGr.query();
if (licGr.next()) {
if (pol.asset_tag) {
licGr.asset_tag = pol.asset_tag || "";
}
licGr.serial_number = pol.serial_number || "";
licGr.update();
// Create license keys defined in the PO receive page
if (pol.licenseKeys && pol.licenseKeys.length) {
var lkGr;
for (var lk = 0; lk < pol.licenseKeys.length; lk++) {
lkGr = new GlideRecord('samp_sw_license_key');
lkGr.initialize();
lkGr.software_entitlement = licGr.sys_id + '';
lkGr.license_key = pol.licenseKeys[lk].license_key;
lkGr.insert();
}
}
}
},
createRecSlipLineConsumables: function(pol, rsl, qty) {
var po = new GlideRecord('proc_po');
po.get(pol.purchase_order);
var rs = new GlideRecord('proc_rec_slip');
rs.get(rsl.receiving_slip);
var asset = new GlideRecord('alm_asset');
asset.addQuery('model', pol.model);
if (this.isHAMPActive || this.isEAMActive) {
asset.addQuery('install_status', 2).addOrCondition('install_status', 9);
} else {
asset.addQuery('install_status', 2);
}
asset.addQuery('purchase_line', pol.sys_id);
asset.query();
while (qty > 0) {
if (asset.next()) {
if (qty >= asset.quantity) {
asset.install_status = 6;
asset.substatus = 'available';
asset.purchase_line = '';
asset.cost = rsl.cost * asset.quantity;
asset.stockroom = rsl.receiving_slip.stockroom;
asset.update();
qty -= asset.quantity;
} else {
this._createConsumable(po, pol, qty, 6, rs.stockroom, rsl);
asset.quantity -= qty;
asset.update();
qty = 0;
}
} else {
this._createConsumable(po, pol, qty, 6, rs.stockroom, rsl);
qty = 0;
}
}
},
createRecSlipLineAssets: function(pol, rsl, qty, assetSysIds, reserve, assetDetails) {
var STATUS_IN_STOCK = 6;
var STATUS_ON_ORDER = 2;
var STATUS_IN_USE = 1;
var STATUS_IN_TRANSIT = 9;
var po = new GlideRecord('proc_po');
po.get(pol.purchase_order);
var type = (new AssetUtils()).getAssetOrConsumable(pol.model);
var asset = new GlideRecord('alm_asset');
asset.addQuery('purchase_line', pol.sys_id);
asset.addQuery('receiving_line', '');
if (this.isHAMPActive || this.isEAMActive) {
asset.addQuery('install_status', STATUS_ON_ORDER).addOrCondition('install_status', STATUS_IN_TRANSIT);
} else {
asset.addQuery('install_status', STATUS_ON_ORDER);
}
/* Incase of asset are precreated and */
if (!gs.nil(assetSysIds) && assetSysIds.length > 0) {
asset.addQuery('sys_id', 'IN', assetSysIds.join(','));
}
asset.query();
var itemNumber = 0;
while (qty > 0) {
if (asset.next()) {
if (type == 'software') {
asset.install_status = STATUS_IN_USE;
} else {
asset.install_status = STATUS_IN_STOCK;
asset.substatus = 'available';
}
asset.receiving_line = rsl.sys_id;
asset.stockroom = rsl.receiving_slip.stockroom;
if (JSUtil.nil(reserve)) {
asset.reserved_for = rsl.requested_for;
}
asset.cost = rsl.cost;
if (type == 'hardware' || type == 'asset') {
if (!gs.nil(assetDetails) && !gs.nil(assetDetails[itemNumber])) {
if (assetDetails[itemNumber]['serial_number']) {
asset.serial_number = assetDetails[itemNumber]['serial_number'];
}
if (assetDetails[itemNumber]['asset_tag']) {
asset.asset_tag = assetDetails[itemNumber]['asset_tag'];
}
}
}
asset.work_notes = gs.getMessage('Received through Purchase Order {0} by {1}', [(this.getHref(po, po.number)), (gs.getUser().getFullName())]);
asset.update();
qty--;
} else {
if (type == 'software') {
this._createSoftware(po, pol, STATUS_IN_USE, rsl, reserve, itemNumber, assetDetails);
qty--;
} else if (type == 'hardware' || type == 'asset') {
this._createAsset(po, pol, STATUS_IN_STOCK, rsl, reserve, itemNumber, assetDetails);
qty--;
}
}
itemNumber++;
}
},
cancelProcurementOrders: function(scRequest) {
if (scRequest.sourceable) {
var requestedItem = new GlideRecord('sc_req_item');
requestedItem.addQuery('request', scRequest.getUniqueValue());
requestedItem.query();
while (requestedItem.next()) {
var requestedItemId = requestedItem.getUniqueValue();
this._cancelPurchaseOrderLines(requestedItemId);
this._cancelTransferOrderLines(requestedItemId);
}
}
},
_cancelPurchaseOrderLines: function(requestedItemId) {
var purchaseOrderLine = new GlideRecord('proc_po_item');
purchaseOrderLine.addQuery('request_line', requestedItemId);
purchaseOrderLine.query();
while (purchaseOrderLine.next()) {
if (purchaseOrderLine.getValue('status') != 'received') {
purchaseOrderLine.setValue('status', 'canceled');
purchaseOrderLine.update();
}
}
},
_cancelTransferOrderLines: function(requestedItemId) {
var transferOrderLine = new GlideRecord('alm_transfer_order_line');
transferOrderLine.addQuery('request_line', requestedItemId);
transferOrderLine.query();
while (transferOrderLine.next()) {
var stage = transferOrderLine.getValue('stage');
if (stage != 'received' && stage != 'delivered' && stage != 'in_transit') {
transferOrderLine.setValue('stage', 'cancelled');
transferOrderLine.update();
}
}
},
_createConsumable: function(po, pol, qty, status, stockroom, rsl) {
var asset = new GlideRecord('alm_consumable');
asset.quantity = qty;
asset.model = pol.model;
// asset model category is consumable
asset.model_category = '218323293743100044e0bfc8bcbe5d61';
if ( this.isEAMActive && sn_eam.EAMSourcingAutomationAPI && sn_eam.EAMSourcingAutomationAPI.populatePOdetailsOnConsumable) {
// added hook point to set consumables into 'In Stock' state and 'reserved' substate , if sourced through EAM Sourcing or using a eam product catalog
sn_eam.EAMSourcingAutomationAPI.populatePOdetailsOnConsumable(pol, asset);
}
else if (!gs.nil(pol.model.cmdb_model_category) && this.isEAMActive && sn_eam.EnterpriseModelUtils && sn_eam.EnterpriseModelUtils.isInEAMmodelHierarchy(pol.model.sys_class_name + '')) {
// keeping this block as some customer might be on EAM 2.0 with Utah release and then hook point might not be available, in that case this block executes
// asset model category is the first model category of the model for enterprise models
var modelCategories = pol.model.cmdb_model_category;
var modelCategoriesArr = modelCategories.split(',');
asset.model_category = modelCategoriesArr[0];
// Populate purchase_line, request_line, and requested_for fields for enterprise-class consumable
asset.purchase_line = pol.sys_id;
asset.request_line = pol.request_line;
if ((sn_eam.StockOrderUtils.isStockOrderItem && !sn_eam.StockOrderUtils.isStockOrderItem(pol.request_line.cat_item.sys_id)) && !gs.nil(pol.request_line.requested_for)) {
// Skip for stock orders
asset.reserved_for = pol.request_line.requested_for;
asset.substatus = 'reserved';
}
}
asset.install_status = status;
if (status == 2) {
asset.purchase_line = pol.sys_id;
}
if (stockroom) {
asset.stockroom = stockroom;
}
if (rsl) {
asset.cost = rsl.cost * qty;
}
asset.insert();
},
_createAsset: function(po, pol, status, rsl, reserve, itemNumber, assetDetails) {
//Respect "Don't create assets" option
if (pol.model.asset_tracking_strategy == "do_not_track") {
return;
}
//Avoid creating asset if there's no category
if (!pol.model.cmdb_model_category) {
var message = gs.getMessage("No Assets for \"{0}\" were created because the Product Model does not have a Model Category", pol.model.display_name);
gs.addInfoMessage(message);
return;
}
var assetClass = 'alm_asset';
var detected_model_category = pol.model.cmdb_model_category.split(',')[0];
var model_category_gr = new GlideRecord('cmdb_model_category');
model_category_gr.get(detected_model_category);
if (!gs.nil(model_category_gr.asset_class)) {
assetClass = model_category_gr.asset_class;
}
var asset = new GlideRecord(assetClass);
asset.initialize();
asset.model = pol.model;
asset.install_status = status;
if (JSUtil.nil(reserve)) {
asset.reserved_for = po.requested_by;
}
asset.purchase_line = pol.sys_id;
asset.request_line = pol.request_line;
asset.model_category = detected_model_category;
asset.vendor = po.vendor;
asset.acquisition_method = 'purchase';
var isReservedForSet = 0;
if (!gs.nil(assetDetails) && !gs.nil(assetDetails[itemNumber])) {
if (assetDetails[itemNumber]['serial_number']) {
asset.serial_number = assetDetails[itemNumber]['serial_number'];
}
if (assetDetails[itemNumber]['asset_tag']) {
asset.asset_tag = assetDetails[itemNumber]['asset_tag'];
}
if (!gs.nil(assetDetails[itemNumber]['reserved_for']) && !gs.nil(assetDetails[itemNumber]['reserved_for']['value'])) {
isReservedForSet = 1;
asset.reserved_for = assetDetails[itemNumber]['reserved_for']['value'];
asset.substatus = 'reserved';
}
}
if (rsl) {
if (isReservedForSet === 0) {
if (JSUtil.nil(reserve)) {
asset.reserved_for = rsl.requested_for;
}
if (reserve === true) {
asset.substatus = 'reserved';
if (!JSUtil.nil(rsl.requested_for)) {
asset.reserved_for = rsl.requested_for;
}
}
}
asset.receiving_line = rsl.sys_id;
asset.cost = rsl.cost;
asset.stockroom = rsl.receiving_slip.stockroom;
asset.work_notes = gs.getMessage('Received through Purchase Order {0} by {1}', [(this.getHref(po, po.number)), (gs.getUser().getFullName())]);
}
var assetId = asset.insert();
if (gs.nil(assetId)) {
var obj = {};
obj[pol.sys_id] = assetDetails[itemNumber];
this.failedAssets.push(obj);
} else {
if (!gs.nil(assetDetails) && !gs.nil(assetDetails[itemNumber])) {
assetDetails[itemNumber]['sys_id'] = assetId;
}
}
},
_createSoftware: function(po, pol, status, rsl, reserve, itemNumber, assetDetails) {
var asset = new GlideRecord('alm_license');
asset.initialize();
asset.model = pol.model;
asset.install_status = status;
asset.reserved_for = po.requested_by;
asset.purchase_line = pol.sys_id;
asset.request_line = pol.request_line;
asset.vendor = po.vendor;
asset.acquisition_method = 'purchase';
if (rsl) {
asset.receiving_line = rsl.sys_id;
asset.reserved_for = rsl.requested_for;
asset.cost = rsl.cost.getReferenceCurrencyCode() + ';' + String( parseFloat(rsl.cost.getReferenceValue()) * rsl.quantity );
asset.stockroom = rsl.receiving_slip.stockroom;
/* By default Receiving line quantity is the S/W asset rights unless the user split the license further. */
if (this.isSAMSActive) {
asset.software_model = pol.model;
asset.purchased_rights = rsl.quantity;
asset.metric_group = pol.metric_group;
asset.license_metric = pol.license_metric;
//check if this is for Microsoft Per Core or Per Core(with CAL)
if ((pol.metric_group.sys_id == this.METRIC_GROUP_MICROSOFT) &&
((pol.license_metric.sys_id == this.LICENSE_METRIC_MS_PER_CORE) || (pol.license_metric.sys_id == this.LICENSE_METRIC_MS_PER_CORE_WITH_CAL))) {
if ((rsl.quantity % pol.rights_per_license_pack) === 0) {
asset.rights_per_license_pack = pol.rights_per_license_pack;
asset.number_of_packs = rsl.quantity / pol.rights_per_license_pack;
} else {
asset.rights_per_license_pack = 1;
asset.number_of_packs = rsl.quantity;
}
}
asset.salvage_value = pol.model.salvage_value || "";
asset.depreciation = pol.model.depreciation || "";
asset.unit_cost = rsl.cost.getReferenceCurrencyCode() + ';' + String( parseFloat(rsl.cost.getReferenceValue()));
this._setAssetLicenseType(asset, pol);
} else {
asset.rights = rsl.quantity;
}
asset.work_notes = gs.getMessage('Received through Purchase Order {0} by {1}', [ (this.getHref(po, po.number)), (gs.getUser().getFullName()) ]);
}
var assetSysId = asset.insert();
if (!gs.nil(assetSysId) && !gs.nil(assetDetails) && !gs.nil(assetDetails[itemNumber])) {
assetDetails[itemNumber]['sys_id'] = assetSysId;
}
//Create Downgrade Rights once asset is created
this._createDowngradeRights(assetSysId, pol.purchase_order);
//Auto allocate the rights after entitlement creation
this._autoAllocateRights(assetSysId,rsl,pol);
},
_setAssetLicenseType: function(asset, pol) {
if(!GlidePluginManager.isActive('com.snc.samp')) {
return;
}
// License metric for subscription software
var USER_SUBSCRIPTION = "48c5d8d293200300544814f1b47ffb45";
var roGr = new GlideRecord('samp_remediation_option');
roGr.addQuery('purchase_order', pol.purchase_order);
roGr.addQuery('maintenance', true);
roGr.query();
if (roGr.next()) {
var microsoftCoreCompany = new SAMCoreCompanyUtil().resolveCoreCompanyForSoftwarePublisher(ReconciliationConstants.MICROSOFT_PUBLISHER_SYS_ID );
if(pol.model.manufacturer.toString() === microsoftCoreCompany) {
asset.setValue('product_type', 'perpetual_software_assurance');
} else {
asset.setValue('product_type', 'perpetual_maintenance');
}
asset.setValue('start_date', new GlideDateTime().getDate());
asset.setValue('end_date', new GlideDateTime('9999-12-31'));
} else if (pol.license_metric == USER_SUBSCRIPTION) {
asset.setValue('product_type', 'subscription');
asset.setValue('start_date', new GlideDateTime().getDate());
}
},
_createDowngradeRights: function(assetSysId, poSysId) {
if (!this.isSAMSActive) {
return;
}
var roGr = new GlideRecord('samp_remediation_option');
roGr.addQuery('purchase_order', poSysId);
roGr.addNotNullQuery('license_metric_result');
roGr.query();
if(roGr.next()) {
var downgradeRights = roGr.license_metric_result.downgrade_rights;
if(!gs.nil(downgradeRights)) {
var downgradeModels = downgradeRights.split(',');
var dmGr = new GlideRecord('samp_downgrade_model');
for(var model in downgradeModels) {
dmGr.initialize();
dmGr.setValue('license', assetSysId);
dmGr.setValue('model', downgradeModels[model]);
dmGr.insert();
}
}
}
},
_autoAllocateRights: function(assetSysId, rsl, pol){
if(!GlidePluginManager.isActive('com.snc.samp') || String(pol.request_line.cat_item.workflow) !== '917506260711301019cc909f0ad3005d') {
return;
}
var rightsToAllocate = rsl.quantity >= pol.request_line.quantity?pol.request_line.quantity:rsl.quantity;
var seGr = new GlideRecord('alm_license');
if(seGr.get(assetSysId)){
var entitlementType = String(seGr.license_metric.entitlement_type);
if(entitlementType === 'user' && !gs.nil(rsl.requested_for)){
this._createAllocations(assetSysId, rightsToAllocate, 'alm_entitlement_user','assigned_to', rsl.requested_for);
}else if(entitlementType === 'workstation'){
var device = this._getDeviceId(pol.request_line.cat_item, pol.request_line, rsl.requested_for);
if(!gs.nil(device))
this._createAllocations(assetSysId, rightsToAllocate,'alm_entitlement_asset','allocated_to', device);
}
}
},
_getDeviceId: function(catItemSysId, ritmSysId, requestedUser){
var deviceId = null;
var varGr = new GlideRecord('item_option_new');
varGr.addQuery('name', 'device_name');
varGr.addQuery('cat_item',catItemSysId);
varGr.query();
varGr.next();
var gr = new GlideRecord('sc_item_option_mtom');
gr.addQuery('request_item',ritmSysId);
gr.query();
while(gr.next()) {
if (String(gr.sc_item_option.item_option_new) === varGr.getUniqueValue()) {
deviceId = gr.sc_item_option.value;
if(!gs.nil(deviceId)){
var deviceGr = new GlideRecord('cmdb_ci_computer');
if(deviceGr.get(deviceId)){
var user = deviceGr.getValue('assigned_to');
if(user === String(requestedUser))
return deviceId;
}
}
}
}
return null;
},
_createAllocations: function(seSysId, rightsUsed, table, column, allocationTo) {
var almSysId = '';
var almGr = new GlideRecord(table);
almGr.addQuery(column, allocationTo);
almGr.addQuery('licensed_by', seSysId);
almGr.query();
if (almGr.next()) {
var newQuantity = parseInt(almGr.getValue('quantity'), 10) + rightsUsed;
almGr.setValue('quantity', newQuantity);
almSysId = almGr.getUniqueValue();
almGr.update();
} else {
var newAlmGr = new GlideRecord(table);
newAlmGr.initialize();
newAlmGr.licensed_by = seSysId;
newAlmGr.setValue('quantity', rightsUsed);
if(column === 'assigned_to')
newAlmGr.assigned_to = allocationTo;
else if(column === 'allocated_to')
newAlmGr.allocated_to = allocationTo;
almSysId = newAlmGr.insert();
}
},
_findPO: function(item, vendor, consolidate, destination) {
var request = new GlideRecord('sc_request');
request.get(item.request);
var po = new GlideRecord('proc_po');
po.addQuery('vendor', vendor);
po.addQuery('ship_to', destination);
po.addQuery('status', 'requested');
if (consolidate == false) {
po.addQuery('init_request', request.sys_id);
}
po.query();
if (po.next()) {
return po;
}
else {
return this.createPO(request, vendor, destination);
}
},
getHref: function(record, text) {
return '[code]<a href=' + record.getLink(true) + '>' + String(text) + '</a>[/code]';
},
/* ******************************************************
UI Action condition checkers
****************************************************** */
showCancelOnPurchaseOrder: function(po) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showCancelOnPurchaseOrder) {
var response = new sn_hamp.HAMProcurementUtils().showCancelOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showCancelOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showCancelOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.showCancelOnPurchaseOrder) {
response = new sn_itam_common.AssetCommonProcurementUtils().showCancelOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var status = po.getValue('status');
var statusAllows = (status === 'requested' || status === 'ordered'
|| status === 'pending' || status === 'suspended');
return HAMAllows && statusAllows && !this.isAssetOperationInProgress(po);
},
showReceiveInIEOnPurchaseOrder: function(po) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showReceiveInIEOnPurchaseOrder) {
var response = new sn_hamp.HAMProcurementUtils().showReceiveInIEOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showReceiveInIEOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showReceiveInIEOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var status = po.getValue('status');
var statusAllows = (status === 'ordered' || status === 'pending');
var browserAllows = (gs.getSession().getProperty('user_agent_browser') == 'ie'
&& gs.getSession().getProperty('user_agent_version') < 10);
return HAMAllows && statusAllows && browserAllows && !this.isAssetOperationInProgress(po);
},
showReceiveOnPurchaseOrder: function(po) {
var HAMAllows = true;
var response;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showReceiveOnPurchaseOrder) {
response = new sn_hamp.HAMProcurementUtils().showReceiveOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.showReceiveOnPurchaseOrder && sn_itam_common.AssetCommonProcurementUtils.prototype.usePOReceiveForLeaseContract && new sn_itam_common.AssetCommonProcurementUtils().usePOReceiveForLeaseContract(po) === true) {
response = new sn_itam_common.AssetCommonProcurementUtils().showReceiveOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
} else if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showReceiveOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showReceiveOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var status = po.getValue('status');
var statusAllows = (status === 'ordered' || status === 'pending');
var browserAllows = !(gs.getSession().getProperty('user_agent_browser') == 'ie'
&& gs.getSession().getProperty('user_agent_version') < 10);
return HAMAllows && statusAllows && browserAllows && !this.isAssetOperationInProgress(po);
},
showHardwareCreationLinkOnPurchaseOrder: function(po) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showHardwareCreationLinkOnPurchaseOrder) {
var response = new sn_hamp.HAMProcurementUtils().showHardwareCreationLinkOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.showHardwareCreationLinkOnPurchaseOrder && sn_itam_common.AssetCommonProcurementUtils.prototype.usePOReceiveForLeaseContract && new sn_itam_common.AssetCommonProcurementUtils().usePOReceiveForLeaseContract(po) === true) {
response = new sn_itam_common.AssetCommonProcurementUtils().showHardwareCreationLinkOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
} else if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showHardwareCreationLinkOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showHardwareCreationLinkOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var statusAllows = (po.getValue('status') === 'ordered');
var hasHwPO = this.hasHardwarePO(po);
return HAMAllows && statusAllows && hasHwPO && !this.isAssetOperationInProgress(po);
},
showOrderOnPurchaseOrder: function(po) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showOrderOnPurchaseOrder) {
var response = new sn_hamp.HAMProcurementUtils().showOrderOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showOrderOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showOrderOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var procurementIntegrationAllows = true;
if (this.procurementIntegrationActive) {
procurementIntegrationAllows = new sn_asset_proc_int.ITAMProcurementIntegrationUtil().showOrderOnPurchaseOrder(po);
}
var status = po.getValue('status');
var statusAllows = (status === 'requested' || status === 'canceled');
var hasPOLs = this.poHasPurchaseOrderLineItems(po);
return HAMAllows && procurementIntegrationAllows && statusAllows && hasPOLs && !this.isAssetOperationInProgress(po);
},
showDeleteOnPurchaseOrder: function(po) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showDeleteOnPurchaseOrder) {
var response = new sn_hamp.HAMProcurementUtils().showDeleteOnPurchaseOrder(po);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showDeleteOnPurchaseOrder) {
response = new sn_itam_common.ContractRenewalUtils().showDeleteOnPurchaseOrder(po);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var canDelete = (po.isValidRecord() && po.canDelete());
var poHasReceivingSlip = this.poHasReceivingSlip(po);
return HAMAllows && canDelete && !poHasReceivingSlip && !this.isAssetOperationInProgress(po);
},
showCancelOnPurchaseOrderLine: function(pol) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showCancelOnPurchaseOrderLine) {
var response = new sn_hamp.HAMProcurementUtils().showCancelOnPurchaseOrderLine(pol);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showCancelOnPurchaseOrderLine) {
response = new sn_itam_common.ContractRenewalUtils().showCancelOnPurchaseOrderLine(pol);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var status = pol.getValue('status');
var statusAllows = (status === 'requested' || status === 'ordered'
|| status === 'pending' || status === 'suspended');
return HAMAllows && statusAllows && !this.isAssetOperationInProgress(pol);
},
showOrderOnPurchaseOrderLine: function(pol) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showOrderOnPurchaseOrderLine) {
var response = new sn_hamp.HAMProcurementUtils().showOrderOnPurchaseOrderLine(pol);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showOrderOnPurchaseOrderLine) {
response = new sn_itam_common.ContractRenewalUtils().showOrderOnPurchaseOrderLine(pol);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.showCancelOnPurchaseOrderLine) {
response = new sn_itam_common.AssetCommonProcurementUtils().showCancelOnPurchaseOrderLine(pol);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var statusAllows = (pol.getValue('status') === 'canceled');
var poStatus = String(this.getPOStatusFromPOL(pol));
var poStatusAllows = ((poStatus !== 'canceled') && (poStatus !== 'received'));
return HAMAllows && statusAllows && poStatusAllows && !this.isAssetOperationInProgress(pol);
},
showHardwareCreationLinkOnPurchaseOrderLine: function(pol) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.showHardwareCreationLinkOnPurchaseOrderLine) {
var response = new sn_hamp.HAMProcurementUtils().showHardwareCreationLinkOnPurchaseOrderLine(pol);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.showHardwareCreationLinkOnPurchaseOrderLine && sn_itam_common.AssetCommonProcurementUtils.prototype.usePOReceiveForLeaseContract && new sn_itam_common.AssetCommonProcurementUtils().usePOReceiveForLeaseContract(pol.purchase_order) === true) {
response = new sn_itam_common.AssetCommonProcurementUtils().showHardwareCreationLinkOnPurchaseOrderLine(pol);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
} else if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.showHardwareCreationLinkOnPurchaseOrderLine) {
response = new sn_itam_common.ContractRenewalUtils().showHardwareCreationLinkOnPurchaseOrderLine(pol);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var statusAllows = (pol.getValue('status') === 'ordered');
var hasHwPOL = this.hasHardwarePOLineItem(pol);
var assetTrackingAllows = (String(pol.model.asset_tracking_strategy) !== 'do_not_track');
return HAMAllows && statusAllows && hasHwPOL && assetTrackingAllows && !this.isAssetOperationInProgress(pol);
},
shouldCreateAssetsFromRSL: function(rsl) {
var HAMAllows = true;
if (this.isHAMPActive && sn_hamp.HAMProcurementUtils && sn_hamp.HAMProcurementUtils.prototype.shouldCreateAssetsFromRSL) {
var response = new sn_hamp.HAMProcurementUtils().shouldCreateAssetsFromRSL(rsl);
HAMAllows = response.answer;
if (!response.continueProcessing) { return HAMAllows; }
}
var ITAMCommonAllows = true;
if (this.isITAMCommonActive && sn_itam_common.AssetCommonProcurementUtils && sn_itam_common.AssetCommonProcurementUtils.prototype.shouldCreateAssetsFromRSL && sn_itam_common.AssetCommonProcurementUtils.prototype.usePOReceiveForLeaseContract && new sn_itam_common.AssetCommonProcurementUtils().usePOReceiveForLeaseContract(rsl.purchase_line.purchase_order) === true) {
response = new sn_itam_common.AssetCommonProcurementUtils().shouldCreateAssetsFromRSL(rsl);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
} else if (this.isITAMCommonActive && sn_itam_common.ContractRenewalUtils && sn_itam_common.ContractRenewalUtils.prototype.shouldCreateAssetsFromRSL) {
response = new sn_itam_common.ContractRenewalUtils().shouldCreateAssetsFromRSL(rsl);
ITAMCommonAllows = response.answer;
if (!response.continueProcessing) { return ITAMCommonAllows; }
}
var baseConditionAllows = !rsl.purchase_line.nil() && rsl.quantity > 0
&& rsl.purchase_line.model.asset_tracking_strategy != 'do_not_track';
return HAMAllows && baseConditionAllows;
},
rollupAssetOperationToPO: function(po) {
var assetOperationInProgress = '';
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.addNotNullQuery('asset_operation');
pol.query();
while (po.next()) {
if (pol.asset_operation) {
assetOperationInProgress = pol.asset_operation;
break;
}
}
var purchaseOrder = new GlideRecord('proc_po');
purchaseOrder.get(po.sys_id);
purchaseOrder.asset_operation = assetOperationInProgress;
purchaseOrder.update();
},
getAssetOperationInProgressMessage: function() {
return gs.getMessage('Asset updates are in progress. Please do not update this record until complete. Reload page to check progress.');
},
isAssetOperationInProgressForPO: function(po) {
var purchaseOrder = new GlideRecord('proc_po');
purchaseOrder.get(po.sys_id);
return !!record.getValue('asset_operation');
},
isAssetOperationInProgressForPOL: function(po) {
var pol = new GlideRecord('proc_po_item');
pol.addQuery('purchase_order', po.sys_id);
pol.addNotNullQuery('asset_operation');
pol.query();
if (pol.hasNext()) {
return true;
}
return false;
},
isAssetOperationInProgress: function(record) {
var isPOLine = record.getTableName() === ProcurementUtils.PURCHASE_ORDER_LINE_ITEM_TABLE;
var result = !!record.getValue('asset_operation');
if (!isPOLine) {
return result || this.isAssetOperationInProgressForPOL(record);
} else {
return result || this.isAssetOperationInProgressForPO(record.purchase_order);
}
},
updateAssetOperationInProgress: function(record, value) {
record.asset_operation = value;
record.update();
},
areAssetsAlreadyCreatedForPOL: function(pol){
var orderedQuantity = pol.ordered_quantity;
var asset = new GlideAggregate('alm_asset');
asset.addQuery('purchase_line', pol.sys_id);
asset.addAggregate('COUNT');
asset.query();
if (asset.next()) {
var count = asset.getAggregate('COUNT');
if (count === orderedQuantity){
return true;
}
}
return false;
},
type: 'ProcurementUtils'
};
ProcurementUtils.getCloseTaskCondition = function(task) {
return parseInt(task.state, 10) !== -5 && task.state < 3
&& task.approval.toString() !== 'requested';
};
ProcurementUtils.getConsumeAndCloseTaskCondition = function(task) {
var baseTaskCondition = global.ProcurementUtils.getCloseTaskCondition(task);
return baseTaskCondition && task.task_name.toString() === 'consume' && !gs.nil(task.model)
&& !gs.nil(task.quantity) && !gs.nil(task.stockroom) && !gs.nil(task.requested_for);
};
ProcurementUtils.getConsumble = function (model, fromStockroom, status, substatus, quantity) {
var con = new GlideRecord('alm_consumable');
con.addQuery('stockroom', fromStockroom.sys_id);
con.addQuery('quantity', '>=', quantity);
con.addQuery('model', model.sys_id);
con.addQuery('install_status', status);
con.addQuery('substatus', substatus);
global.AssetUtils.addAssetQuery(con, global.AssetUtils.ASSET_FUNCTION_FEATURE.SOURCING);
con.setLimit(1);
con.query();
if (con.next()) {
return con;
}
throw gs.getMessage('{0} consumable in State - {1} and Subsate - {2} with {3} or more quantity'
+ ' not found in {4} stockroom', [model.display_name, status, substatus, quantity, fromStockroom.name]);
};
ProcurementUtils.consumeTaskAssetQualifier = function (asset) {
var gr = new GlideRecord('alm_asset');
gr.addQuery('model', asset.model);
gr.addQuery('stockroom', asset.stockroom);
gr.addQuery('install_status', global.AssetUtils.INSTOCK_STATUS);
gr.addQuery('substatus', global.AssetUtils.AVAILABLE_SUBSTATUS);
global.AssetUtils.addAssetQuery(gr, global.AssetUtils.ASSET_FUNCTION_FEATURE.SOURCING);
return gr.getEncodedQuery();
};
ProcurementUtils.reserveAndReleaseAsset = function (currentTask, previousTask) {
if (gs.nil(currentTask.asset)) {
gs.addErrorMessage(gs.getMessage('The following mandatory fields are not filled in: {0}',
currentTask.asset.getLabel()));
return false;
}
if (gs.nil(previousTask.asset)) {
gs.addErrorMessage(gs.getMessage('Existing value of {0} field is empty on task',
previousTask.asset.getLabel()));
return false;
}
var currentAssetGr = new GlideRecord(currentTask.asset.sys_class_name);
var previousAssetGr = new GlideRecord(previousTask.asset.sys_class_name);
currentAssetGr.get(currentTask.asset.sys_id);
previousAssetGr.get(previousTask.asset.sys_id);
if (currentAssetGr.getValue('install_status') !== global.AssetUtils.INSTOCK_STATUS.toString()
|| currentAssetGr.getValue('substatus') !== global.AssetUtils.AVAILABLE_SUBSTATUS) {
gs.addErrorMessage(gs.getMessage('Selected asset is not available in stock.'));
return false;
}
currentAssetGr.install_status = global.AssetUtils.INSTOCK_STATUS;
currentAssetGr.substatus = global.AssetUtils.RESERVED_SUBSTATUS;
currentAssetGr.reserved_for = previousAssetGr.reserved_for;
currentAssetGr.update();
previousAssetGr.install_status = global.AssetUtils.INSTOCK_STATUS;
previousAssetGr.substatus = global.AssetUtils.AVAILABLE_SUBSTATUS;
previousAssetGr.reserved_for = '';
previousAssetGr.update();
return true;
};
ProcurementUtils.isRITMFullyReceived = function (ritm) {
var reqItemGr = new GlideRecord('sc_req_item');
reqItemGr.get(ritm);
// If the requested item haven't been fully sourced, it can't be fully received at this point
if (!reqItemGr.sourced) {
return false;
}
// Local order - consume asset task
var cTaskGr = new GlideRecord(global.ProcurementUtils.CONSUME_ASSET_TASK_TABLE);
cTaskGr.addQuery('parent', ritm);
cTaskGr.addQuery('active', true);
cTaskGr.setLimit(1);
cTaskGr.query();
if (cTaskGr.hasNext()) {return false;}
// Transfer order - transfer order line
var tolGr = new GlideRecord(global.ProcurementUtils.TRANSFER_ORDER_LINE_TABLE);
tolGr.addQuery('request_line', ritm);
tolGr.addQuery('stage', 'NOT IN', 'delivered,cancelled');
tolGr.setLimit(1);
tolGr.query();
if (tolGr.hasNext()) {return false;}
// Purchase order - purchase order line item
var polGr = new GlideRecord(global.ProcurementUtils.PURCHASE_ORDER_LINE_ITEM_TABLE);
polGr.addQuery('request_line', ritm);
polGr.addQuery('status', 'NOT IN', 'received,canceled');
polGr.setLimit(1);
polGr.query();
if (polGr.hasNext()) {return false;}
// Enterprise local order - confirm asset task
if (new TableUtils('sn_eam_confirm_asset_task').tableExists()) {
var cfTaskGr = new GlideRecord('sn_eam_confirm_asset_task');
cfTaskGr.addQuery('parent', ritm);
cfTaskGr.addQuery('state', '1');
cfTaskGr.setLimit(1);
cfTaskGr.query();
if (cfTaskGr.hasNext()) {return false;}
}
return true;
};
ProcurementUtils.validateFieldsForConsumeAsset = function (consumeAssetTask) {
consumeAssetTask.state = 3;
if (!consumeAssetTask.update()) {
return consumeAssetTask;
}
return consumeAssetTask.parent.getRefRecord();
};
ProcurementUtils.canCloseConsumeTask = function (consumeAssetTask) {
var hasAccess = gs.getUser().hasRole('inventory_user') || gs.getUser().hasRole('itil') || gs.getUser().hasRole('admin') || gs.getUser().hasRole('asset');
return (hasAccess && (global.ProcurementUtils.getCloseTaskCondition(consumeAssetTask) && consumeAssetTask.task_name.toString() !== 'consume'));
};
Sys ID
378ec0bb37c13000158bbfc8bcbe5d17