|
| 1 | +var projectId = '<SYS ID of Project (pm_project)>'; |
| 2 | + |
| 3 | +var instanceName = gs.getProperty('instance_name'); |
| 4 | + |
| 5 | +gs.info('Ensure you have clicked the "Calculate Completion Estimates" related link on the Project form to sync up the EAC with the latest data.'); |
| 6 | +gs.info(''); |
| 7 | +var fiscalCal = new ITFM_FiscalCalendar(); |
| 8 | +var fiscalObject = fiscalCal.validatePeriods(); |
| 9 | +var parsedFiscalObject = JSON.parse(fiscalObject); |
| 10 | + |
| 11 | +if (parsedFiscalObject.type == "Error") { |
| 12 | +gs.info('Fiscal Calendar is not valid which may cause issues with the expected EAC calculation:'); |
| 13 | +gs.info(parsedFiscalObject.msg); |
| 14 | +} |
| 15 | + |
| 16 | +var currentFiscalPeriod = new FinancialsForPPM().getCurrentFiscalPeriod(); |
| 17 | +var currentFiscalPeriodId = JSON.parse(currentFiscalPeriod).fiscal_period; |
| 18 | +var grFP = new GlideRecord('fiscal_period'); |
| 19 | +grFP.get(currentFiscalPeriodId); |
| 20 | + |
| 21 | +var startDate = grFP.getValue('start_date_time'); |
| 22 | +var year = startDate.substring(0,4); |
| 23 | +var month = startDate.substring(4,6); |
| 24 | +var day = startDate.substring(6,8); |
| 25 | +var date = year + "-" + month + "-" + day; |
| 26 | + |
| 27 | +gs.info(''); |
| 28 | +gs.info('The current Fiscal Period is named "' + grFP.getDisplayValue() + '" and the Sys ID is ' + currentFiscalPeriodId); |
| 29 | + |
| 30 | +gs.info(''); |
| 31 | +gs.info('EAC calculation: Total actual costs from previous months + Total planned cost from the current and future months'); |
| 32 | + |
| 33 | +var capexFuture = 0; |
| 34 | +var opexFuture = 0; |
| 35 | +var capexActual = 0; |
| 36 | +var opexActual = 0; |
| 37 | + |
| 38 | +var aggCapexFuture = new GlideAggregate('cost_plan_breakdown'); |
| 39 | +aggCapexFuture.addAggregate('SUM', 'cost_default_currency'); |
| 40 | +aggCapexFuture.addEncodedQuery("breakdown_type=task^task=" + projectId + "^expense_type=capex^fiscal_period.fiscal_start_date_time>=javascript:gs.dateGenerate('" + date + "','00:00:00')"); |
| 41 | +aggCapexFuture.setGroup(false); |
| 42 | +aggCapexFuture.query(); |
| 43 | +if (aggCapexFuture.next()) { |
| 44 | +capexFuture = aggCapexFuture.getAggregate('SUM', 'cost_default_currency'); |
| 45 | +gs.info(''); |
| 46 | +gs.info('Capex Future Costs: ' + aggCapexFuture.getAggregate('SUM', 'cost_default_currency')); |
| 47 | +gs.info("https://" + instanceName + ".service-now.com/" + "cost_plan_breakdown_list.do?sysparm_query=breakdown_type%3Dtask%5Etask%3D" + projectId + "%5Eexpense_type%3Dcapex%5Efiscal_period.fiscal_start_date_time%3E%3Djavascript%3Ags.dateGenerate('" + date + "'%2C'00%3A00%3A00')&sysparm_view="); |
| 48 | +} |
| 49 | + |
| 50 | +var aggOpexFuture = new GlideAggregate('cost_plan_breakdown'); |
| 51 | +aggOpexFuture.addAggregate('SUM', 'cost_default_currency'); |
| 52 | +aggOpexFuture.addEncodedQuery("breakdown_type=task^task=" + projectId + "^expense_type=opex^fiscal_period.fiscal_start_date_time>=javascript:gs.dateGenerate('" + date + "','00:00:00')"); |
| 53 | +aggOpexFuture.setGroup(false); |
| 54 | +aggOpexFuture.query(); |
| 55 | +if (aggOpexFuture.next()) { |
| 56 | +opexFuture = aggOpexFuture.getAggregate('SUM', 'cost_default_currency'); |
| 57 | +gs.info(''); |
| 58 | +gs.info('Opex Future Costs: ' + aggOpexFuture.getAggregate('SUM', 'cost_default_currency')); |
| 59 | +gs.info("https://" + instanceName + ".service-now.com/" + "cost_plan_breakdown_list.do?sysparm_query=breakdown_type%3Dtask%5Etask%3D" + projectId + "%5Eexpense_type%3Dopex%5Efiscal_period.fiscal_start_date_time%3E%3Djavascript%3Ags.dateGenerate('" + date + "'%2C'00%3A00%3A00')&sysparm_view="); |
| 60 | +} |
| 61 | + |
| 62 | +var aggCapexActual = new GlideAggregate('cost_plan_breakdown'); |
| 63 | +aggCapexActual.addAggregate('SUM', 'actual'); |
| 64 | +aggCapexActual.addEncodedQuery("breakdown_type=task^task=" + projectId + "^expense_type=capex^fiscal_period.fiscal_start_date_time<javascript:gs.dateGenerate('" + date + "','00:00:00')"); |
| 65 | +aggCapexActual.setGroup(false); |
| 66 | +aggCapexActual.query(); |
| 67 | +if (aggCapexActual.next()) { |
| 68 | +capexActual = aggCapexActual.getAggregate('SUM', 'actual'); |
| 69 | +gs.info(''); |
| 70 | +gs.info('Capex Past Actual Costs: ' + aggCapexActual.getAggregate('SUM', 'actual')); |
| 71 | +gs.info("https://" + instanceName + ".service-now.com/" + "cost_plan_breakdown_list.do?sysparm_query=breakdown_type%3Dtask%5Etask%3D" + projectId + "%5Eexpense_type%3Dcapex%5Efiscal_period.fiscal_start_date_time%3Cjavascript%3Ags.dateGenerate('" + date + "'%2C'00%3A00%3A00')&sysparm_view="); |
| 72 | +} |
| 73 | + |
| 74 | +var aggOpexActual = new GlideAggregate('cost_plan_breakdown'); |
| 75 | +aggOpexActual.addAggregate('SUM', 'actual'); |
| 76 | +aggOpexActual.addEncodedQuery("breakdown_type=task^task=" + projectId + "^expense_type=opex^fiscal_period.fiscal_start_date_time<javascript:gs.dateGenerate('" + date + "','00:00:00')"); |
| 77 | +aggOpexActual.setGroup(false); |
| 78 | +aggOpexActual.query(); |
| 79 | +if (aggOpexActual.next()) { |
| 80 | +opexActual = aggOpexActual.getAggregate('SUM', 'actual'); |
| 81 | +gs.info(''); |
| 82 | +gs.info('Opex Past Actual Costs: ' + aggOpexActual.getAggregate('SUM', 'actual')); |
| 83 | +gs.info("https://" + instanceName + ".service-now.com/" + "cost_plan_breakdown_list.do?sysparm_query=breakdown_type%3Dtask%5Etask%3D" + projectId + "%5Eexpense_type%3Dopex%5Efiscal_period.fiscal_start_date_time%3Cjavascript%3Ags.dateGenerate('" + date + "'%2C'00%3A00%3A00')&sysparm_view="); |
| 84 | +} |
| 85 | + |
| 86 | +gs.info(''); |
| 87 | +gs.info('Plugged into the formula (CapexNowAndFuture + OpexNowAndFuture + CapexPastActuals + OpexPastActuals) = EAC'); |
| 88 | +gs.info(Number(capexFuture) + ' + ' + Number(opexFuture) + ' + ' + Number(capexActual) + ' + ' + Number(opexActual) + ' = EAC'); |
| 89 | +var sum = Number(capexFuture) + Number(opexFuture) + Number(capexActual) + Number(opexActual); |
| 90 | +gs.info('Expected EAC = ' + sum); |
0 commit comments