Name
global.PPMPortfolioEntityChange
Description
Handles changes to demand and project from Portfolio workbench gantt.
Script
var PPMPortfolioEntityChange = Class.create();
PPMPortfolioEntityChange.prototype = {
initialize: function(operations) {
this.operations = operations;
this.task = operations['sysparm_task'];
this.sysClass = this.task['sys_class_name'];
this.sysId = this.task['sys_id'];
if ( this.operations['sysparm_name'] == 'updateTask' && (this.operations['sysparm_property'] == 'planned_start_date' || this.operations['sysparm_property'] == 'rank' || this.operations['sysparm_property'] == 'capex_budget' || this.operations['sysparm_property'] == 'opex_budget') )
this.valid = true;
else
this.valid = false;
},
getTimezoneOffset: function() {
return this.operations['sysparm_timezone_offset'];
},
json: function() {
return new JSON();
},
applyChanges: function(fiscalYearId) {
PPMDebug.log("Into applyChanges");
var encodedData;
if ( this.valid ) {
PPMDebug.log("Updating the task");
var gr = new GlideRecord(this.sysClass);
if ( gr.get(this.sysId) ) {
PPMDebug.log("Record is Valid Record");
if ( this.operations['sysparm_property'] == 'planned_start_date' )
return this.handleDateChange(gr);
else if ( this.operations['sysparm_property'] == 'capex_budget' || this.operations['sysparm_property'] == 'opex_budget')
return this.handleBudgetChange(gr, fiscalYearId, this.operations['sysparm_property']);
else
return this.handleRankChange(gr, fiscalYearId);
}
}
else {
encodedData = this.json().encode({tasks:[this.task], links:[]});
return {status: true, message: 'success', info: gs.getMessage('Editing of this field is not supported'), data: encodedData};
}
},
handleRankChange: function(gr, fiscalYearId) {
if(this.task) {
var rank = 0;
if(JSUtil.notNil(this.task['rank']))
rank = this.task['rank'];
this.updateRank(gr, fiscalYearId, rank);
var encodedData = this.json().encode({tasks:[this.task], links:[], full_reload: true});
return {status: true, message: gs.getMessage('Rank changed'), data: encodedData};
}
return {status: true, message: gs.getMessage('Nothing changed'), data: '{}'};
},
handleBudgetChange : function(gr, fiscalYearId, budgetType) {
if(this.task) {
var _budget;
if(JSUtil.notNil(this.task[budgetType]))
_budget = this.task[budgetType];
this.updateBudget(gr, fiscalYearId, _budget, budgetType);
var encodedData = this.json().encode({tasks:[this.task], links:[], full_reload: true});
var _message = (budgetType === 'capex_budget') ?
gs.getMessage('Capex budget changed') : gs.getMessage('Opex budget changed');
return {status: true, message: _message, data: encodedData};
}
return {status: true, message: gs.getMessage('Nothing changed'), data: '{}'};
},
handleDateChange: function(gr) {
var api = new SNC.PlannedTaskAPI();
var gdt = api.deriveDateFromOffset(this.task['planned_start_date'], this.getTimezoneOffset());
var isFiscalYearChange = this.isFiscalYearChange(gr, gdt);
var updateFlag = true;
var encodedData;
if ( gr.instanceOf('dmn_demand') )
updateFlag = this.handleDemandDateChange(gr, gdt);
else if ( gr.instanceOf('pm_project') )
updateFlag = this.handleProjectDateChange(gr, gdt);
if(updateFlag) {
gr.get(this.sysId);
this.updateTaskWithLatestData(gr);
encodedData = this.json().encode({tasks:[this.task], links:[]});
return {status: true, message: gs.getMessage('Start date changed'), data: encodedData, full_reload: isFiscalYearChange};
} else {
var errorMessage = this._getErrorMessageAndFlushFromSession();
encodedData = this.json().encode({status:'error', message: errorMessage, tasks:[], links:[]});
return {status: false, message: gs.getMessage('Unable to perform the operation'), data: encodedData, full_reload: isFiscalYearChange};
}
},
_getErrorMessageAndFlushFromSession: function(){
/* in portfolio workbench, platform notifications are shown after page refresh,
for better user experience, get messages from session, and flush them out
ganttAjaxSuccess will take care of displaying custom notification error message
*/
var errorMessage = j2js(gs.getErrorMessages());
gs.flushMessages();
return errorMessage;
},
updateRank: function (gr, fiscalYearId, rank) {
PPMDebug.log("updateRank: " + gr.getValue("short_description") + " | " + fiscalYearId + " | " + rank);
var funding = new GlideRecord('project_funding');
funding.addQuery('task', gr.getValue('sys_id'));
if(JSUtil.notNil(fiscalYearId))
funding.addQuery('fiscal_period', fiscalYearId);
funding.query();
if ( funding.next() ) {
funding.setValue('portfolio_index', rank);
funding.update();
}
},
updateBudget : function(gr, fiscalYearId, budget, budgetType) {
PPMDebug.log("updateBudget: " + gr.getValue("short_description") + " | " + fiscalYearId + " | " + budgetType + budget);
var entity = 'task';
if(gr.instanceOf('pm_program'))
entity = 'program';
var projectFunding = new PPMProjectFunding();
var fundingRec = projectFunding.findOrCreateFundingRecordForEntity(entity, gr.getValue('sys_id'), fiscalYearId);
if(fundingRec.isValidRecord()){
fundingRec.setValue(budgetType, budget);
fundingRec.update();
}
},
isFiscalYearChange: function(gr, gdt) {
var startDate = gr.getValue("start_date");
PPMDebug.log("Old StartDate: " + startDate + " - New StartDate: " + gdt.getValue());
if(JSUtil.notNil(startDate)) {
var startDateTime = new GlideDateTime(startDate);
var fiscalPeriod = PPMFiscalPeriod.getFiscalYearForDate(startDateTime);
var newFiscalPeriod = PPMFiscalPeriod.getFiscalYearForDate(gdt);
if(fiscalPeriod.getValue("sys_id") != newFiscalPeriod.getValue("sys_id")){
PPMDebug.log("isFiscalYearChange: true");
return true;
}
}
PPMDebug.log("isFiscalYearChange: false");
return false;
},
handleDemandDateChange: function(gr, gdt) {
var start = gr.getValue('start_date');
var end = gr.getValue('requested_by');
var startDate = new GlideDate();
startDate.setValue(start);
var endDate = new GlideDate();
endDate.setValue(end);
var dur = GlideDateTime.subtract(startDate, endDate);
gr.setValue('start_date', gdt.getLocalDate());
var requestedByDate = gdt.getLocalDate();
requestedByDate.addDaysLocalTime(dur.getDayPart());
gr.setValue('requested_by', requestedByDate);
var updateFlag = gr.update();
// clear the ranks
PPMDebug.log("Previous Start Year: " + startDate.getYear() + " | New Start Year: " + gdt.getYear());
if(startDate.compareTo(gdt) <= 0 && startDate.getYear() != gdt.getYear()) {
this.updateTaskFiscalYearRanks(gr, startDate.getYear(), gdt.getYear());
}
return updateFlag;
},
handleProjectDateChange: function(gr, gdt) {
var start = gr.getValue('start_date');
var startDate = new GlideDateTime();
startDate.setValue(start);
gr.setValue('start_date', gdt.getValue());
var updateFlag = gr.update();
// clear the ranks
PPMDebug.log("Previous Start Year: " + startDate.getYear() + " | New Start Year: " + gdt.getYear());
if(startDate.compareTo(gdt) <= 0 && startDate.getYear() != gdt.getYear()) {
this.updateTaskFiscalYearRanks(gr, startDate.getYear(), gdt.getYear());
}
return updateFlag;
},
updateTaskFiscalYearRanks: function (gr, previousYear, newYear) {
PPMDebug.log("updateTaskFiscalYearRanks: " + previousYear + " | " + newYear);
if(JSUtil.notNil(previousYear) && JSUtil.notNil(newYear)) {
var diffYears = previousYear - newYear;
if(diffYears > 0) {
var fiscalYears = [];
var startYear = new GlideDateTime();
startYear.setDayOfMonth(1);
startYear.setMonth(1);
startYear.setYear(previousYear);
for (var i = 0; i < diff; i++) {
startYear.setYear(previousYear+i);
var fiscalYear = SNC.FiscalCalendar.getFiscalYearForDate(startYear.getValue());
if(JSUtil.notNil(fiscalYear)) {
this.updateRank(gr, fiscalYear, 0);
}
}
}
}
},
updateTaskWithLatestData: function(gr) {
var startDate, endDate;
var startDateMillis = this.task['start_date'];
var endDateMillis = this.task['end_date'];
if ( gr.instanceOf('dmn_demand') ) {
startDate = new GlideDateTime();
startDate.setDisplayValue(gr.getValue("start_date") + " 00:00:00");
startDateMillis = startDate.getNumericValue();
endDate = new GlideDateTime();
endDate.setDisplayValue(gr.getValue("requested_by") + " 00:00:00");
endDateMillis = endDate.getNumericValue();
} else if ( gr.instanceOf('pm_project') ){
startDate = new GlideDateTime(gr.getValue("start_date"));
startDateMillis = startDate.getNumericValue();
endDate = new GlideDateTime(gr.getValue("end_date"));
endDateMillis = endDate.getNumericValue();
}
PPMDebug.log("New Start Date: " + startDate.getValue());
PPMDebug.log("New End Date: " + endDate.getValue());
this.task['start_date'] = startDateMillis;
this.task['planned_start_date'] = startDateMillis;
this.task['end_date'] = endDateMillis;
this.task['planned_end_date'] = endDateMillis;
},
type: 'PPMPortfolioEntityChange'
};
Sys ID
48e3784c37202200277826877e41f14d