Name
global.PlanningConsoleServer
Description
Serves planning console processor requests
Script
var PlanningConsoleServer = Class.create();
PlanningConsoleServer.prototype = {
initialize: function() {
this.plannedTaskAPI = new SNC.PlannedTaskAPI();
this.ppmConfigAPI = SNC.PPMConfig;
this.PLANNED_TASK_TABLE = 'planned_task';
},
fetchPlanningConsoleData: function(entity, sysClassName, sysId, consoleId, context, fiscalYearId, loadWithPermissions) {
var metadata,
ganttData,
permissions,
schedule,
pcData = [];
metadata = this.fetchMetadata(entity, sysClassName, sysId, consoleId, context, fiscalYearId);
pcData.push(metadata);
if(entity == 'custom')
ganttData = this.fetchMultiTaskGanttData(consoleId);
else
ganttData = this.fetchTaskGanttData(entity, sysClassName, sysId, false, context, fiscalYearId, loadWithPermissions);
ganttData = this.getJson().decode(ganttData);
pcData.push(ganttData);
permissions = this.fetchPermissions(sysClassName, sysId, consoleId, context);
pcData.push(permissions);
schedule = this.fetchSchedule(sysClassName, sysId);
schedule = this.getJson().decode(schedule);
pcData.push(schedule);
return pcData;
},
fetchMetadata: function(entity, sysClassName, sysId, consoleId, context, fiscalYearId) {
var planningConsoleContext = this.getCorrectContext(entity, context),
metadata,
glideRecord,
level = 0;
if(JSUtil.notNil(consoleId) && consoleId !== '' && planningConsoleContext == 'Investment Timeline View') {
metadata = new PlannedTaskConsoleMetadata(consoleId);
return metadata.portalMetadata(entity, planningConsoleContext);
}
if(JSUtil.notNil(consoleId) && consoleId !== '') {
metadata = new PlannedTaskConsoleMetadata(consoleId);
return metadata.metadata();
}
if(!PmRecordAccessHelper.canReadRecord(sysClassName, sysId)) {
return {status: 'error', message: "User doesnot have access to the record"};
}
if(PPMTableCheck.isPortfolio(sysClassName)) {
metadata = new PortfolioMetaData(sysClassName, planningConsoleContext);
return metadata.metadata(sysId, fiscalYearId);
}
if(PPMTableCheck.isProgram(sysClassName)) {
metadata = new ProgramMetaData(sysClassName);
return metadata.metadata(sysId, fiscalYearId);
}
if(PPMTableCheck.isRelease(sysClassName)) {
metadata = new ReleaseMetadata();
return metadata.metadata(sysClassName);
}
if(PPMTableCheck.isProject(sysClassName)) {
metadata = new ProjectMetaData();
glideRecord = this.fetchProjectRecord(sysClassName, sysId);
level = this.fetchMaxLevel(glideRecord.getValue('sys_id'));
return metadata.metadata(glideRecord, level);
}
// Internally Check if the Seperate Metadata seeded for the table
if(PPMTableCheck.isPlannedTask(sysClassName)) {
metadata = new PlannedTaskMetadata(sysClassName, consoleId);
return metadata.metadata();
}
},
fetchMultiTaskGanttData: function(consoleId) {
var plannedTaskAPI = this.plannedTaskAPI,
plannedTaskCustomConsole = new PlannedTaskCustomConsole(consoleId),
matchingRecords,
matchingRecordIds,
readRecordIds = [],
multiTaskGanttDataStr;
matchingRecords = plannedTaskCustomConsole.matchingRecordIds();
matchingRecordIds = this.filterDuplicates(matchingRecords);
readRecordIds = [];
for(i=0; i<matchingRecordIds.length; i++) {
if(PmRecordAccessHelper.canReadRecord('planned_task', matchingRecordIds[i]))
readRecordIds.push(matchingRecordIds[i]);
}
multiTaskGanttDataStr = plannedTaskAPI.multiTaskGanttDataV2(plannedTaskCustomConsole.table(), readRecordIds);
return multiTaskGanttDataStr;
},
fetchTaskGanttData: function(entity, sysClassName, sysId, criticalPath, context, fiscalYearId, loadWithPermissions) {
var planningConsoleContext = this.getCorrectContext(entity, context),
contextObj,
queryConstraint,
loadPermissions,
errorStatus,
ganttDataStr;
if(PmRecordAccessHelper.canReadRecord(sysClassName, sysId)) {
contextObj = {
entity: entity,
sysClassName: sysClassName,
context: planningConsoleContext,
sysId: sysId,
fiscalYearId: fiscalYearId
};
queryConstraint = ConsoleConstraints.buildConstraintsFor(entity, fiscalYearId, contextObj);
if (!queryConstraint) {
var errorMessage = gs.getMessage('Invalid Fiscal Period');
errorStatus = {
status: 'error',
message: errorMessage
};
return this.getJson().encode(errorStatus);
}
loadPermissions = (loadWithPermissions === false) ? false : true;
var topTask = sysId;
var hasLinksOutside = false;
// **Support for sub project start**
//if its sub project build a query for sub project
if(sysId){
var _gr = new GlideRecord('planned_task');
if(_gr.get(sysId)){
topTask = _gr.getValue('top_task');
if(topTask != sysId){
//add wbs logic
var projectEncodedQuery ="";
if(queryConstraint){
projectEncodedQuery = queryConstraint.getNodeQueryCondition(sysClassName)|| "";
}else{
queryConstraint = new SNC.QueryConstraint();
}
var wbs = _gr.getValue('wbs');
//check links
var oLinkQuery = "child.ref_planned_task.wbs=" + wbs + "^ORchild.ref_planned_task.wbsSTARTSWITH" + wbs
+ ".^child.ref_planned_task.top_task="+ topTask
+ "^parent.ref_planned_task.wbs!="+ wbs + "^parent.ref_planned_task.wbsNOT LIKE"+wbs+".%";
var grRel = new GlideRecord('planned_task_rel_planned_task');
grRel.addEncodedQuery(oLinkQuery);
grRel.query();
hasLinksOutside = grRel.getRowCount() > 0;
var outsideTasks = [topTask];
while(grRel.next()){
outsideTasks.push(grRel.getValue('parent'));
}
projectEncodedQuery += "wbsSTARTSWITH"+wbs+".^ORwbs="+wbs+"^ORsys_idIN"+outsideTasks.join();
//append project query
queryConstraint.addNodeQueryCondition(sysClassName, projectEncodedQuery);
//project task query
var oPPMConfig = new SNC.PPMConfig();
var projTaskTable = 'pm_project_task';
var configId = oPPMConfig.getConfigId(sysClassName);
if(configId){
projTaskTable = oPPMConfig.getProjectTaskTable(configId);
}
queryConstraint.addNodeQueryCondition(projTaskTable, projectEncodedQuery);
}
}
}
// **Support for sub project end**
ganttDataStr = this.plannedTaskAPI.ganttDataV2(sysClassName, planningConsoleContext, topTask, queryConstraint, criticalPath, loadPermissions);
if (topTask != sysId) {
var ganttData = this.getJson().decode(ganttDataStr);
ganttData.hideTopTask = topTask;
ganttData.hasLinksOutside = hasLinksOutside;
if (ganttData && ganttData.tasks) {
for (var t = 0; t < ganttData.tasks.length; t++) {
if (ganttData.tasks[t].sys_id == sysId) {
ganttData.tasks[t].parent = "";
ganttData._project_sub_tree_wbs = ganttData.tasks[t].wbs;
break;
}
}
}
ganttDataStr = this.getJson().encode(ganttData);
}
} else {
errorStatus = {
status: 'error',
message: 'User doesnot have access to the record'
};
ganttDataStr = this.getJson().encode(errorStatus);
}
return ganttDataStr;
},
fetchPermissions: function(sysClassName, sysId, consoleId, context) {
var ppmConsoleAccessStrategy = new PPMConsoleAccessStrategy(),
planningConsoleContext = !!context ? context : 'default',
accessConfig;
accessConfig = ppmConsoleAccessStrategy.accessConfig(sysClassName, sysId, consoleId, planningConsoleContext);
return accessConfig;
},
fetchSchedule: function(sysClassName, sysId, scheduleId, scheduleTimezone, startYear, endYear, forward) {
var isScheduleId = !!scheduleId,
errorStatus,
scheduleStr;
if(PmRecordAccessHelper.canReadRecord(sysClassName, sysId)) {
if(isScheduleId)
scheduleStr = this.plannedTaskAPI.getSchedule(scheduleId, scheduleTimezone, startYear, endYear, forward);
else
scheduleStr = this.plannedTaskAPI.getScheduleForTaskId(sysId);
if (JSUtil.nil(JSON.parse(scheduleStr))) {
errorStatus = {
status: 'error',
message: gs.getMessage('Could not fetch schedule')
};
scheduleStr = this.getJson().encode(errorStatus);
}
} else {
errorStatus = {
status: 'error',
message: gs.getMessage('User does not have access to the record')
};
scheduleStr = this.getJson().encode(errorStatus);
}
return scheduleStr;
},
fetchNotifications: function(sysClassName, sysId) {
var notifications = [];
if(!PPMTableCheck.isProject(sysClassName))
return notifications;
var projectRecord,
isProjectClosed,
ptStateUtil,
projectNotifications;
projectRecord = this.fetchProjectRecord(sysClassName, sysId);
ptStateUtil = new PlannedTaskStateUtil(projectRecord);
isProjectClosed = ptStateUtil.isStateInactive(projectRecord.state);
if(isProjectClosed && GlidePluginManager.isActive('com.snc.resource_management')) {
projectNotifications = new ProjectOpenNotifications();
notifications = notifications.concat(projectNotifications.addPlanningConsoleNotifications(sysClassName, sysId));
}
return notifications;
},
fetchProjectRecord: function(sysClassName, sysId) {
var ppmConfigAPI = this.ppmConfigAPI,
projectTableName = ppmConfigAPI.getProjectTable(sysClassName),
projectRecord;
projectRecord = new GlideRecord(projectTableName);
projectRecord.get(sysId);
return projectRecord;
},
fetchMaxLevel: function(projectSysId) {
var plannedTaskTable = this.PLANNED_TASK_TABLE,
levelAggregates,
maxLevel;
levelAggregates = new GlideAggregate(plannedTaskTable);
levelAggregates.addQuery('top_task', projectSysId);
levelAggregates.addAggregate('MAX', 'level');
levelAggregates.orderByAggregate('MAX', 'level'); //Descending order
levelAggregates.query();
if(levelAggregates.next())
maxLevel = levelAggregates.getAggregate('MAX', 'level');
return maxLevel;
},
filterDuplicates: function(matchingRecords) {
var ids = [],
parentIds = [],
arrayUtil = new ArrayUtil(),
childParents = [],
index,
i;
for(i=0; i<matchingRecords.length; i++) {
ids.push(matchingRecords[i].sys_id);
if(JSUtil.notNil(matchingRecords[i].parent)) {
if(arrayUtil.contains(parentIds, matchingRecords[i].parent));
parentIds.push(matchingRecords[i].parent);
}
}
// Check if the parent(s) already exists in the ids
for(i=0; i<parentIds.length; i++) {
if(arrayUtil.contains(ids, parentIds[i])) {
childParents.push(parentIds[i]);
}
}
// Now remove all the children of that parent already exists in the ids
for(i=0; i<matchingRecords.length; i++) {
if(arrayUtil.contains(childParents, matchingRecords[i].parent)) {
index = ids.indexOf(matchingRecords[i].sys_id);
ids.splice(index, 1);
}
}
// By this time, all the children of the parent(s) are removed.
// There might exists children whose parent(s) are not part of childParents
// Remove the same
for(i=0; i<childParents.length; i++) {
index = parentIds.indexOf(childParents[i]);
parentIds.splice(index, 1);
}
//gs.info("Left over parentIds: " + new JSON().encode(parentIds));
// Remove all the left over parent children
for(i=0; i<matchingRecords.length; i++) {
if(arrayUtil.contains(parentIds, matchingRecords[i].parent)) {
index = ids.indexOf(matchingRecords[i].sys_id);
ids.splice(index, 1);
}
}
return ids;
},
getCorrectContext: function(entity, context) {
var correctContext = (entity == 'custom' ? 'my_gantt' : context);
return correctContext;
},
getJson: function() {
return new JSON();
},
type: 'PlanningConsoleServer'
};
Sys ID
579981750b002300d08dae9863673aaa