Name
sn_itom_licensing.ITOMLicensingMSPHelperStore
Description
Helper to perform domain wise reporting for the accounted usage.
Script
var ITOMLicensingMSPHelperStore = Class.create();
ITOMLicensingMSPHelperStore.prototype = {
initialize: function (streamCountsPerDomain, bundleUsageStream, otherStreamsInBundle) {
this.streamCountsPerDomain = streamCountsPerDomain;
this.bundleUsageStream = bundleUsageStream;
this.otherStreamsInBundle = otherStreamsInBundle;
this.utils = new sn_itom_licensing.ITOMLicensingUtilsStore();
this.metadataUtil = new sn_itom_licensing.ITOMLicensingMetaDataStore();
this.otherStreamDeductions = {};
this.arrayUtil = new global.ArrayUtil();
},
accountUsageForDomains: function (skuType) {
var bundleRecords = this._getRecordsToRedistribute(skuType,"1");
var alacarteRecords = this._getRecordsToRedistribute(skuType,"0");
if (bundleRecords.length > 0){
return this._invokeRedistribution(bundleRecords, alacarteRecords);
} else {
return this._reportStreamWiseUsageForDomains(alacarteRecords);
}
},
_getRecordsToRedistribute: function (skuType,bundleType) {
var records = [];
var skuNames = this.metadataUtil.getBundleIDfromSkuAndBundleType(skuType,bundleType)
var usageGR = new GlideRecord('itom_lu_usage_account');
usageGR.addQuery('sku_name','IN',skuNames.join(","));
usageGR.addQuery('sys_domain','global');
if(bundleType == "0")
usageGR.addQuery('accounted_usage','>','0');
usageGR.query();
while (usageGR.next()) {
var record = {
'sku': usageGR.getValue('sku_name'),
'usage': usageGR.getValue('accounted_usage'),
'sys_id': usageGR.getValue('sys_id')
};
records.push(record);
}
return records;
},
_invokeRedistribution: function(bundleRecords, alacarteRecords){
var domainWiseAccountingRecs = [];
this.arrayUtil.concat(domainWiseAccountingRecs, this._redistributeUsage(bundleRecords, true));
this.arrayUtil.concat(domainWiseAccountingRecs, this._redistributeUsage(alacarteRecords, false));
// check if anything is pending
if (this._checkPendingUsage()){
this.arrayUtil.concat(domainWiseAccountingRecs, this._reportStreamWiseUsageForDomains(alacarteRecords));
}
return domainWiseAccountingRecs;
},
_checkPendingUsage: function(){
var domainWiseUsage = this._getDomainWiseUsageToAccount();
for (var j = 0; j < domainWiseUsage.length; j++) {
var domainRecord = domainWiseUsage[j];
if (domainRecord.usage > 0){
return true;
}
}
return false;
},
_reportStreamWiseUsageForDomains: function(usageRecords){
var domainWiseAccountedRecords = [];
for (var i = 0; i < usageRecords.length; i++) {
var accountedRecord = usageRecords[i];
gs.info("Accounted record "+JSON.stringify(accountedRecord));
var domainWiseUsage = this._getDomainWiseUsageToAccount(accountedRecord.sku);
for (var j = 0; j < domainWiseUsage.length; j++) {
var domainRecord = domainWiseUsage[j];
domainWiseAccountedRecords.push({
'usage': domainRecord.usage,
'domain': domainRecord.domain,
'sku': accountedRecord.sku
});
}
}
return domainWiseAccountedRecords;
},
_redistributeUsage: function (usageRecords, isBundle) {
var domainWiseAccountedRecords = [];
for (var i = 0; i < usageRecords.length; i++) {
var accountedRecord = usageRecords[i];
var domainWiseUsage = (isBundle) ? this._getDomainWiseUsageToAccount(): this._getDomainWiseUsageToAccount(accountedRecord.sku);
for (var j = 0; j < domainWiseUsage.length; j++) {
var domainRecord = domainWiseUsage[j];
if (this.otherStreamDeductions[domainRecord.domain] && this.arrayUtil.contains(this.otherStreamsInBundle, domainRecord.stream)){
domainRecord.usage -= this.otherStreamDeductions[domainRecord.domain];
}
domainWiseAccountedRecords.push({
'usage': Math.min(domainRecord.usage, accountedRecord.usage),
'domain': domainRecord.domain,
'sku': accountedRecord.sku
});
var remainingUsage = domainRecord.usage - accountedRecord.usage;
if (remainingUsage < 0) {
// within limit
accountedRecord.usage = Math.abs(remainingUsage);
if (isBundle){
this._addOtherStreamDeductionForDomain(domainRecord.domain, domainRecord.usage);
}
domainRecord.usage = 0;
} else {
// over the limit
domainRecord.usage -= accountedRecord.usage;
if (isBundle){
this._addOtherStreamDeductionForDomain(domainRecord.domain, accountedRecord.usage);
}
accountedRecord.usage = 0;
}
}
}
return domainWiseAccountedRecords;
},
_addOtherStreamDeductionForDomain: function(domain, deduction){
// In a bundle, when high water mark is calculated and accounted, we have to deduct the usage of
// high water mark stream in all other streams too. For ex, let's say that visibility is high water mark and has a usage
// of 100 SUs and health has 80 SUs. Let's say we have itom_pro bundle which has visibility and health and its capacity is 100 SUs.
// When we deduct 100 SUs from bundle for visibility, then health is also accounted for as it is part of the bundle.
this.otherStreamDeductions[domain] = deduction;
},
_getDomainWiseUsageToAccount: function (stream) {
var domainWiseUsage = [];
for (var i = 0; i < this.streamCountsPerDomain.length; i++) {
var streamCountObj = this.streamCountsPerDomain[i];
if (streamCountObj && this._checkStream(stream, streamCountObj) && streamCountObj.usage > 0) {
domainWiseUsage.push(streamCountObj);
}
}
return domainWiseUsage;
},
_checkStream: function(stream, streamCountObj){
return (stream && stream.indexOf(streamCountObj.stream) != -1 || (!stream && streamCountObj.stream == this.bundleUsageStream));
},
type: 'ITOMLicensingMSPHelperStore'
};
Sys ID
ecd4888cb786301046df8985de11a9ea