rays-javascript-extension/build/ryzproj.min.js

15 lines
4.7 KiB
JavaScript

/**
* Ray's Projects
* @version v0.1.0.104 (2023/12/27 1051)
*/
class RyzProject{constructor(b){this.Project=Object.assign(this.newProject,b);this.Tasks=[];this.initialiseComponents()}initialiseComponents(){}get NewTask(){return{ID:null,Name:"",Description:"",Tag:null,StartDelay:0,Duration:1,PredecessorTaskID:null,IsCollated:!1,CollatedTaskID:null,ActuWorkHours:null,Progress:0,Resources:[]}}get StartDate(){return new Date(this.Project.StartDate)}get FinishDate(){let b=new Date(this.Project.StartDate);this.ExportTasks().forEach(a=>{null!=a.FinishDate&&(b=Date.max(b,
a.FinishDate))});return b}get Duration(){return Date.diffDays(this.StartDate,this.FinishDate)}get newProject(){return{Name:"",Description:"",StartDate:Date.today(),Tag:null,StartOfWeek:1,WorkHours:[0,7.5,7.5,7.5,7.5,7.5,0]}}get newTaskNode(){return{Order:null,ID:null,Name:"",Description:"",Tag:null,StartDate:null,FinishDate:null,StartDelay:0,Duration:1,PredecessorTaskID:null,IsCollated:!1,CollatedTaskID:null,CalcWorkHours:0,ActuWorkHours:null,Progress:0,Resources:[],Level:0,PredecessorTaskNo:null,
Tasks:[]}}AddTask(b){b=Object.assign(this.NewTask,b);b=Object.assign(this.newTaskNode,b);if(null==b.PredecessorTaskID&&null==b.CollatedTaskID)this.Tasks.push(b);else if(null!=b.PredecessorTaskID){var a=this.FindTask(b.PredecessorTaskID);null!=a?a.Tasks.push(b):this.log("Task not found ("+b.PredecessorTaskID+")")}else null!=b.CollatedTaskID?(a=this.FindTask(b.CollatedTaskID),null!=a?a.Tasks.push(b):this.log("Task not found ("+b.CollatedTaskID+")")):this.log("Task not found ("+b.ID+")")}ClearTasks(){this.Tasks=
[]}ExportTasks(){let b=this.Tasks.copy().flatten("Tasks");for(var a=0;a<b.length;a++)b[a].Order=a+1,delete b[a].Tasks;return b}FindTask(b){let a=null;this.Tasks.forEachTree("Tasks",function(c){return c.ID==b?(a=c,!1):!0});return a}GetNodeType(b){return null==b?0:null==b.PredecessorTaskID&&null==b.CollatedTaskID&&0==b.IsCollated?1:null==b.PredecessorTaskID&&null==b.CollatedTaskID&&1==b.IsCollated?2:null!=b.PredecessorTaskID&&null==b.CollatedTaskID&&0==b.IsCollated?3:null!=b.PredecessorTaskID&&null==
b.CollatedTaskID&&1==b.IsCollated?4:null!=b.CollatedTaskID&&0==b.IsCollated?5:null!=b.CollatedTaskID&&1==b.IsCollated?6:0}Invalidate(){let b=!1;this.Recalculate()||(b=!1);return b}Recalculate(){let b=!1;this.Sort();let a=this.Tasks.flatten("Tasks");for(var c=0;c<a.length;c++)a[c].Order=c+1,a[c].StartDate=null,a[c].FinishDate=null,a[c].CalcWorkHours=null;for(var e=0;128>e;e++){if(0>=a.copy().countMany({propName:"StartDate",value:null},{propName:"FinishDate",value:null})){b=!0;break}this.log("Round "+
(e+1));for(c=0;c<a.length;c++)switch(this.GetNodeType(a[c])){case 1:a[c].StartDate=Date.addDays(this.Project.StartDate,a[c].StartDelay);a[c].FinishDate=Date.addDays(a[c].StartDate,a[c].Duration);break;case 2:a[c].StartDate=Date.addDays(this.Project.StartDate,a[c].StartDelay);a[c].Progress=0;this.recalculateCollatedTask(a,c);break;case 3:var d=a.first("ID",a[c].PredecessorTaskID);null!=d&&null!=d.FinishDate&&(a[c].StartDate=Date.addDays(d.FinishDate,a[c].StartDelay),a[c].FinishDate=Date.addDays(a[c].StartDate,
a[c].Duration));break;case 4:d=a.first("ID",a[c].PredecessorTaskID);null!=d&&null!=d.FinishDate&&(a[c].StartDate=Date.addDays(d.FinishDate,a[c].StartDelay),a[c].Progress=0,this.recalculateCollatedTask(a,c));break;case 5:d=a.first("ID",a[c].CollatedTaskID);null!=d&&null!=d.StartDate&&(a[c].StartDate=Date.addDays(d.StartDate,a[c].StartDelay),a[c].FinishDate=Date.addDays(a[c].StartDate,a[c].Duration),a[c].Level=d.Level+1);break;case 6:d=a.first("ID",a[c].CollatedTaskID),null!=d&&null!=d.StartDate&&(a[c].StartDate=
Date.addDays(d.StartDate,a[c].StartDelay),a[c].Progress=0,a[c].Level=d.Level+1,this.recalculateCollatedTask(a,c))}}this.recalculateWorkHours(a);this.recalculatePredecessorTaskNo(a);return b}Sort(){this.Tasks.sortTree("Tasks","StartDelay")}log(b){console.log(b)}recalculateWorkHours(b){for(var a=0;a<b.length;a++){if(null==b[a].StartDate)continue;if(null==b[a].FinishDate)continue;if(0>=b[a].Duration)continue;let c=0,e=new Date(b[a].StartDate);for(let d=0;d<b[a].Duration;d++){const f=e.getDay();c+=this.Project.WorkHours[f]}b[a].CalcWorkHours=
c}}recalculatePredecessorTaskNo(b){for(var a=0;a<b.length;a++){if(null==b[a].PredecessorTaskID)continue;const c=this.FindTask(b[a].PredecessorTaskID);null!=c&&(b[a].PredecessorTaskNo=c.Order)}}recalculateCollatedTask(b,a){let c=b.select("CollatedTaskID",b[a].ID);if(0>=c.length)return b[a].Duration=0,new Date(b[a].StartDate);if(c.any("FinishDate",null))return b[a].Duration=0,null;let e=new Date(b[a].StartDate);c.forEach(d=>{d.FinishDate>e&&(e=d.FinishDate)});b[a].Progress=Math.average(c.toList("Progress"));
b[a].FinishDate=new Date(e);b[a].Duration=Date.diffDays(b[a].StartDate,b[a].FinishDate)}};