Name
global.MatchingDimensionParts
Description
Dimension to process parts matching.
Script
/**
* Rate users on available parts in personal stockrooms, required by a task
*
* Two counting methods:
* 1. count 1 or 0, this is default
* 2. count fraction, enabled by passing in args.config.partialPart
*
* Example: task requires 10 consumable assets, an agent has 5 consumable assets in stockroom.
* Method 1 rates this agent to "0 / 1"
* Method 2 rates this agent to "0.5 / 1"
*
* Input: task - a task sys_id or a task GlideRecord
* users - an array of user sys_ids
* taskFieldValues - ignored, not used as part_requirement is not a field in task
* args - config object, i.e. args.config.userPart, args.config.partialPart
*
* Output: {"06826bf03710200044e0bfc8bcbe5d8a":{
* "detailedDisplayValue":"Dynex 6 foot USB 2.0 A/B Cable,Philips Respironics BiPAP Focus",
* "displayValue":"2 / 2",
* "rating":1,"value":2},
* "82826bf03710200044e0bfc8bcbe5d89":{
* "detailedDisplayValue":"Dynex 6 foot USB 2.0 A/B Cable",
* "displayValue":"0 / 2",
* "rating":0,
* "value":0}}
*/
var MatchingDimensionParts = Class.create();
MatchingDimensionParts.prototype = {
FIELD_AGENT_STOCKROOM_TYPE : "e2aa2b3f3763100044e0bfc8bcbe5dde",
initialize: function() {
this.debugOn = new CSMUtil().isDebugOn();
this.countPartial = false;
},
process : function(task, users, taskFieldValues, args) {
if (args && args.config && args.config.usePart) {
if (JSUtil.notNil(args.config.partialPart) && args.config.partialPart) {
this.countPartial = true;
}
var modelReqQuant = this.getPartsForTask(task);
var usersParts = this.getUserPartsMatching(users, modelReqQuant);
if (this.debugOn)
gs.log(JSON.stringify(usersParts), "Matching Parts");
return usersParts;
}
return this._rateUserEqually(users, false);
},
_rateUserEqually : function(users, featureEnabled) {
var partObj = {};
partObj.rating = 1;
partObj.value = 1;
partObj.displayValue = gs.getMessage("NA");
var dispString = featureEnabled ? gs.getMessage("Task does not require any part, all users rated equally.")
: gs.getMessage("Part required is not enabled, all users rated equally");
partObj.detailedDisplayValue = dispString;
var userParts = {};
users.forEach(function(id) {
userParts[id] = partObj;
});
return userParts;
},
getPersonalRooms: function(userIds) {
var rooms = new GlideRecord("alm_stockroom");
rooms.addQuery("type", this.FIELD_AGENT_STOCKROOM_TYPE);
rooms.addQuery("manager", "IN", userIds.join());
rooms.query();
var pRoomIds = {};
while (rooms.next()) {
pRoomIds[rooms.getUniqueValue()] = rooms.getValue("manager");
}
return pRoomIds;
},
getPartsForTask: function(task) {
var modelReqQuant = {};
var taskSysId = task.sys_id;
if (!taskSysId)
taskSysId = task;
if (taskSysId) {
var partRequirement = new GlideAggregate("sm_part_requirement");
partRequirement.addQuery("service_order_task", taskSysId);
partRequirement.groupBy("model");
partRequirement.addAggregate("SUM", "required_quantity");
partRequirement.query();
while (partRequirement.next()) {
var model = partRequirement.model + "";
var requiredQuantity = +partRequirement.getAggregate("SUM", "required_quantity");
modelReqQuant[model] = requiredQuantity;
}
}
if (this.debugOn)
gs.log(JSON.stringify(modelReqQuant), "Matching Parts");
return modelReqQuant;
},
getUserPartsMatching: function(agentIds, modelReqQuant) {
if (
Object.keys(modelReqQuant).length === 0 &&
modelReqQuant.constructor === Object
) {
return this._rateUserEqually(agentIds, true);
}
if (JSUtil.nil(agentIds)) return {};
var userParts = {};
var personRoomIds = this.getPersonalRooms(agentIds);
if (this.debugOn)
gs.log(JSON.stringify(personRoomIds), "Matching Parts");
agentIds.forEach(function(id) {
userParts[id] = {};
});
var roomModels = {};
var modelsArr = Object.keys(modelReqQuant);
if (modelsArr.length > 0) {
var asset = new GlideAggregate("alm_asset");
asset.addQuery("model", "IN", modelsArr.join());
asset.addQuery("install_status", "6"); // in stock
asset.addQuery("substatus", "available");
asset.addQuery("stockroom", "IN", Object.keys(personRoomIds).join());
asset.groupBy("stockroom");
asset.groupBy("model");
asset.addAggregate("SUM", "quantity");
asset.query();
while (asset.next()) {
var assetModel = asset.model + "";
var assetRoom = asset.stockroom + "";
var requirementAmount = modelReqQuant[assetModel];
var ownedAmount = +asset.getAggregate("SUM", "quantity");
if (!roomModels.hasOwnProperty(assetRoom)) {
roomModels[assetRoom] = {
partCount: 0,
partNames: []
};
}
roomModels[assetRoom]["partNames"].push(asset.getDisplayValue());
if (requirementAmount <= ownedAmount) {
roomModels[assetRoom]["partCount"] += 1;
} else if (this.countPartial) {
roomModels[assetRoom]["partCount"] += ownedAmount / requirementAmount;
}
}
}
for (var room in personRoomIds) {
if (roomModels.hasOwnProperty(room)) {
var model = roomModels[room];
userParts[personRoomIds[room]] = {
detailedDisplayValue: model["partNames"].join(),
displayValue: model["partCount"] + " / " + modelsArr.length,
rating: model["partCount"] / modelsArr.length,
value: model["partCount"]
};
} else {
userParts[personRoomIds[room]] = {
detailedDisplayValue: gs.getMessage(
"No Matching Part Available in Personal Stockroom"
),
displayValue: "0 / " + modelsArr.length,
rating: 0,
value: 0
};
}
}
return userParts;
},
type: 'MatchingDimensionParts'
};
Sys ID
4a3f34eeffe6330032ba6f9f793bf1dd