Skip to content

Commit 987da68

Browse files
authored
Noah drew patch 2 (#1961)
* Create Explain Project EAC (Estimate At Completion) Value The Estimate At Completion value (EAC) for Projects can be hard to visualize. This script will print out messages to explain the calculation and how the value is getting calculated. Run this in the [System Defintion > Scripts - Background] module. Set the "projectId" variable on line 1 with the Sys ID of your pm_project record * Delete Specialized Areas/Project Management/Explain Project EAC (Estimate At Completion) Value directory * Create Create Explain Project EAC (Estimate At Completion) Value * Create README.md
1 parent 4f3ad75 commit 987da68

File tree

2 files changed

+95
-0
lines changed

2 files changed

+95
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
The Estimate At Completion value (EAC) for Projects can be hard to visualize.
2+
This script will print out messages to explain the formula and how the value is getting calculated.
3+
4+
Run this in the [System Defintion > Scripts - Background] module.
5+
Set the "projectId" variable on line 1 with the Sys ID of your pm_project record.

0 commit comments

Comments
 (0)