Name
global.PmProjectStatusReport
Description
Status Report API
Script
var PmProjectStatusReport = Class.create();
PmProjectStatusReport.prototype = {
initialize: function() {},
projectRecord: function(sysId, projectTable) {
//gs.info("Into projectRecord: " + sysId + " - " + projectTable);
var gr;
if (JSUtil.notNil(projectTable)) {
gr = new GlideRecord(projectTable); // for Teamspaces
} else {
gr = new GlideRecord("pm_project");
}
gr.get(sysId);
return gr;
},
getIcon: function(value) {
if (value == 'green')
return 'icon-success-circle';
else if (value == 'yellow')
return 'icon-not-started-circle';
else
return 'icon-warning-circle';
},
headerInfoPlain: function(sysId, weekDate, reportId) {
//gs.info("Into headerInfo: " + sysId);
var projectStatusRec, startDate, endDate, workStart, workEnd, approvedStartDate, approvedEndDate, cost, workCost;
if (reportId)
projectStatusRec = this.getProjectStatusBySysId(reportId);
else if (weekDate)
projectStatusRec = this.getProjectStatus(sysId, weekDate);
else {
projectStatusRec = this.getProjectStatusByProjectID(sysId);
if (projectStatusRec.hasNext())
projectStatusRec.next();
}
var projectRec = this.projectRecord(sysId);
if (JSUtil.notNil(projectStatusRec.getValue("start_date"))) {
var psd = projectStatusRec.start_date.getGlideObject();
startDate = psd.getLocalDate().getDisplayValue();
}
if (JSUtil.notNil(projectStatusRec.getValue("end_date"))) {
var ped = projectStatusRec.end_date.getGlideObject();
endDate = ped.getLocalDate().getDisplayValue();
}
if (JSUtil.notNil(projectStatusRec.getValue("work_start"))) {
var asd = projectStatusRec.work_start.getGlideObject();
workStart = asd.getLocalDate().getDisplayValue();
}
if (JSUtil.notNil(projectStatusRec.getValue("work_end"))) {
var aed = projectStatusRec.work_end.getGlideObject();
workEnd = aed.getLocalDate().getDisplayValue();
}
if (JSUtil.notNil(projectStatusRec.getValue("approved_start_date"))) {
var apsd = projectStatusRec.approved_start_date.getGlideObject();
approvedStartDate = apsd.getLocalDate().getDisplayValue();
}
if (JSUtil.notNil(projectStatusRec.getValue("approved_end_date"))) {
var aped = projectStatusRec.approved_end_date.getGlideObject();
approvedEndDate = aped.getLocalDate().getDisplayValue();
}
if (this._isProjectCurrencySelected(projectRec)) {
if (projectStatusRec.planned_cost_project_currency)
cost = projectStatusRec.planned_cost_project_currency.getDisplayValue();
if (projectStatusRec.actual_cost_project_currency)
workCost = projectStatusRec.actual_cost_project_currency.getDisplayValue();
} else {
if (projectStatusRec.planned_cost)
cost = projectStatusRec.planned_cost.getCurrencyDisplayValue();
if (projectStatusRec.work_cost)
workCost = projectStatusRec.work_cost.getCurrencyDisplayValue();
}
var statusReportData = {
short_description: projectRec.getValue("short_description"),
number: projectRec.getValue("number"),
project_manager_label: gs.getMessage("Project Manager"),
project_manager_value: projectRec.getDisplayValue("project_manager"),
portfolio_label: gs.getMessage("Portfolio"),
portfolio_value: projectRec.getDisplayValue("primary_portfolio"),
start_date_label: gs.getMessage("Planned Start Date"),
start_date_value: startDate,
work_start_label: gs.getMessage("Actual Start Date"),
work_start_value: workStart,
work_end_exists: JSUtil.notNil(projectRec.getValue("work_end")),
work_end_label: gs.getMessage("Actual End Date"),
work_end_value: workEnd,
end_date_label: gs.getMessage("Planned End Date"),
end_date_value: endDate,
approved_start_date_label: gs.getMessage("Approved Start Date"),
approved_start_date_value: approvedStartDate,
approved_end_date_label: gs.getMessage("Approved End Date"),
approved_end_date_value: approvedEndDate,
percent_complete_label: gs.getMessage("% Complete"),
percent_complete_value: projectStatusRec.getDisplayValue("percent_complete"),
state_label: gs.getMessage("State"),
state_value: projectStatusRec.getDisplayValue("state"),
planned_cost: cost,
work_cost: workCost,
phase: projectStatusRec.getDisplayValue("phase")
};
if (this._isProjectCurrencySelected(projectRec))
statusReportData["project_currency"] = projectRec.project_currency.code + '';
return statusReportData;
},
allProjectStatus: function(sysId) {
var projectStatus = [];
var gr = new GlideRecord("project_status");
gr.addQuery("project", sysId);
gr.orderByDesc("as_on");
gr.query();
//gs.info("statusRecordCount: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
while (gr.next()) {
projectStatus.push({
sys_id: gr.getValue("sys_id"),
label: gr.getDisplayValue("as_on"),
value: gr.getValue("as_on"),
selected: false
});
}
if (projectStatus.length > 0) {
projectStatus[0].selected = true;
} else {
projectStatus.push({
sys_id: -1,
label: gs.getMessage("None"),
value: "none",
selected: true
});
}
return projectStatus;
},
weeksInfo: function(sysId) {
//gs.info("Into weeksInfo: " + sysId);
var gr = this.projectRecord(sysId);
var startDate = new GlideDateTime(gr.getValue("start_date"));
var endDate = new GlideDateTime(gr.getValue("end_date"));
var startWeek = startDate.getWeekOfYearLocalTime();
var endWeek = endDate.getWeekOfYearLocalTime();
var weeks = [];
for (var i = startWeek; i <= endWeek; i++) {
weeks.push({
number: i,
name: gs.getMessage("Week {0}", i),
selected: (i == startWeek)
});
}
return {
name: gr.getValue("short_description"),
start_date: startDate.getDisplayValue(),
end_date: endDate.getDisplayValue(),
start_week: startWeek,
end_week: endWeek,
weeks: weeks
};
},
statusInfo: function(sysId) {
//gs.info("Into weeksInfo: " + sysId);
var gr = this.projectRecord(sysId);
var allProjectStatus = this.allProjectStatus(sysId);
return {
name: gr.getValue("short_description"),
choices: allProjectStatus,
init_value: allProjectStatus[0].value
};
},
otherStatus: function(statusRecord) {
//gs.info("Into overallStatus: " + statusRecord.getValue("sys_id"));
return this.otherStatusSummary(statusRecord);
},
otherStatusSummary: function(gr) {
var otherStatus = [];
otherStatus.push({
order: 1,
label: gs.getMessage("Overall"),
value: gr.getDisplayValue("overall_health"),
internal_value: this.getColorValue(gr.getValue("overall_health")),
comments: gr.getValue("comments"),
icon: this.getIcon(gr.getValue("overall_health"))
});
otherStatus.push({
order: 2,
label: gs.getMessage("Schedule"),
value: gr.getDisplayValue("schedule"),
internal_value: this.getColorValue(gr.getValue("schedule")),
comments: gr.getValue("schedule_comments"),
icon: this.getIcon(gr.getValue("schedule"))
});
otherStatus.push({
order: 3,
label: gs.getMessage("Cost"),
value: gr.getDisplayValue("cost"),
internal_value: this.getColorValue(gr.getValue("cost")),
comments: gr.getValue("cost_comments"),
icon: this.getIcon(gr.getValue("cost"))
});
otherStatus.push({
order: 4,
label: gs.getMessage("Resources"),
value: gr.getDisplayValue("resources"),
internal_value: this.getColorValue(gr.getValue("resources")),
comments: gr.getValue("resources_comments"),
icon: this.getIcon(gr.getValue("resources"))
});
otherStatus.push({
order: 5,
label: gs.getMessage("Scope"),
value: gr.getDisplayValue("scope"),
internal_value: this.getColorValue(gr.getValue("scope")),
comments: gr.getValue("scope_comments"),
icon: this.getIcon(gr.getValue("scope"))
});
return {
displayFields: otherStatus
};
},
statusByReportName: function(reportName, sysId, weekDate, reportId) {
var allStatus = [];
var gr;
if (reportId)
gr = this.getProjectStatusBySysId(reportId);
else if (weekDate)
gr = this.getProjectStatus(sysId, weekDate);
else {
var gr = this.getProjectStatusByProjectID(sysId);
if (gr.hasNext())
gr.next();
}
return this[reportName](gr);
},
getProjectStatus: function(sysId, weekDate) {
var gr = new GlideRecordSecure("project_status");
gr.addQuery("project", sysId);
if (JSUtil.notNil(weekDate))
gr.addQuery("as_on", "=", weekDate);
else
gr.addQuery("as_on", "<=", (new GlideDateTime()).getValue());
gr.orderByDesc("as_on");
gr.query();
//gs.info("statusRecordCount: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
if (gr.next()) {
return gr;
}
},
getProjectStatusBySysId: function(sysId) {
var gr = new GlideRecordSecure("project_status");
gr.get(sysId);
return gr;
},
getProjectStatusByProjectID: function(projID) {
var gr = new GlideRecordSecure("project_status");
gr.addQuery('project', projID);
gr.orderByDesc('as_on');
gr.orderByDesc('sys_created_on');
gr.setLimit(1);
gr.query();
return gr;
},
overallStatus: function(statusRecord) {
//gs.info("Into overallStatus: " + statusRecord.getValue("sys_id"));
var overallStatus = {
label: gs.getMessage("Overall Status"),
displayFields: []
};
if (JSUtil.notNil(statusRecord) && statusRecord.isValidRecord()) {
overallStatus.displayFields.push({
order: 1,
label: gs.getMessage("Executive Summary"),
value: statusRecord.getValue("executive_summary")
});
overallStatus.displayFields.push({
order: 2,
label: gs.getMessage("Achievements Last Week"),
value: statusRecord.getValue("achievements_last_week")
});
overallStatus.displayFields.push({
order: 3,
label: gs.getMessage("Key Activities planned for next week"),
value: statusRecord.getValue("key_activities_next_week")
});
/*overallStatus.displayFields.push({
order: 4,
label: gs.getMessage("Status"),
value: statusRecord.getDisplayValue("overall_health"),
internal_value: statusRecord.getValue("overall_health")
});*/
}
return overallStatus;
},
getColorValue: function(colorValue) {
if (JSUtil.nil(colorValue))
return "white";
return colorValue;
},
getWeekValue: function(dateValue) {
var date = new GlideDateTime(dateValue);
var week = date.getWeekOfYearLocalTime();
return week;
},
statusValues: function(sysId, startDate, endDate) {
//gs.info("Into statusValues: " + sysId);
var statusValues = {};
var projectGr = this.projectRecord(sysId);
var gr = new GlideRecord("project_status");
gr.addQuery("project", sysId);
if (JSUtil.notNil(startDate))
gr.addQuery("as_on", ">=", startDate);
if (JSUtil.notNil(endDate))
gr.addQuery("as_on", "<=", endDate);
else
gr.addQuery("as_on", "<=", (new GlideDateTime()).getValue());
gr.query();
//gs.info("statusRecordCount: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
while (gr.next()) {
var week = this.getWeekValue(gr.getValue("as_on"));
statusValues[week] = {
overall: this.getColorValue(gr.getValue("overall_health")),
schedule: this.getColorValue(gr.getValue("schedule")),
cost: this.getColorValue(gr.getValue("cost")),
resources: this.getColorValue(gr.getValue("resources")),
scope: this.getColorValue(gr.getValue("scope")),
};
}
//gs.info("statusValues: " + (new JSON()).encode(statusValues));
return statusValues;
},
getStatuses: function(projectId, endDate, limit) {
var projectStatus = [],
orderedStatus = [];
var gr = new GlideRecord("project_status");
gr.addQuery("project", projectId);
if (JSUtil.notNil(endDate)) {
var endDateObj = new GlideDate();
endDateObj.setDisplayValue(endDate);
gr.addQuery("as_on", "<=", endDateObj.getValue());
}
gr.setLimit(limit);
gr.orderByDesc("as_on");
gr.orderByDesc("sys_created_on");
gr.query();
//gs.info("statusRecordCount: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
while (gr.next()) {
projectStatus.push({
overall: this.getColorValue(gr.getValue("overall_health")),
comments: gr.getValue("comments"),
schedule: this.getColorValue(gr.getValue("schedule")),
schedule_comments: gr.getValue("schedule_comments"),
cost: this.getColorValue(gr.getValue("cost")),
cost_comments: gr.getValue("cost_comments"),
resources: this.getColorValue(gr.getValue("resources")),
resources_comments: gr.getValue("resources_comments"),
scope: this.getColorValue(gr.getValue("scope")),
scope_comments: gr.getValue("scope_comments"),
date: gr.getDisplayValue("as_on")
});
}
return projectStatus;
},
getStatusesFromLastReport: function(lastReportId, limit) {
//gs.info("Into getStatusesFromLastReport: " + lastReportId + " -- " + limit);
var lastProjectStatus = this.getProjectStatusBySysId(lastReportId);
var projectId = lastProjectStatus.getValue("project");
var endDate = lastProjectStatus.getValue("as_on");
var projectStatus = [];
var gr = new GlideRecord("project_status");
gr.addQuery("project", projectId);
if (JSUtil.notNil(endDate))
gr.addQuery("as_on", "<=", endDate);
else
gr.addQuery("as_on", "<=", (new GlideDateTime()).getValue());
gr.setLimit(limit || 10);
gr.orderBy("as_on");
gr.query();
//gs.info("statusRecordCount: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
while (gr.next()) {
projectStatus.push({
overall: this.getColorValue(gr.getValue("overall_health")),
schedule: this.getColorValue(gr.getValue("schedule")),
cost: this.getColorValue(gr.getValue("cost")),
resources: this.getColorValue(gr.getValue("resources")),
scope: this.getColorValue(gr.getValue("scope")),
date: gr.getValue("as_on")
});
}
return projectStatus;
},
statusReport: function(sysId, startDate, endDate) {
//gs.info("Into statusReport: " + sysId);
var statusReport = {};
// high chart plots on the based on the index of the category
statusReport['yAxis'] = {
categories: [gs.getMessage('Scope'), gs.getMessage('Resource'),
gs.getMessage('Cost'), gs.getMessage('Schedule'),
gs.getMessage('Overall')
],
title: null
};
var weeksInfo = this.weeksInfo(sysId);
var startWeek = weeksInfo.start_week;
var weeks = weeksInfo.weeks;
var statusValues = this.statusValues(sysId, startDate, endDate);
var xAxisCategories = [];
for (var i = 0; i < weeks.length; i++) {
xAxisCategories.push(weeks[i].name);
}
statusReport['xAxis'] = {
categories: xAxisCategories
}
// now re-map the start week to zero index
var data = [];
for (var i = 0; i < weeks.length; i++) {
var week = weeks[i].number;
var statusValue = statusValues[week];
var valueArray = ['scope', 'resources', 'cost', 'schedule', 'overall'];
for (var j = 0; j < valueArray.length; j++) {
var color = "white";
if (JSUtil.notNil(statusValue))
color = statusValue[valueArray[j]];
data.push({
x: i,
y: j,
color: color
});
}
}
statusReport['data'] = data;
return statusReport;
},
fiscalPeriodsForIds: function(fiscalPeriodIds) {
//gs.info("Into fiscalPeriodsForIds: " + fiscalPeriodIds.join(','));
var fiscalPeriodsArray = [];
var fiscalPeriods = new GlideRecord("fiscal_period");
fiscalPeriods.addQuery("sys_id", "IN", fiscalPeriodIds.join());
fiscalPeriods.orderBy("start_date_time");
fiscalPeriods.query();
while (fiscalPeriods.next()) {
fiscalPeriodsArray.push({
sys_id: fiscalPeriods.getValue("sys_id"),
name: fiscalPeriods.getValue("name"),
start_date_time: fiscalPeriods.getValue("fiscal_start_date_time"),
end_date_time: fiscalPeriods.getValue("fiscal_end_date_time")
})
}
//gs.info("return fiscalPeriodsForIds: " + (new JSON()).encode(fiscalPeriodsArray));
return fiscalPeriodsArray;
},
fiscalPeriodsWithinDateRange: function(startDate, endDate) {
var breakdownFiscalType = new FinancialsForPPM().getBreakdownUnit();
var fiscalPeriodsArray = [];
if (JSUtil.notNil(startDate) && JSUtil.notNil(endDate)) {
var fiscalPeriods = new GlideRecord("fiscal_period");
fiscalPeriods.addQuery("fiscal_type", breakdownFiscalType || "month");
fiscalPeriods.addQuery("fiscal_start_date_time", ">=", startDate.getValue());
fiscalPeriods.addQuery("fiscal_end_date_time", "<=", endDate.getValue());
fiscalPeriods.orderBy("start_date_time");
fiscalPeriods.query();
while (fiscalPeriods.next()) {
fiscalPeriodsArray.push({
sys_id: fiscalPeriods.getValue("sys_id"),
name: fiscalPeriods.getValue("name"),
start_date_time: fiscalPeriods.getValue("fiscal_start_date_time"),
end_date_time: fiscalPeriods.getValue("fiscal_end_date_time"),
start_date : fiscalPeriods.start_date_time.getGlideObject().getGlideDateTime().getDate(),
end_date : fiscalPeriods.end_date_time.getGlideObject().getGlideDateTime().getDate()
});
}
}
return fiscalPeriodsArray;
},
getFiscalPeriodForDate: function(date) {
//gs.info("Into getFiscalPeriodForDate - date: " + date);
if (JSUtil.notNil(date)) {
// var fiscalYear = PPMFiscalPeriod.getFiscalYearForDate(date);
var fiscalType = new FinancialsForPPM().getBreakdownUnit();
var fiscalPeriods = new GlideRecord("fiscal_period");
// fiscalPeriods.addQuery("fiscal_year", fiscalYear.getValue("sys_id"));
fiscalPeriods.addQuery("fiscal_type", fiscalType); // Take it from fiscal unit
fiscalPeriods.addQuery("fiscal_start_date_time", "<=", date);
fiscalPeriods.addQuery("fiscal_end_date_time", ">=", date);
fiscalPeriods.orderBy("start_date_time");
fiscalPeriods.query();
//gs.info("getFiscalPeriodForDate query: " + fiscalPeriods.getEncodedQuery());
if (fiscalPeriods.next()) {
//gs.info("getFiscalPeriodForDate period: " + fiscalPeriods.getValue("name"));
return fiscalPeriods;
}
}
},
breakdownRecords: function(sysId, fiscalPeriodSysIds) {
//gs.info("Into breakdownRecords: " + sysId);
var budgetValues = {};
var gr = new GlideRecord("cost_plan_breakdown");
gr.addQuery("breakdown_type", "task");
gr.addQuery("task", sysId);
if (JSUtil.notNil(fiscalPeriodSysIds))
gr.addQuery("fiscal_period", "IN", fiscalPeriodSysIds.join(","));
gr.query();
//gs.info("breakdownRecords Count: " + gr.getRowCount() + " -- " + gr.getEncodedQuery());
return gr;
},
getData: function(budgetActualValues, fiscalPeriodId) {
var budgetActual = {
budget: 0,
actual: 0
};
if (JSUtil.notNil(budgetActualValues) && JSUtil.notNil(fiscalPeriodId)) {
for (var i = 0; i < budgetActualValues.length; i++) {
if (fiscalPeriodId == budgetActualValues[i].fiscal_period) {
// entries for capex and opex
budgetActual.budget = parseFloat(budgetActual.budget) + parseFloat(budgetActualValues[i].budget);
budgetActual.actual = parseFloat(budgetActual.actual) + parseFloat(budgetActualValues[i].actual);
}
}
}
return budgetActual;
},
budgetVsActual: function(sysId) { // Cost Budget Vs Actual
//gs.info("Into budgetVsActual: " + sysId);
var arrayUtil = new ArrayUtil();
var budgetActualValues = [];
var fiscalPeriodSysIds = [];
var projectRec = this.projectRecord(sysId);
var gr = this.breakdownRecords(sysId);
while (gr.next()) {
var fiscalPeriodId = gr.getValue("fiscal_period");
//check if customer want to show function currency or project currency
if (this._isProjectCurrencySelected(projectRec)) {
budgetActualValues.push({
budget: gr.getValue("cost_project_currency"),
expense_type: gr.getValue("expense_type"),
actual: gr.getValue("actual"), //need to change
fiscal_period: fiscalPeriodId
});
} else {
budgetActualValues.push({
budget: gr.getValue("cost_default_currency"),
expense_type: gr.getValue("expense_type"),
actual: gr.getValue("actual"),
fiscal_period: fiscalPeriodId
});
}
if (!arrayUtil.contains(fiscalPeriodSysIds, fiscalPeriodId))
fiscalPeriodSysIds.push(fiscalPeriodId);
}
//gs.info("fiscalPeriodSysIds: " + fiscalPeriodSysIds.join(","));
var fiscalPeriods = this.fiscalPeriodsForIds(fiscalPeriodSysIds);
var xAxis = [];
var leastStartDate, highestEndDate;
for (var i = 0; i < fiscalPeriods.length; i++) {
if (JSUtil.nil(leastStartDate)) {
leastStartDate = new GlideDateTime(fiscalPeriods[i].start_date_time);
} else {
var startDate = new GlideDateTime(fiscalPeriods[i].start_date_time);
if (startDate.compareTo(leastStartDate) < 0)
leastStartDate = startDate;
}
if (JSUtil.nil(highestEndDate)) {
highestEndDate = new GlideDateTime(fiscalPeriods[i].end_date_time);
} else {
var endDate = new GlideDateTime(fiscalPeriods[i].end_date_time);
if (endDate.compareTo(highestEndDate) > 0)
highestEndDate = endDate;
}
}
var fiscalPeriods = this.fiscalPeriodsWithinDateRange(leastStartDate, highestEndDate);
var budgetData = [];
var actualData = [];
for (var i = 0; i < fiscalPeriods.length; i++) {
xAxis.push(fiscalPeriods[i].name);
var budgetActualValue = this.getData(budgetActualValues, fiscalPeriods[i].sys_id)
budgetData.push(budgetActualValue.budget);
actualData.push(budgetActualValue.actual);
}
// Prepare the Chart Options
var chartOptions = {
xAxis: {
categories: xAxis
},
series: [{
data: budgetData,
name: 'Planned'
}, {
data: actualData,
name: 'Actual'
}],
yAxis_title: this._isProjectCurrencySelected(projectRec) ? projectRec.project_currency.symbol + '' : PPMCurrencyHelper.defaultCurrencySymbol(),
};
if (this._isProjectCurrencySelected(projectRec))
chartOptions["projectCurrencySelected"] = true;
return chartOptions;
},
actualVsAllocated: function(sysId) { // Resource Actual Vs Allocated
//gs.info("Into actualVsAllocated: " + sysId);
var leastStartDate, highestEndDate;
var gr = this.resourcePlans(sysId);
while (gr.next()) {
if (JSUtil.nil(leastStartDate)) {
leastStartDate = new GlideDateTime(gr.getValue("start_date"));
} else {
var startDate = new GlideDateTime(gr.getValue("start_date"));
if (startDate.compareTo(leastStartDate) < 0)
leastStartDate = startDate;
}
if (JSUtil.nil(highestEndDate)) {
highestEndDate = new GlideDateTime(gr.getValue("end_date"));
} else {
var endDate = new GlideDateTime(gr.getValue("end_date"));
if (endDate.compareTo(highestEndDate) > 0)
highestEndDate = endDate;
}
}
if (JSUtil.notNil(leastStartDate)) {
var fiscalPeriodRecord = this.getFiscalPeriodForDate(leastStartDate);
if (JSUtil.notNil(fiscalPeriodRecord) && fiscalPeriodRecord.isValidRecord())
leastStartDate = new GlideDateTime(fiscalPeriodRecord.getValue("fiscal_start_date_time"));
}
if (JSUtil.notNil(highestEndDate)) {
var fiscalPeriodRecord = this.getFiscalPeriodForDate(highestEndDate);
if (JSUtil.notNil(fiscalPeriodRecord) && fiscalPeriodRecord.isValidRecord())
highestEndDate = new GlideDateTime(fiscalPeriodRecord.getValue("fiscal_end_date_time"));
}
var fiscalPeriods = this.fiscalPeriodsWithinDateRange(leastStartDate, highestEndDate);
var xAxis = [],
actualData = [],
allocatedData = [];
for (var i = 0; i < fiscalPeriods.length; i++) {
xAxis.push(fiscalPeriods[i].name);
var resourceData = this.actualVsAllocatedHours(sysId, fiscalPeriods[i]);
actualData.push(resourceData.actual);
allocatedData.push(resourceData.allocated);
}
// Prepare the Chart Options
var chartOptions = {
xAxis: {
categories: xAxis
},
series: [{
data: allocatedData,
name: 'Allocated'
},
{
data: actualData,
name: 'Actual'
}
],
yAxis_title: gs.getMessage("Hours")
};
return chartOptions;
},
resourcePlans: function(topTaskId) {
//gs.info("resourcePlans: " + topTaskId);
var gr = new GlideRecord("resource_plan");
gr.addQuery("top_task", topTaskId);
gr.orderBy("start_date");
gr.query();
//gs.info("resourcePlans query: " + gr.getEncodedQuery());
return gr;
},
getExecutiveSummary: function(projectStatusId) {
//gs.info("getExecutiveSummary: " + projectStatusId);
var statusRecord = this.getProjectStatusBySysId(projectStatusId);
return this.overallStatus(statusRecord);
},
getOtherSummary: function(projectStatusId) {
//gs.info("getOtherSummary: " + projectStatusId);
var statusRecord = this.getProjectStatusBySysId(projectStatusId);
return this.otherStatusSummary(statusRecord);
},
getVariance: function(startDate, workStart) {
//gs.info("Into getVariance: " + startDate + " - " + workStart);
var variance;
var start = new GlideDateTime(startDate);
var work = new GlideDateTime();
if (JSUtil.notNil(workStart)) {
work = new GlideDateTime(workStart);
}
variance = GlideDateTime.subtract(start, work);
var value = "";
if (work.compareTo(start) > 0 && (work.getDate().getValue() != start.getDate().getValue())) {
value = variance.getDayPart() + " Days";
}
return {
value: value,
show_icon: JSUtil.notNil(value)
};
},
getTasksByQuery: function(reportBaselineSysId, queryString, tableName) {
//gs.info("Into getTasksByQuery: " + projectSysId + " - " + queryString);
var fields_array = [gs.getMessage("Short Description"), gs.getMessage("Planned Start Date"),
gs.getMessage("Actual Start Date"), gs.getMessage("State"), gs.getMessage("Variance")
];
var tasks = [];
var gr = new GlideRecord(tableName);
gr.addEncodedQuery(queryString);
gr.orderBy("start_date");
gr.query();
//gs.info("getTasksByQuery Count: " + gr.getRowCount() + " - " + gr.getEncodedQuery());
while (gr.next()) {
var variance = this.getVariance(gr.getValue("start_date"), gr.getValue("work_start"));
tasks.push({
short_description: gr.getValue("short_description"),
start_date: gr.getDisplayValue("start_date"),
work_start: gr.getDisplayValue("work_start"),
variance: variance.value,
variance_show_icon: variance.show_icon,
state: gr.getDisplayValue("state")
});
}
var response = {
fields_array: fields_array,
tasks: tasks
};
//gs.info("getTasksByQuery: " + (new JSON()).encode(response));
return response;
},
actualVsAllocatedHours: function(projectSysId, fiscalPeriod) {
//gs.info("Into actualVsAllocatedHours: " + projectSysId + " - " + fiscalPeriod.sys_id);
var metrics = {};
metrics.actual = 0;
metrics.allocated = 0;
var refCol = 'resource_plan.top_task';
//gs.info("refCol: " + refCol);
var gr = new GlideAggregate('resource_allocation');
gr.addQuery(refCol, projectSysId);
gr.addQuery('start_date', '>=', fiscalPeriod.start_date);
gr.addQuery('start_date', '<=', fiscalPeriod.end_date);
gr.addQuery('booking_type', 1);
gr.addAggregate('SUM', 'allocated_hours');
gr.setGroup(false);
gr.query();
//gs.info("resource_allocation Query: " + gr.getEncodedQuery());
if (gr.next()) {
var allocated = gr.getAggregate('SUM', 'allocated_hours');
if (!gs.nil(allocated))
metrics.allocated = parseFloat(allocated);
}
var timeCard = new GlideAggregate('time_card');
// Time card as top task column -- Check with Pradeep.
timeCard.addAggregate('SUM', 'total');
timeCard.addQuery('week_starts_on', '>=', fiscalPeriod.start_date);
timeCard.addQuery('week_starts_on', '<=', fiscalPeriod.end_date);
timeCard.addQuery('state', 'Processed');
timeCard.setGroup(false);
var taskSubQuery = timeCard.addJoinQuery('planned_task', 'task', 'sys_id');
taskSubQuery.addCondition('top_task', projectSysId);
timeCard.query();
//gs.info("time_card Query: " + timeCard.getEncodedQuery());
if (timeCard.next()) {
var totalHours = timeCard.getAggregate('SUM', 'total');
if (!gs.nil(totalHours))
metrics.actual = parseFloat(totalHours);
}
//gs.info("metrics: " + (new JSON()).encode(metrics));
return metrics;
},
getReportBaselineId: function(reportId) {
var gr = new GlideRecord('project_status_report_baseline');
if (!gr.isValid())
return;
gr.addQuery('status_report', reportId);
gr.query();
if (gr.next())
return gr.getValue('sys_id');
return;
},
createStatusReportBaseline: function(projectId, statusReportId) {
try {
var extraFieldsMap = {
status_report: statusReportId,
cost_data : JSON.stringify(this.budgetVsActual(projectId)),
resource_data : JSON.stringify(this.actualVsAllocated(projectId))
};
var metaInfo = {
name: 'Project Status Report Basleine',
baselineConfig: '28bdc09973b300101001fcf2c4f6a779', //hardcoded config
primarySysId: projectId,
considerChildren: true,
postAction: null,
extraFieldMaps: extraFieldsMap
};
var baselineAPI = new BaselineAPI();
baselineAPI.startBaselineJob(metaInfo);
} catch (e) {
gs.debug("Project Status Report Baseline: Error occured in occured in creating the job");
gs.debug(JSON.stringify(e));
}
},
_isProjectCurrencySelected: function(projectGR) {
return projectGR.status_report_currency == "project_currency";
},
type: 'PmProjectStatusReport'
};
Sys ID
9e75b5e09f331200598a5bb0657fcf19