Name
global.InterProjectTaskDeletionHandler
Description
Called on task deletion - if task and relation is getting deleted, check if relation is shadow relation, then remove the inter project depedency
Script
var InterProjectTaskDeletionHandler = Class.create();
InterProjectTaskDeletionHandler.prototype = {
initialize: function() {
this.api = new SNC.PlannedTaskAPI();
},
_getPayload: function(deletedTasksAndRelations) {
PPMDebug.log("Into InterProjectTaskDeletionHandler._getPayload -> " + deletedTasksAndRelations);
var data;
if ( JSUtil.nil(deletedTasksAndRelations) ) {
data = {};
data.tasks = [];
data.links = [];
return data;
}
data = (new JSON()).decode(deletedTasksAndRelations);
if ( JSUtil.nil(data.tasks) )
data.tasks = [];
if ( JSUtil.nil(data.relations) )
data.relations = [];
data.notificationFilter = '';
data.relations.forEach(function(relation) {
if ( JSUtil.notNil(relation.orig_sys_id) ) {
relation.shadow = true;
var result = data.tasks.filter(function(task) { return task.sys_id == relation.child; });
PPMDebug.log("InterProjectTaskDeletionHandler._getPayload result - child -> " + (new JSON()).encode(result));
if ( result.length > 0 ) {
if ( result[0].shadow == true ) {
relation.nonShadowEndPoint = 'parent'; //shadow task in pred project deleted
}
else {
data.notificationFilter = 'task=' + relation.child; //actual task in succ project deleted
relation.nonShadowEndPoint = 'child';
}
}
result = data.tasks.filter(function(task) { return task.sys_id == relation.parent; });
PPMDebug.log("InterProjectTaskDeletionHandler._getPayload result - parent -> " + (new JSON()).encode(result));
if ( result.length > 0 ) {
if ( result[0].shadow == true ) {
data.notificationFilter = 'task=' + relation.child; //shadow task in succ project deleted
relation.nonShadowEndPoint = 'child';
}
else {
data.notificationFilter = 'source=' + relation.parent; // actual task in pred project deleted
relation.nonShadowEndPoint = 'parent';
}
}
}
});
PPMDebug.log("Return InterProjectTaskDeletionHandler._getPayload -> " + (new JSON()).encode(data));
return data;
},
process: function(deletedTasksAndRelations) {
PPMDebug.log("Into InterProjectTaskDeletionHandler.process -> " + deletedTasksAndRelations);
var data = this._getPayload(deletedTasksAndRelations);
var relationsToDelete = [];
var tasksToDelete = [];
var projectsToRecalculate = [];
var self = this;
data.relations.forEach(function(relation) {
if ( relation.shadow === true ) {
relationsToDelete.push(relation.orig_sys_id);
var relations = ShadowTaskQueryHelper.findShadowRelations(relation.orig_sys_id);
while ( relations.next() )
relationsToDelete.push(relations.getValue('sys_id'));
PPMDebug.log("InterProjectTaskDeletionHandler.process relation -> " + (new JSON()).encode(relation));
var gr = new GlideRecord('planned_task');
var taskId;
if ( relation.nonShadowEndPoint == 'child' )
taskId = relation.child;
else
taskId = relation.parent;
if ( gr.get('orig_sys_id', taskId) ) {
PPMDebug.log("InterProjectTaskDeletionHandler.process - delete shadow -> " + gr.getValue("number") +
" - " + gr.getValue("short_description") + " - " + gr.top_task.short_description);
// check if the task has other relations on the task
var relationService = new PlannedTaskRelationDBService();
allRelations = relationService.allRelations(gr.getValue("sys_id"), [relation.id || relation.sys_id]);
if(JSUtil.nil(allRelations) || allRelations.getRowCount() == 0) {
tasksToDelete.push(gr.getValue('sys_id'));
projectsToRecalculate.push(gr.getValue('top_task'));
}
}
var result = data.tasks.filter(function(task) { return task.sys_id == relation.child; });
if ( result.length > 0 )
taskId = relation.parent;
else
taskId = relation.child;
if ( self._taskShouldBeDeleted(taskId) )
tasksToDelete.push(taskId);
}
});
//check if any task is not deleted yet due to cascade delete
var projectsToBeRecalculated = [];
data.tasks.forEach(function(task) {
if ( task.shadow !== true ) {
var gr = new GlideRecord('planned_task');
gr.addQuery('orig_sys_id', task.sys_id);
gr.query();
while(gr.next()){ // check if originated sys_id
tasksToDelete.push(gr.getValue("sys_id"));
var subTreeRoot = gr.getValue("sub_tree_root");
if(projectsToBeRecalculated.indexOf(subTreeRoot) == -1){
projectsToBeRecalculated.push(subTreeRoot);
}
}
}
});
projectsToBeRecalculated.forEach(function(projectId){
InterProjectEventManager.raiseFullRecalculateEvent(projectId);
});
this.deleteTasks(tasksToDelete);
this.deleteRelations(relationsToDelete);
this.recalculateProjects(projectsToRecalculate);
this.deleteNotifications(data.notificationFilter);
},
_taskShouldBeDeleted: function(taskId) {
var gr = new GlideRecord('planned_task');
if ( gr.get(taskId) ) {
if ( JSUtil.notNil(gr.getValue('orig_sys_id')) ) {
var rel = new GlideRecord('planned_task_rel_planned_task');
var qc = rel.addQuery('parent', taskId);
qc.addOrCondition('child', taskId);
rel.query();
return (rel.getRowCount() == 0);
}
}
return false;
},
deleteTasks: function(tasksToDelete) {
PPMDebug.log("Into InterProjectTaskDeletionHandler.deleteTasks -> " + tasksToDelete.join(","));
var uniqueTopTasks = [], arrayUtil = new ArrayUtil();
tasksToDelete.forEach(function(task) {
var gr = new GlideRecord('planned_task');
if ( gr.get(task) ) {
gr = new GlideRecord(gr.getValue('sys_class_name')); //set right class name, else workflow would fire on delete
gr.get(task);
if(JSUtil.notNil(gr.getValue("top_task"))) {
if(!arrayUtil.contains(uniqueTopTasks, gr.getValue("top_task")))
uniqueTopTasks.push(gr.getValue("top_task"));
}
gr.setWorkflow(false);
gr.deleteRecord();
}
});
PPMDebug.log("Into InterProjectTaskDeletionHandler.uniqueTopTasks -> " + uniqueTopTasks.join(","));
if(uniqueTopTasks.length > 0) {
uniqueTopTasks.forEach(function(topTaskId) {
this.api.validateWbs(topTaskId);
});
}
},
deleteRelations: function(relationsToDelete) {
PPMDebug.log("Into InterProjectTaskDeletionHandler.deleteRelations -> " + relationsToDelete.join(","));
relationsToDelete.forEach(function(relation) {
var gr = new GlideRecord('planned_task_rel_planned_task');
if(gr.get(relation)) {
// gr.setWorkflow(false); // if relation exists delete the relation
gr.deleteRecord();
}
});
},
deleteNotifications: function(filter) {
PPMDebug.log("Into InterProjectTaskDeletionHandler.deleteNotifications -> " + filter);
if ( JSUtil.notNil(filter) ) {
var gr = new GlideRecord('planned_task_notification');
gr.addEncodedQuery(filter);
gr.setWorkflow(false);
gr.deleteMultiple();
}
},
recalculateProjects :function(projectsToRecalculate) {
PPMDebug.log("Into InterProjectTaskDeletionHandler.recalculateProjects -> " + projectsToRecalculate.join(","));
var uniqueProjects = projectsToRecalculate.filter(function(item, pos) {
return projectsToRecalculate.indexOf(item) == pos;
});
uniqueProjects.forEach(function(projectId) {
this.api.validateWbs(projectId); // re-vaidate on the safer side
InterProjectEventManager.raiseFullRecalculateEvent(projectId);
});
},
type: 'InterProjectTaskDeletionHandler'
};
Sys ID
48adad319fd22200598a5bb0657fcf38