diff --git a/server/models/project.js b/server/models/project.js index 7ece811..4f0506a 100644 --- a/server/models/project.js +++ b/server/models/project.js @@ -27,14 +27,6 @@ var ProjectSchema = new mongoose.Schema({ longdescr: { type: String, }, - hoursplanned: { - type: Number, - default: 0 - }, - hoursworked: { - type: Number, - default: 0 - }, id_parent: { type: String, }, @@ -64,10 +56,6 @@ var ProjectSchema = new mongoose.Schema({ id_prev: { type: String, }, - progressCalc: { - type: Number, - default: 0 - }, modified: { type: Boolean, }, @@ -77,12 +65,39 @@ var ProjectSchema = new mongoose.Schema({ test_url: { type: String, }, + totalphases: { + type: Number, + default: 1 + }, + actualphase: { + type: Number, + default: 1 + }, + hoursplanned: { + type: Number, + default: 0 + }, + hoursworked: { + type: Number, + default: 0 + }, + progressCalc: { + type: Number, + default: 0 + }, begin_development: { type: Date, }, begin_test: { type: Date, }, + hoursweeky_plannedtowork: { + type: Number, + default: 0 + }, + endwork_estimate: { + type: Date + } }); @@ -176,7 +191,6 @@ ProjectSchema.statics.getAllProjects = async function (userId) { ProjectSchema.statics.updateCalc = async function (userId, idproj, objdatacalc, recIn) { - return new Promise((resolve, reject) => { if (!!recIn) { return resolve(recIn); @@ -185,21 +199,22 @@ ProjectSchema.statics.updateCalc = async function (userId, idproj, objdatacalc, } }).then((myproj) => { if (!!myproj) { - // console.log('myproj', myproj); + console.log('objdatacalc progressCalc', objdatacalc.mydata.progressCalc); objdatacalc.setValuesToRecord(myproj); - console.log('updateCalc', myproj._id, objdatacalc); + // console.log('updateCalc', myproj._id, myproj.progressCalc); - myproj.save() + return myproj.save() .then(() => { // console.log('salvato proj!'); + return true; }) .catch(err => { console.log("Error updateCalc", err.message); }); } - return true; + return false; }).catch(e => { console.log('Error: ', e); return false; diff --git a/server/models/todo.js b/server/models/todo.js index 5d2749d..f24dfd5 100644 --- a/server/models/todo.js +++ b/server/models/todo.js @@ -88,19 +88,23 @@ TodoSchema.methods.toJSON = function () { }; -TodoSchema.statics.findByUserIdAndIdParent = function (userId, category) { +TodoSchema.statics.findByUserIdAndIdParent = function (userId, category, phase = '') { var Todo = this; - if (userId === '') { - return Todo.find({ - 'category': category, - }); - } else { - return Todo.find({ - 'userId': userId, - 'category': category, - }); + let tofind = { + 'category': category, + }; + + if (userId !== '') { + tofind['userId'] = userId; } + + if (!!phase) { + tofind['phase'] = phase; + } + + return Todo.find(tofind); + }; TodoSchema.statics.findAllByUserIdAndCat = function (userId, category = '') { @@ -158,71 +162,102 @@ TodoSchema.statics.getAllTodo = async function (userId) { }; class CalcTodo { - constructor() { + constructor(phase) { + this.mydata = { - hoursworked: 0, - hoursplanned: 0, - progressCalc: 0, + phase: phase, numitem: 0 + }; + this.clean() + } + + clean() { + this.mydata.hoursplanned = 0; + this.mydata.hoursworked = 0; + this.mydata.progressCalc = 0; + } + + addDataProj(datain) { + if (!!datain) { + if (datain.actualphase === this.mydata.phase) { + CalcTodo.addFields(this.mydata, datain); + } } } - addData(datain) { + addDataTodo(datain) { if (!!datain) { - this.mydata.hoursworked += datain.hoursworked; - this.mydata.hoursplanned += datain.hoursplanned; - if (!!datain.progressCalc) - this.mydata.progressCalc += datain.progressCalc; - else if (!!datain.progress) - this.mydata.progressCalc += datain.progress; - - this.mydata.numitem++; + if (datain.phase === this.mydata.phase) { + CalcTodo.addFields(this.mydata, datain); + } } } + static addFields(recout, recin) { + // console.log('addFields', recin); + recout.hoursworked += recin.hoursworked; + recout.hoursplanned += recin.hoursplanned; + if (!!recin.progressCalc) + recout.progressCalc += recin.progressCalc; + else + recout.progressCalc += recin.progress; + + recout.numitem++; + } + + static copyFields(recout, recin) { + recout.hoursworked = recin.hoursworked; + recout.hoursplanned = recin.hoursplanned; + if (!!recin.progressCalc) + recout.progressCalc = recin.progressCalc; + else + recout.progressCalc = 0; + } + + setValuesToRecord(objout) { + CalcTodo.copyFields(objout, this.mydata) + } + endDataCalc() { if (this.mydata.numitem > 0) { this.mydata.progressCalc = Math.round(this.mydata.progressCalc / this.mydata.numitem); } } - setValuesToRecord(objout) { - objout.hoursworked = this.mydata.hoursworked; - objout.hoursplanned = this.mydata.hoursplanned; - objout.progressCalc = this.mydata.progressCalc; - } - getData() { // return tools.jsonCopy(this.mydata); return { ...this.mydata } } } +TodoSchema.statics.calculateTreeTodo = async function (actualphase, userId, idproj, calcalsoUpper, masterproj, nocalcDown) { + // console.log('calculateTreeTodo', 'actualphase', actualphase, idproj); -TodoSchema.statics.calculateTreeTodo = async function (userId, idproj, calcalsoUpper, masterproj, nocalcDown) { - console.log('calculateTreeTodo', idproj); + const myrecproj = await Project.findProjectByUserId(userId, idproj); + // const id_parent = await Project.getIdParentByIdProj(idproj); - let objdata = new CalcTodo(); + let objdata = new CalcTodo(actualphase); let promiseChain = Promise.resolve(); return await Project.findByUserIdAndIdParent(userId, idproj) .then(arrsubproj => { - console.log('arrsubproj', 'userId', userId, 'idproj', idproj, arrsubproj.length); + // console.log(' ', arrsubproj.length, 'SubProjects trovati'); + // console.log('arrsubproj', 'userId', userId, 'idproj', idproj, arrsubproj.length); if (!nocalcDown) { // 1) Calculate the SubProjects of this project Main for (const subproj of arrsubproj) { if (!calcalsoUpper) { // not include the first Project because it was already calculated before promiseChain = promiseChain.then(() => { - return Todo.calculateTreeTodo(userId, subproj._id, calcalsoUpper, masterproj, true) + return Todo.calculateTreeTodo(actualphase, userId, subproj._id, calcalsoUpper, masterproj, true) .then((subobjdata) => { - objdata.addData(subobjdata); + objdata.addDataProj(subobjdata); }); }); } else { promiseChain = promiseChain.then(() => { - objdata.addData(subproj); + objdata.addDataProj(subproj); }); } } @@ -231,39 +266,44 @@ TodoSchema.statics.calculateTreeTodo = async function (userId, idproj, calcalsoU return promiseChain; }) .then(() => { - console.log('objdata', objdata); + // console.log('objdata', objdata); // 2) Calculate the Todos of this project - return Todo.calculateTodoHoursAndProgress(userId, idproj); + return Todo.calculateTodoHoursAndProgress(userId, idproj, myrecproj.actualphase); }) .then((objdatatodos) => { - objdata.addData(objdatatodos); - // End Calculate - objdata.endDataCalc(); + if (myrecproj.actualphase === actualphase) { + // console.log('objdatatodos', objdatatodos); + objdata.addDataTodo(objdatatodos); - // Update into the DB: - return Project.updateCalc(userId, idproj, objdata, null) - .then(() => { - return objdata.getData(); - }); + // End Calculate + objdata.endDataCalc(); + + // Update into the DB: + return Project.updateCalc(userId, idproj, objdata, null) + .then((ris) => { + if (ris) + return objdata.getData(); + else + return null; + }); + } else { + return null; + } }) .then((ris) => { if (calcalsoUpper) { - return Project.getIdParentByIdProj(idproj) - .then(idparent => { - console.log('idparent', idparent); - if (!!idparent) { - // Calculate also the upper Projects ! - return new Promise((resolve, reject) => { - Todo.calculateTreeTodo(userId, idparent, true, masterproj, false); - resolve(ris) - }); - } else { - return new Promise((resolve, reject) => { - resolve() - }); - } + if (!!myrecproj.id_parent) { + // Calculate also the upper Projects ! + return new Promise((resolve, reject) => { + Todo.calculateTreeTodo(actualphase, userId, myrecproj.id_parent, true, masterproj, false); + resolve(ris) }); + } else { + return new Promise((resolve, reject) => { + resolve() + }); + } } else { return new Promise((resolve, reject) => { resolve() @@ -272,16 +312,16 @@ TodoSchema.statics.calculateTreeTodo = async function (userId, idproj, calcalsoU }) }; - -TodoSchema.statics.calculateTodoHoursAndProgress = async function (userId, idproj) { +TodoSchema.statics.calculateTodoHoursAndProgress = async function (userId, idproj, actualphase) { var Todo = this; - let objdata = new CalcTodo(); + let objdata = new CalcTodo(actualphase); - return await Todo.findByUserIdAndIdParent(userId, idproj) + return await Todo.findByUserIdAndIdParent(userId, idproj, actualphase) .then(arrtodo => { + // console.log(' calculateTodo *', arrtodo.length, '* FOUND'); for (let itemtodo of arrtodo) { - objdata.addData(itemtodo); + objdata.addDataTodo(itemtodo); } objdata.endDataCalc(); diff --git a/server/router/projects_router.js b/server/router/projects_router.js index 7cec53d..ac68b45 100644 --- a/server/router/projects_router.js +++ b/server/router/projects_router.js @@ -79,11 +79,12 @@ router.patch('/:id', authenticate, (req, res) => { Project.findByIdAndUpdate(id, { $set: body }, { new: true }).then((project) => { - tools.mylogshow(' PROJECT TO MODIFY: ', project.descr, body); + tools.mylogshow(' PROJECT TO MODIFY: ', project.descr); if (!project) { return res.status(404).send(); } + if (project.userId !== String(req.user._id)) { // I'm trying to write something not mine! return res.status(404).send({ code: server_constants.RIS_CODE_TODO_CREATING_NOTMYUSER }); @@ -91,9 +92,17 @@ router.patch('/:id', authenticate, (req, res) => { project.modified = false; - tools.mylog('PATCH ', project.descr, project._id); + // Recalculate + return calcSingleProject('', project) + .then(objout => { + tools.mylog('PATCH ', project.descr, project._id, project.progressCalc); + + return Project.findById(id).then((projectris) => { + // console.log('projectris progressCalc', projectris.progressCalc); + res.send({ projectris }); + }); + }); - res.send({ project }); }).catch((e) => { tools.mylogserr('Error patch PROJECT: ', e); res.status(400).send(); @@ -153,7 +162,7 @@ async function calcProjects(userId, obj) { promiseChain = promiseChain.then(() => { // Find the todos for this project // Calculate the Progression of the Project // sum the progression - return Todo.calculateTreeTodo(userId, rec._id, false, rec._id, false) + return Todo.calculateTreeTodo(userId, rec._id) }) } return promiseChain @@ -165,6 +174,13 @@ async function calcProjects(userId, obj) { } +// USATO SOLO LE PRIME VOLTE! O A RICHIESTA! +async function calcSingleProject(userId, myproj) { + + return await Todo.calculateTreeTodo(myproj.actualphase, userId, myproj._id, false, myproj._id, false) + +} + router.delete('/:id', authenticate, (req, res) => { var id = req.params.id; diff --git a/server/router/todos_router.js b/server/router/todos_router.js index c0c5bd3..9988af4 100644 --- a/server/router/todos_router.js +++ b/server/router/todos_router.js @@ -88,7 +88,7 @@ router.patch('/:id', authenticate, (req, res) => { } let level = 0; - return Todo.calculateTreeTodo(todo.userId, todo.category, true, todo.category, false) + return Todo.calculateTreeTodo(todo.phase, todo.userId, todo.category, true, todo.category, false) .then(objdatacalc => { tools.mylogshow(' TODO TO MODIFY: ', todo.descr, todo.expiring_at); diff --git a/server/tools/general.js b/server/tools/general.js index 1d482f8..84db08f 100644 --- a/server/tools/general.js +++ b/server/tools/general.js @@ -24,6 +24,10 @@ webpush.setVapidDetails(subject, publicVapidKey, privateVapidKey); module.exports = { + TYPE_PROJECT: 1, + TYPE_TODO: 2, + + MAX_PHASES: 5, FIRST_PROJ: '__PROJECTS', EXECUTE_CALCPROJ: true, getHostname: function () { @@ -62,7 +66,7 @@ module.exports = { // #TODO Projects++ Add fields ... allfieldProject: function () { return ['userId', 'pos', 'id_parent', 'descr', 'longdescr', 'hoursplanned', 'hoursworked', 'priority', 'statusproj', 'created_at', 'modify_at', - 'completed_at', 'expiring_at', 'enableExpiring', 'id_prev', 'progressCalc', 'modified', 'live_url', 'test_url', 'begin_development', 'begin_test'] + 'completed_at', 'expiring_at', 'enableExpiring', 'id_prev', 'progressCalc', 'modified', 'live_url', 'test_url', 'begin_development', 'begin_test', 'totalphases', 'actualphase', 'hoursweeky_plannedtowork', 'endwork_estimate'] }, allfieldProjectWithId: function () {