var mongoose = require('mongoose'); const _ = require('lodash'); const tools = require('../tools/general'); var { Project } = require('./project'); mongoose.Promise = global.Promise; mongoose.level = "F"; // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true }); mongoose.set('debug', process.env.DEBUG); var TodoSchema = new mongoose.Schema({ userId: { type: String, }, pos: { type: Number, }, category: { type: String, }, descr: { type: String, }, priority: { type: Number, }, statustodo: { type: Number, default: 0 }, created_at: { type: Date }, modify_at: { type: Date }, start_date: { type: Date, }, completed_at: { type: Date }, expiring_at: { type: Date, }, enableExpiring: { type: Boolean, default: false }, id_prev: { type: String, }, progress: { type: Number, }, phase: { type: Number, }, assigned_to_userId: { type: String, }, hoursplanned: { type: Number, }, hoursworked: { type: Number, }, modified: { type: Boolean, }, }); TodoSchema.methods.toJSON = function () { var todo = this; var todoObject = todo.toObject(); // console.log(todoObject); return _.pick(todoObject, tools.allfieldTodoWithId()); }; TodoSchema.statics.findByUserIdAndIdParent = function (userId, category) { var Todo = this; if (userId === '') { return Todo.find({ 'category': category, }); } else { return Todo.find({ 'userId': userId, 'category': category, }); } }; TodoSchema.statics.findAllByUserIdAndCat = function (userId, category = '') { var Todo = this; if (category === '') { return Todo.find({ 'userId': userId, }).then(ris => { //return tools.mapSort(ris) return ris }) } else { return Todo.find({ 'userId': userId, 'category': category, }); } }; TodoSchema.statics.getArrIdParentInTable = function (userId) { var Todo = this; return Todo.find({ 'userId': userId }).distinct("category") .then(arrcategory => { return arrcategory }) }; TodoSchema.statics.getAllTodo = async function (userId) { var Todo = this; const arralltodo = await Todo.findAllByUserIdAndCat(userId); // console.log('arralltodo', arralltodo); let obj = []; obj.arrcategories = await Todo.getArrIdParentInTable(userId); const arrtodos = []; if (obj.arrcategories.length > 0) { for (let mycat in obj.arrcategories) { arrtodos.push(tools.mapSort(arralltodo.filter(item => item.category === obj.arrcategories[mycat]))) } } obj.arrtodos = arrtodos; // console.log('obj', obj); return obj; }; class CalcTodo { constructor() { this.mydata = { hoursworked: 0, hoursplanned: 0, progressCalc: 0, numitem: 0 } } addData(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++; } } 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 (userId, idproj, calcalsoUpper, masterproj, nocalcDown) { console.log('calculateTreeTodo', idproj); let objdata = new CalcTodo(); let promiseChain = Promise.resolve(); return await Project.findByUserIdAndIdParent(userId, idproj) .then(arrsubproj => { 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) .then((subobjdata) => { objdata.addData(subobjdata); }); }); } else { promiseChain = promiseChain.then(() => { objdata.addData(subproj); }); } } } return promiseChain; }) .then(() => { console.log('objdata', objdata); // 2) Calculate the Todos of this project return Todo.calculateTodoHoursAndProgress(userId, idproj); }) .then((objdatatodos) => { objdata.addData(objdatatodos); // End Calculate objdata.endDataCalc(); // Update into the DB: return Project.updateCalc(userId, idproj, objdata, null) .then(() => { return objdata.getData(); }); }) .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() }); } }); } else { return new Promise((resolve, reject) => { resolve() }); } }) }; TodoSchema.statics.calculateTodoHoursAndProgress = async function (userId, idproj) { var Todo = this; let objdata = new CalcTodo(); return await Todo.findByUserIdAndIdParent(userId, idproj) .then(arrtodo => { for (let itemtodo of arrtodo) { objdata.addData(itemtodo); } objdata.endDataCalc(); return objdata.getData(); }) .catch(e => { console.log('Error: ', e); return null; }); }; TodoSchema.pre('save', function (next) { // var todo = this; // console.log('todo.expiring_at', todo.expiring_at); next(); }); var Todo = mongoose.model('Todos', TodoSchema); module.exports = { Todo };