Name
global.POReceiveManager
Description
Handles Purchase Order Receive
Script
var POReceiveManager = Class.create();
POReceiveManager.prototype = {
initialize: function(request) {
this.failedAssets = [];
this.request = request;
this.isSAMPActive = GlidePluginManager.isActive('com.snc.samp');
this.isHAMPActive = GlidePluginManager.isActive('com.sn_hamp');
this.isEAMActive = GlidePluginManager.isActive('com.sn_eam');
},
getAllStockRoom: function() {
var stockrooms = this._getRecordObject('alm_stockroom', //table name
[], //All records
['sys_id', 'name', 'localtion']); //Fields
return (new JSON()).encode(stockrooms);
},
_getPreCreatedAssets: function(polineSysid, model) {
var onOrderAssets = this._getRecordObject('alm_asset', // table name
[{
key: 'purchase_line',
value: polineSysid,
}, {
key: 'install_status',
value: '2',
}, {
key: 'model',
value: model,
}],
['sys_id', 'asset_tag', 'serial_number', 'model', 'license_key'], // Fields
{
reserved_for: {
table: 'sys_user',
fields: ['user_name', 'sys_id', 'name'],
},
});
var assets = onOrderAssets;
if (this.isHAMPActive || this.isEAMActive) {
var inTransitAssets = this._getRecordObject('alm_asset', // table name
[{
key: 'purchase_line',
value: polineSysid,
}, {
key: 'install_status',
value: '9',
}, {
key: 'model',
value: model,
}],
['sys_id', 'asset_tag', 'serial_number', 'model', 'license_key'], // Fields
{
reserved_for: {
table: 'sys_user',
fields: ['user_name', 'sys_id', 'name'],
},
});
assets = onOrderAssets.concat(inTransitAssets);
}
return assets;
},
getPOItems: function() {
var poSysId = this.request.getParameter('sysparm_po_sysid');
var items = this.getPOItemsWithParams(poSysId);
return items;
},
getPOItemsWithParams: function(poSysId, polSysId) {
var reqItems = [];
var refFieldsToRequest = {
'requested_for': {
table: 'sys_user',
fields: ['user_name', 'sys_id', 'name']
},
'model': {
table: 'cmdb_model',
fields: ['sys_id', 'display_name', 'asset_tracking_strategy', 'sys_class_name']
},
'purchase_order': {
table: 'proc_po',
fields: ['sys_id', 'number', 'ship_to']
},
'vendor': {
table: 'core_company',
fields: ['sys_id', 'name']
}
};
if (this.isSAMPActive) {
refFieldsToRequest.license_metric = {
table: 'samp_sw_license_metric',
fields: ['sys_id', 'name']
};
refFieldsToRequest.metric_group = {
table: 'samp_sw_metric_group',
fields: ['sys_id', 'name']
};
}
var queryParams = [{
key: "purchase_order",
value: poSysId
},
{
key: 'remaining_quantity',
value: '0',
operator: '>'
},
{
key: 'status',
value: 'canceled',
operator: '!='
}
];
if (!gs.nil(polSysId)) {
queryParams.push({
key: 'sys_id',
value: polSysId
});
}
var items = this._getRecordObject("proc_po_item",
queryParams,
[], //Get all fields
refFieldsToRequest,
'number');
/* update pre generated assets for each POline model */
var createCIUsingIRE = gs.getProperty('glide.asset.create_ci_with_ire');
var AssetCMDBUtil = new global.AssetCMDBUtil();
for (var i = 0; i < items.length; i++) {
var item = items[i];
item['createCIUsingIRE'] = createCIUsingIRE;
item['pre_created_assets'] = this._getPreCreatedAssets(item.sys_id, item.model.sys_id);
item['item_model_type'] = this._getItemModelType(item.model.sys_id);
var shipTOSysid = item.purchase_order.ship_to;
/* Need value and displayValue for default selection of ShipTo reference picker at client side */
if (!gs.nil(shipTOSysid)) {
var stockRooms = this._getRecordObject('alm_stockroom',
[{
key: 'sys_id',
value: shipTOSysid
}],
['sys_id', 'name']);
if (!gs.nil(stockRooms) && stockRooms.length > 0)
item.purchase_order.ship_to = stockRooms[0];
}
if (createCIUsingIRE === 'true') {
var productModel = item.model.sys_id;
var productModelGr = new GlideRecord('cmdb_model');
productModelGr.get(productModel);
var modelCategories = productModelGr.getValue('cmdb_model_category');
if (!gs.nil(modelCategories) && productModelGr.asset_tracking_strategy != 'track_as_consumable' && productModelGr.asset_tracking_strategy != 'do_not_track') {
modelCategories = modelCategories.split(',');
var modelCategory = modelCategories[0];
item['is_serial_number_mandatory'] = AssetCMDBUtil.isSerialNumberMandatory(modelCategory);
if (this.isEAMActive && !item['is_serial_number_mandatory']) {
var isMandatory = sn_eam.EAMUtils.isSerialNumberMandatory(modelCategory);
item['is_serial_number_mandatory'] = isMandatory;
}
} else {
item['is_serial_number_mandatory'] = false;
}
} else {
item['is_serial_number_mandatory'] = false;
}
}
return (new JSON()).encode(items);
},
processPOReceive: function() {
var poSysId = this.request.getParameter('sysparm_po_sysid');
var data = this.request.getParameter('sysparm_receivedata');
var batchProcessing = this.request.getParameter('sysparm_batching');
return this.processPOReceiveWithParams(poSysId, data, batchProcessing);
},
processPOReceiveWithParams: function(poSysId, data, batchProcessing) {
data = (new JSON()).decode(data);
var response = this._validate(data);
if (response.status == 'success') {
/* group polines by destination stockroom to create per stockroom Receiving Slips*/
var dataByDestination = this._groupbyDestination(data);
for (var stockroom in dataByDestination) {
var poLines = dataByDestination[stockroom];
this._processPOLines(poSysId, poLines, stockroom, batchProcessing);
}
}
var poItemsGr = new GlideRecord('proc_po_item');
var failedAssetsObj = {};
for (var i = 0; i < this.failedAssets.length; i++) {
var polSysId = Object.keys(this.failedAssets[i])[0];
if (failedAssetsObj[polSysId] == undefined) {
poItemsGr.get(polSysId);
failedAssetsObj[polSysId] = {};
failedAssetsObj[polSysId]['items'] = [this.failedAssets[i][polSysId]];
failedAssetsObj[polSysId]['received_quantity'] = poItemsGr.getValue('received_quantity');
failedAssetsObj[polSysId]['remaining_quantity'] = poItemsGr.getValue('remaining_quantity');
} else {
failedAssetsObj[polSysId]['items'].push(this.failedAssets[i][polSysId]);
}
}
response['failedAssets'] = failedAssetsObj;
if (this.failedAssets.length > 0) {
gs.flushMessages();
}
return (new JSON()).encode(response);
},
_validate: function(data) {
var response = {
status: 'success'
};
return response;
},
_processPOLines: function(poSysId, poLines, stockroom, batching) {
var isPOSoftwareLine;
var poLine;
var polGr;
var po = new GlideRecord('proc_po');
po.get(poSysId);
var pu = new ProcurementUtils();
var receivingSlip;
if (batching == 'in_between' || batching == 'last_batch_call') {
receivingSlip = new GlideRecord('proc_rec_slip');
receivingSlip.addQuery('purchase_order', po.sys_id);
receivingSlip.addQuery('stockroom', stockroom);
receivingSlip.orderByDesc('sys_created_on');
receivingSlip.setLimit(1);
receivingSlip.query();
receivingSlip.next();
} else {
receivingSlip = pu.createReceiptSlip(po, stockroom);
}
var receivingSlipLineCreated = 0;
for (var i = 0; i < poLines.length; i++) {
poLine = poLines[i];
poLine.reserved = poLine.reserved || false;
isPOSoftwareLine = this._isPOSoftwareLine(poLine);
// var rights;
polGr = new GlideRecord("proc_po_item");
polGr.get(poLine.sys_id);
/* Create only one asset for software PO line */
// if (this._isPOSoftwareLine(poLine)) {
// rights = poLine.receiving_quantity;
// }
if (this.isSAMPActive && isPOSoftwareLine) {
pu.createReceiptSlipLineForSAMP(
receivingSlip,
polGr,
poLine
);
receivingSlipLineCreated = 1;
} else if (poLine.assetTags) {
// Assets with Tags and/or SN created
var failedItems = (pu.createReceiptSlipLineWithAssetDetails(
receivingSlip,
polGr,
poLine.receiving_quantity,
poLine.cost_with_currency,
poLine.reserved_for.value,
poLine.assetTags,
poLine.reserved,
isPOSoftwareLine
));
this.failedAssets = this.failedAssets.concat(failedItems);
if (failedItems.length != poLine.receiving_quantity) {
receivingSlipLineCreated = 1;
}
} else {
// Standard receive without any Asset Tags or SN created in popup
pu.createReceiptSlipLine(
receivingSlip,
polGr,
poLine.receiving_quantity,
poLine.cost_with_currency,
poLine.reserved_for.value,
'',
'',
poLine.reserved
);
receivingSlipLineCreated = 1;
}
}
// batching will be false if receiving is done from other areas other than PO Receive page
if (receivingSlipLineCreated === 0 && (batching == 'none' || batching == false)) {
var procRecSlipGr = new GlideRecord('proc_rec_slip');
procRecSlipGr.get(receivingSlip.sys_id);
procRecSlipGr.deleteRecord();
}
if (batching == 'last_batch_call') {
var procRecSlipItemGr = new GlideRecord('proc_rec_slip_item');
procRecSlipItemGr.addQuery('receiving_slip', receivingSlip.sys_id);
procRecSlipItemGr.setLimit(1);
procRecSlipItemGr.query();
if (!procRecSlipItemGr.hasNext()) {
receivingSlip.deleteRecord();
}
}
},
_groupbyDestination: function(data) {
var dataByDestination = {};
for (var i = 0; i < data.length; i++) {
if (gs.nil(dataByDestination[data[i].ship_to.value])) {
dataByDestination[data[i].ship_to.value] = [];
}
dataByDestination[data[i].ship_to.value].push(data[i]);
}
return dataByDestination;
},
_getRecordObject: function(table, queryParams, fields, refMap, orderBy) {
var i;
var records = [];
var gr = new GlideRecord(table);
if (queryParams) {
for (i = 0; i < queryParams.length; i++) {
var qp = queryParams[i];
if (qp.operator) {
gr.addQuery(qp.key, qp.operator, qp.value);
} else {
gr.addQuery(qp.key, qp.value);
}
}
}
if (orderBy) {
gr.orderBy(orderBy);
}
gr.query();
while (gr.next()) {
var rec = {};
var glideElements = gr.getFields();
rec['sys_id'] = gr.sys_id.toString();
for (i = 0; i < glideElements.size(); i++) {
var glideElement = glideElements.get(i);
//gs.info('Processing ' + glideElement.getName() + ' - ' + glideElement.getDisplayValue());
if (!gs.nil(glideElement.toString()) && /* if no fields given then consider all otherwise consider specific */
(fields.length == 0 || (fields.length > 0 && fields.indexOf(glideElement.getName()) >= 0))) {
rec[glideElement.getName()] = glideElement.toString();
}
if (refMap && !gs.nil(refMap[glideElement.getName()])) {
var refDetails = refMap[glideElement.getName()];
var refSysid = glideElement.toString();
var refObjs = this._getRecordObject(refDetails.table, [{
key: 'sys_id',
value: refSysid
}], refDetails.fields);
if (!gs.nil(refObjs) && refObjs.length > 0) {
rec[glideElement.getName()] = refObjs[0];
}
}
}
records.push(rec);
}
return records;
},
_isPOSoftwareLine: function(poline) {
return poline.item_model_type == 'software';
},
/* Decide type of item (software/hardware) based on requested item's model*/
_getItemModelType: function(model) {
var type = '';
if (model) {
var modelGR = new GlideRecord('cmdb_model');
modelGR.get(model);
type = (new AssetUtils()).getAssetOrConsumable(modelGR);
}
return type;
},
getAssetTags: function() {
var assetTags = [];
var gr = new GlideRecord('imp_asset_tags');
/*
gr.addNotNullQuery('u_asset_tag');
*/
gr.orderBy('sys_import_row');
gr.query();
while (gr.next()) {
assetTags.push({
asset_tag: gr.u_asset_tag.toString(),
serial_number: gr.u_serial_number.toString(),
reserved_for: gr.u_reserved_for.toString(),
license_key: gr.u_license_key.toString(),
rights: gr.u_rights.toString(),
index: gr.sys_import_row.toString()
});
gr.deleteRecord();
}
return (new JSON()).encode(assetTags);
},
getBatchConfig: function() {
var cfg = {
threshold: 500,
unnecessaryKeys: [
'discount', // unnecessary to send, not changed in UI
'errors', // retrieved and used only for UI validations
'ordered', // unnecessary to send, not changed in UI
'received_quantity', // retrieved and used only for UI
'remaining_quantity', // retrieved and used only for UI
'sys_created_by', // sys parameter, unnecessary to send
'sys_created_on', // sys parameter, unnecessary to send
'sys_domain', // sys parameter, unnecessary to send
'sys_mod_count', // sys parameter, unnecessary to send
'sys_updated_by', // sys parameter, unnecessary to send
'sys_updated_on' // sys parameter, unnecessary to send
]
};
return (new JSON()).encode(cfg);
},
log: function(msg) {
gs.info('[POReceiveManager]: ' + msg);
},
type: 'POReceiveManager'
};
Sys ID
c149ac86932012003706dfa5e57ffbfe