{"version":3,"sources":["../../../../../dev/j/v2/smb/apps/smb-pmg-roi.js"],"names":["Vue","use","VueNumeric","config","devtools","appHook","document","getElementById","length","el","delimiters","beforeCreate","this","PRICELIST","JSON","parse","dataset","pricelist","PRODUCT_KEY","pricelistProductKey","HOURS_MULTIPLIER","data","numberOfEndpoints","numberOfAdmins","averageHourlyRate","apps","name","minutes","computed","avgNumberOfEndpoints","totalHoursSaved","multiplier","reduce","acc","val","unitPrice","getUnitPrice","products","totalLicenceCost","totalSoftCostSavings","roi","methods","pricelistProduct","quantity","discount","key","getTierPriceKeyForQuantity","prices","getReversedArrayKeys","filter","base","Number","arr","Object","keys","reverse","formatPrice","value","fixedPrice","getFixedPrice","priceFormat","replace","currencySymbol","decimalSeparator","precision","thousandSeparator","parseFloat","toFixed","parts","toString","split","join","htmlDecode","input","DOMParser","parseFromString","documentElement","textContent","filters"],"mappings":"CAQA,WACC,YAEAA,KAAIC,IAAIC,WAAAA,YACRF,IAAIG,OAAOC,UAAW,CAEtB,IAAIC,GAAUC,SAASC,eAAe,cAEtC,IAAuB,IAAnBF,EAAQG,OACX,OAAO,CAGE,IAAIR,MACbS,GAAIJ,EACJK,YAAa,KAAM,MAEnBC,aAAc,WACbC,KAAKC,UAAYC,KAAKC,MAAMV,EAAQW,QAAQC,WAAa,MACzDL,KAAKM,YAAcb,EAAQW,QAAQG,oBACnCP,KAAKQ,iBAAmB,MAGzBC,MACCC,kBAAmB,GACnBC,eAAgB,EAChBC,kBAAmB,GACnBC,OACCC,KAAM,OACNC,QAAS,IAETD,KAAM,gBACNC,QAAS,IAETD,KAAM,kBACNC,QAAS,IAETD,KAAM,OACNC,QAAS,IAETD,KAAM,QACNC,QAAS,KAIXC,UACCC,qBAAsB,WACrB,MAAKjB,MAAKW,eAGHX,KAAKU,kBAAoBV,KAAKW,eAF7B,GAKTO,gBAAiB,WAChB,GAAIC,GAAanB,KAAKQ,gBACtB,OAAOR,MAAKa,KAAKO,OAAO,SAASC,EAAKC,GACrC,MAAOD,GAAMC,EAAIP,QAAUI,GACzB,IAGJI,UAAW,WACV,MAAOvB,MAAKwB,aAAaxB,KAAKC,UAAUwB,SAASzB,KAAKM,aAAcN,KAAKiB,uBAG1ES,iBAAkB,WACjB,MAAO1B,MAAKU,kBAAoBV,KAAKuB,WAGtCI,qBAAsB,WACrB,MAAO3B,MAAKY,kBAAoBZ,KAAKkB,iBAGtCU,IAAK,WACJ,MAAK5B,MAAKY,kBAGHZ,KAAK0B,iBAAmB1B,KAAKY,kBAF5B,IAMViB,SAQCL,aAAc,SAASM,EAAkBC,EAAUC,GAClD,GAAIC,GAAMjC,KAAKkC,2BAA2BJ,EAAkBC,GACxDR,EAAYO,EAAiBK,OAAOF,EAExC,OADAV,IAAaA,GAAaS,GAAY,IASvCE,2BAA4B,SAASJ,EAAkBC,GAGtD,MAFAA,GAAWA,EAAW,EAAI,EAAIA,EACR/B,KAAKoC,qBAAqBN,EAAiBK,QAC1CE,OAAO,SAASC,GACtC,MAAOP,IAAYQ,OAAOD,KACxB,IAOJF,qBAAsB,SAASI,GAC9B,MAAOC,QAAOC,KAAKF,GAAKG,WAOzBC,YAAa,SAASC,GACrB,GAAIxC,GAAYL,KAAKC,UACjB6C,EAAa9C,KAAK+C,cAAcF,EACpC,OAAOxC,GAAU2C,YAAYC,QAAQ,KAAM5C,EAAU6C,gBAAgBD,QAAQ,KAAMH,IAOpFC,cAAe,SAASF,GACvB,GAAIM,GAAmBnD,KAAKC,UAAUkD,iBACrCC,EAAYpD,KAAKC,UAAUmD,UAC3BC,EAAoBrD,KAAKC,UAAUoD,kBAEhCP,EAAaQ,WAAWf,OAAOM,IAAQU,QAAQH,GAC/CI,EAAQV,EAAWW,WAAWC,MAAM,IAGxC,OAFAF,GAAM,GAAKA,EAAM,GAAGP,QAAQ,wBAAyBI,GAE9CG,EAAMG,KAAKR,IAOnBS,WAAY,SAASC,GAEpB,OADU,GAAIC,YAAYC,gBAAgBF,EAAO,aACtCG,gBAAgBC,cAI7BC,SACCX,QAAS,SAASV,EAAOO,GACxB,MAAOE,YAAWf,OAAOM,IAAQU,QAAQH","file":"smb-pmg-roi.js","sourcesContent":["/**\n * vue-smb-pmg-roi\n * @version 1.0.0\n * @author Erik Ondrus \n * @requires accounting.min.js\t(j/v2/smb/vendor/accounting.min.js)\n * @requires vue-numeric.min.js\t(j/v2/smb/vendor/vue-numeric.min.js)\n */\n\n(function() {\n\t'use strict';\n\n\tVue.use(VueNumeric.default); // todo\n\tVue.config.devtools = true;\n\n\tvar appHook = document.getElementById('vue-pmg-roi');\n\n\tif (appHook.length === 0) {\n\t\treturn false;\n\t}\n\n\tvar app = new Vue({\n\t\tel: appHook,\n\t\tdelimiters: ['{%', '%}'],\n\n\t\tbeforeCreate: function() {\n\t\t\tthis.PRICELIST = JSON.parse(appHook.dataset.pricelist || null);\n\t\t\tthis.PRODUCT_KEY = appHook.dataset.pricelistProductKey;\n\t\t\tthis.HOURS_MULTIPLIER = 1.67; // what is this value?\n\t\t},\n\n\t\tdata: {\n\t\t\tnumberOfEndpoints: 50,\n\t\t\tnumberOfAdmins: 1,\n\t\t\taverageHourlyRate: 70,\n\t\t\tapps: [{\n\t\t\t\tname: 'Zoom',\n\t\t\t\tminutes: 4\n\t\t\t}, {\n\t\t\t\tname: 'Google Chrome',\n\t\t\t\tminutes: 3\n\t\t\t}, {\n\t\t\t\tname: 'Mozilla Firefox',\n\t\t\t\tminutes: 3\n\t\t\t}, {\n\t\t\t\tname: 'Java',\n\t\t\t\tminutes: 5\n\t\t\t}, {\n\t\t\t\tname: 'Adobe',\n\t\t\t\tminutes: 5\n\t\t\t}]\n\t\t},\n\n\t\tcomputed: {\n\t\t\tavgNumberOfEndpoints: function() {\n\t\t\t\tif (!this.numberOfAdmins) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\treturn this.numberOfEndpoints / this.numberOfAdmins;\n\t\t\t},\n\n\t\t\ttotalHoursSaved: function() {\n\t\t\t\tvar multiplier = this.HOURS_MULTIPLIER;\n\t\t\t\treturn this.apps.reduce(function(acc, val) {\n\t\t\t\t\treturn acc + val.minutes * multiplier;\n\t\t\t\t}, 0);\n\t\t\t},\n\n\t\t\tunitPrice: function() {\n\t\t\t\treturn this.getUnitPrice(this.PRICELIST.products[this.PRODUCT_KEY], this.avgNumberOfEndpoints);\n\t\t\t},\n\n\t\t\ttotalLicenceCost: function() {\n\t\t\t\treturn this.numberOfEndpoints * this.unitPrice;\n\t\t\t},\n\n\t\t\ttotalSoftCostSavings: function() {\n\t\t\t\treturn this.averageHourlyRate * this.totalHoursSaved;\n\t\t\t},\n\n\t\t\troi: function() {\n\t\t\t\tif (!this.averageHourlyRate) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\treturn this.totalLicenceCost / this.averageHourlyRate;\n\t\t\t}\n\t\t},\n\n\t\tmethods: {\n\n\t\t\t/*\n\t\t\t * @param {object} pricelistProduct - specific product in pricelist\n\t\t\t * @param {number} quantity - number of selected quantity => used for indetify tier price\n\t\t\t * @param {number} discount - percent discount in decimal format\n\t\t\t * @returns {number} Current UnitPrice\n\t\t\t */\n\t\t\tgetUnitPrice: function(pricelistProduct, quantity, discount) {\n\t\t\t\tvar key = this.getTierPriceKeyForQuantity(pricelistProduct, quantity);\n\t\t\t\tvar unitPrice = pricelistProduct.prices[key];\n\t\t\t\tunitPrice -= unitPrice * (discount || 0);\n\t\t\t\treturn unitPrice;\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * @param {object} pricelistProduct - specific product in pricelist\n\t\t\t * @param {string} quantity - number of selected quantity => used for indetify tier price\n\t\t\t * @returns {number} Key of current price level\n\t\t\t */\n\t\t\tgetTierPriceKeyForQuantity: function(pricelistProduct, quantity) {\n\t\t\t\tquantity = quantity < 1 ? 1 : quantity; // get unit price for 0 quantity\n\t\t\t\tvar rangeOfquantity = this.getReversedArrayKeys(pricelistProduct.prices); // [..., \"50\", \"20\", \"5\", \"1\"]\n\t\t\t\treturn rangeOfquantity.filter(function(base) {\n\t\t\t\t\treturn quantity >= Number(base);\n\t\t\t\t})[0]; // return first key where the quantity is higher than the base\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * @param {arr} - array to process\n\t\t\t * @returns {array}\n\t\t\t */\n\t\t\tgetReversedArrayKeys: function(arr) {\n\t\t\t\treturn Object.keys(arr).reverse();\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * @param {number} value - Price\n\t\t\t * @returns {string} Formatted price with currency symbol\n\t\t\t */\n\t\t\tformatPrice: function(value) {\n\t\t\t\tvar pricelist = this.PRICELIST;\n\t\t\t\tvar fixedPrice = this.getFixedPrice(value);\n\t\t\t\treturn pricelist.priceFormat.replace('#c', pricelist.currencySymbol).replace('#p', fixedPrice);\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * @param {number} value - price to fix\n\t\t\t * @returns {number} Fixed price with correct separators\n\t\t\t */\n\t\t\tgetFixedPrice: function(value) {\n\t\t\t\tvar decimalSeparator = this.PRICELIST.decimalSeparator,\n\t\t\t\t\tprecision = this.PRICELIST.precision,\n\t\t\t\t\tthousandSeparator = this.PRICELIST.thousandSeparator;\n\n\t\t\t\tvar fixedPrice = parseFloat(Number(value)).toFixed(precision);\n\t\t\t\tvar parts = fixedPrice.toString().split('.');\n\t\t\t\tparts[0] = parts[0].replace(/\\B(?=(\\d{3})+(?!\\d))/g, thousandSeparator);\n\n\t\t\t\treturn parts.join(decimalSeparator);\n\t\t\t},\n\n\t\t\t/*\n\t\t\t * @param {string} input - Value to decode (£)\n\t\t\t * @returns {string} Decoded value (£)\n\t\t\t */\n\t\t\thtmlDecode: function(input) {\n\t\t\t\tvar doc = new DOMParser().parseFromString(input, 'text/html');\n\t\t\t\treturn doc.documentElement.textContent;\n\t\t\t}\n\t\t},\n\n\t\tfilters: {\n\t\t\ttoFixed: function(value, precision) {\n\t\t\t\treturn parseFloat(Number(value)).toFixed(precision);\n\t\t\t}\n\t\t}\n\t});\n})();\n"]}