diff --git a/.directory b/.directory index adcb477..8e14767 100755 --- a/.directory +++ b/.directory @@ -1,6 +1,6 @@ [Dolphin] SortOrder=1 -SortRole=modificationtime -Timestamp=2020,2,18,17,19,21 +SortRole=size +Timestamp=2021,2,3,1,38,16 Version=4 ViewMode=1 diff --git a/src/server/classes/queryclass.js b/src/server/classes/queryclass.js index b0bb8e3..827b8d8 100755 --- a/src/server/classes/queryclass.js +++ b/src/server/classes/queryclass.js @@ -7,6 +7,11 @@ class CParamsQuery { this.filter = params.filter; this.sortBy = params.sortBy; this.descending = params.descending; + this.lk_tab = params.lk_tab; + this.lk_LF = params.lk_LF; + this.lk_FF = params.lk_FF; + this.lk_as = params.lk_as; + this.lk_proj = params.lk_proj; } } diff --git a/src/server/config/config.js b/src/server/config/config.js index 069a0d3..71324ca 100755 --- a/src/server/config/config.js +++ b/src/server/config/config.js @@ -164,6 +164,22 @@ if (process.env.NODE_ENV === 'production') { pathreg_add:'_cnm', abilitanave: false, }, + { + idapp: '11', + name: 'ArtEnergetica', + adminemail: '', + manageremail: '', + replyTo: '', + host: 'https://www.artenergetica.org', + portapp: '0', + dir: '', + email_from: 'info.pianetalibero@gmail.com', + email_pwd: '2df135e2b6c02b2c68ec6bf6b103751fcb4dfc48c57d0acb302482358ee8141fmaDuooPabDvlThiBI2XMyA==', + telegram_key:'', + telegram_bot_name: '', + pathreg_add:'', + abilitanave: false, + }, ]; } else if (process.env.NODE_ENV === 'test') { // ---------------- AMBIENTE DI TEST -------------------- @@ -307,7 +323,37 @@ if (process.env.NODE_ENV === 'production') { telegram_bot_name: '', pathreg_add:'_cnm', abilitanave: false, - } + }, + { + idapp: '3', + name: 'Brigitte MG Dumont', + adminemail: 'pao.loarena77@gmail.com', + manageremail: '', + host: 'http://test.brigittemgdumont.com', + portapp: '0', + dir: '', + email_from: 'info.pianetalibero@gmail.com', + email_pwd: '2df135e2b6c02b2c68ec6bf6b103751fcb4dfc48c57d0acb302482358ee8141fmaDuooPabDvlThiBI2XMyA==', + telegram_key:'', + telegram_bot_name: '', + pathreg_add:'', + abilitanave: false, + }, + { + idapp: '11', + name: 'ArtEnergetica', + adminemail: '', + manageremail: '', + host: 'https://www.artenergetica.org', + portapp: '0', + dir: '/var/www/artenergetica.org', + email_from: 'info.pianetalibero@gmail.com', + email_pwd: '2df135e2b6c02b2c68ec6bf6b103751fcb4dfc48c57d0acb302482358ee8141fmaDuooPabDvlThiBI2XMyA==', + telegram_key:'', + telegram_bot_name: '', + pathreg_add:'', + abilitanave: false, + }, ]; } else { // ---------------- AMBIENTE IN L O C A L E -------------------- @@ -450,7 +496,20 @@ if (process.env.NODE_ENV === 'production') { telegram_bot_name: '', pathreg_add:'_cnm', abilitanave: false, - } + }, + { + idapp: '11', + name: 'ArtEnergetica', + adminemail: 'paolo.arena77@gmail.com', + manageremail: '', + host: 'http://localhost', + portapp: '8091', + dir: '', + email_from: 'info.pianetalibero@gmail.com', + email_pwd: '66ffeb915e71fada64ad5c26947dd087c262be3b343734a0447c6dee534b888aZcfbjXEuMBWKxvbh60cniw==', + pathreg_add:'', + abilitanave: false, + }, ]; } diff --git a/src/server/models/department.js b/src/server/models/department.js index 055476c..4ccdb4e 100755 --- a/src/server/models/department.js +++ b/src/server/models/department.js @@ -1,4 +1,4 @@ -mongoose = require('mongoose'); +const mongoose = require('mongoose'); const Schema = mongoose.Schema; const tools = require('../tools/general'); diff --git a/src/server/models/hours.js b/src/server/models/hours.js new file mode 100755 index 0000000..d4a7474 --- /dev/null +++ b/src/server/models/hours.js @@ -0,0 +1,98 @@ +const mongoose = require('mongoose'); +const Schema = mongoose.Schema; + +const tools = require('../tools/general'); + +mongoose.Promise = global.Promise; +mongoose.level = "F"; + + +// Resolving error Unknown modifier: $pushAll +mongoose.plugin(schema => { + schema.options.usePushEach = true +}); + +const HoursSchema = new Schema({ + idapp: { + type: String, + }, + userId: { type: Schema.Types.ObjectId, ref: 'User' }, + descr: { + type: String, + }, + todoId: { + type: String, + }, + date: { + type: Date, + default: Date.now + }, + time_start: { + type: Number, + }, + time_end: { + type: Number, + }, + hours: { + type: Number, + }, +}); + +var Hours = module.exports = mongoose.model('Hours', HoursSchema); + +module.exports.getFieldsForSearch = function () { + return [{ field: 'descr', type: tools.FieldType.string }] +}; + +module.exports.executeQueryTable = function (idapp, params) { + params.fieldsearch = this.getFieldsForSearch(); + return tools.executeQueryTable(this, idapp, params); +}; + +module.exports.findAllIdApp = async function (idapp) { + const myfind = { idapp }; + + return await Hours.find(myfind); +}; + +module.exports.calculateHoursTodo = async function (idtodo) { + const Hours = this; + + if (idtodo) { + const myfind = [ + { + $match: { todoId: idtodo } + }, + { + $group: + { + _id: "$todoId", + + totalAmount: { + $sum: "$hours" + }, + count: { + $sum: 1 + } + } + } + ]; + + try { + const ris = await Hours.aggregate(myfind); + if (ris.length > 0) { + return ris[0].totalAmount; + } else { + return 0; + } + } catch (e) { + console.log('e', e); + return 0; + } + } else { + return 0; + } + +} +; + diff --git a/src/server/models/todo.js b/src/server/models/todo.js index ee954ca..45924e6 100755 --- a/src/server/models/todo.js +++ b/src/server/models/todo.js @@ -2,9 +2,11 @@ var mongoose = require('mongoose'); const _ = require('lodash'); +const { ObjectID } = require('mongodb'); const tools = require('../tools/general'); var { Project } = require('./project'); +const Hours = require('./hours'); var server_constants = require('../tools/server_constants'); @@ -98,12 +100,14 @@ TodoSchema.methods.toJSON = function () { return _.pick(todoObject, tools.allfieldTodoWithId()); }; - TodoSchema.statics.findByUserIdAndIdParent = function (userId, category, phase = '') { var Todo = this; let tofind = { - 'category': category, + category: ObjectID(category), + $or: + [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }] + }; if (userId !== '') { @@ -293,6 +297,7 @@ class CalcTodo { constructor(phase) { this.mydata = { + _id: '', phase: phase, numitem: 0 }; @@ -306,17 +311,21 @@ class CalcTodo { this.mydata.progressCalc = 0; } - addDataProj(datain) { + async addDataProj(datain) { if (!!datain) { if (datain.actualphase === this.mydata.phase) { + if (datain._id) + datain.hoursworked = await Hours.calculateHoursTodo(datain._id.toString()); CalcTodo.addFields(this.mydata, datain, true); } } } - addDataTodo(datain) { + async addDataTodo(datain) { if (!!datain) { if (datain.phase === this.mydata.phase) { + if (datain._id) + datain.hoursworked = await Hours.calculateHoursTodo(datain._id.toString()); CalcTodo.addFields(this.mydata, datain, false); } } @@ -324,6 +333,7 @@ class CalcTodo { static addFields(recout, recin, isproj) { // console.log('addFields', recin); + recout.hoursworked += recin.hoursworked; recout.hoursplanned += recin.hoursplanned; let hoursleft = (recin.hoursplanned - recin.hoursworked); @@ -351,7 +361,6 @@ class CalcTodo { else recout.progressCalc = 0; } - } setValuesToRecord(objout) { @@ -393,12 +402,12 @@ TodoSchema.statics.calculateTreeTodo = async function (actualphase, userId, idpr promiseChain = promiseChain.then(() => { return Todo.calculateTreeTodo(actualphase, userId, subproj._id, calcalsoUpper, masterproj, true) .then((subobjdata) => { - objdata.addDataProj(subobjdata); + return objdata.addDataProj(subobjdata); }); }); } else { promiseChain = promiseChain.then(() => { - objdata.addDataProj(subproj); + return objdata.addDataProj(subproj); }); } } @@ -420,19 +429,19 @@ TodoSchema.statics.calculateTreeTodo = async function (actualphase, userId, idpr if (!!myrecproj) { if (myrecproj.actualphase === actualphase) { // console.log('objdatatodos', objdatatodos); - objdata.addDataTodo(objdatatodos); + return objdata.addDataTodo(objdatatodos) + .then(() => { + // End Calculate + objdata.endDataCalc(); - // 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; + // Update into the DB: + return Project.updateCalc(userId, idproj, objdata, null) + .then((ris) => (ris) ? objdata.getData() : null); }); + + } else { + return Project.updateCalc(userId, idproj, objdata, null) + .then((ris) => (ris) ? objdata.getData() : null); } } } @@ -449,15 +458,17 @@ TodoSchema.statics.calculateTreeTodo = async function (actualphase, userId, idpr }); } else { return new Promise((resolve, reject) => { - resolve() + resolve(ris) }); } } } return new Promise((resolve, reject) => { - resolve() + resolve(ris) }); + }).catch((e) => { + console.log('error', e.message) }) }; @@ -469,9 +480,16 @@ TodoSchema.statics.calculateTodoHoursAndProgress = async function (userId, idpro return await Todo.findByUserIdAndIdParent(userId, idproj, actualphase) .then(arrtodo => { // console.log(' calculateTodo *', arrtodo.length, '* FOUND'); - for (let itemtodo of arrtodo) { - objdata.addDataTodo(itemtodo); + + let promiseChain = Promise.resolve(); + + for (const itemtodo of arrtodo) { + promiseChain = promiseChain.then(() => { + return objdata.addDataTodo(itemtodo); + }) } + return promiseChain; + }).then(() => { objdata.endDataCalc(); @@ -485,6 +503,7 @@ TodoSchema.statics.calculateTodoHoursAndProgress = async function (userId, idpro }; + TodoSchema.pre('save', function (next) { // var todo = this; diff --git a/src/server/models/user.js b/src/server/models/user.js index c6be7b3..46d47e7 100755 --- a/src/server/models/user.js +++ b/src/server/models/user.js @@ -221,6 +221,12 @@ const UserSchema = new mongoose.Schema({ manage_telegram: { type: Boolean }, + resplist: { + type: Boolean + }, + workerslist: { + type: Boolean + }, dateofbirth: { type: Date, }, @@ -1263,6 +1269,28 @@ UserSchema.statics.getusersManagers = async function (idapp) { }); }; +UserSchema.statics.getusersRespList = async function (idapp) { + const User = this; + + return await User.find({ idapp, 'profile.resplist': true }, { _id:1, username: 1, name: 1, surname: 1 }) + .then((arrrec) => { + return (!!arrrec) ? arrrec : null; + }).catch((e) => { + console.error('getusersRespList', e); + }); +}; + +UserSchema.statics.getusersWorkersList = async function (idapp) { + const User = this; + + return await User.find({ idapp, 'profile.workerslist': true }, { _id:1, username: 1, name: 1, surname: 1 }) + .then((arrrec) => { + return (!!arrrec) ? arrrec : null; + }).catch((e) => { + console.error('getusersWorkersList', e); + }); +}; + UserSchema.statics.getusersManagersAndZoomeri = async function (idapp) { const User = this; diff --git a/src/server/router/index_router.js b/src/server/router/index_router.js index 3acdc13..77b82b4 100755 --- a/src/server/router/index_router.js +++ b/src/server/router/index_router.js @@ -59,6 +59,8 @@ const Storehouse = require('../models/storehouse'); const Department = require('../models/department'); const ShareWithUs = require('../models/sharewithus'); const Group = require('../models/group'); +const { Todo } = require('../models/todo'); +const Hours = require('../models/hours'); const Order = require('../models/order'); const tools = require('../tools/general'); @@ -210,6 +212,10 @@ function getTableByTableName(tablename) { mytable = ShareWithUs; else if (tablename === 'groups') mytable = Group; + else if (tablename === 'todos') + mytable = Todo; + else if (tablename === 'hours') + mytable = Hours; else if (tablename === 'orders') mytable = Order; else if (tablename === 'producers') @@ -285,6 +291,7 @@ router.post('/settable', authenticate, (req, res) => { let mytablerec = new mytable(mydata); console.log('mytablerec', mytablerec); + const mytablestrutt = getTableByTableName(params.table); return mytablerec.save() .then(rec => { @@ -293,7 +300,16 @@ router.post('/settable', authenticate, (req, res) => { }).catch((e) => { console.log(e.message); - res.status(400).send(e); + if (e.code === 11000) { + const id = mytablerec._id; + delete mytablerec._doc['_id']; + return mytablestrutt.findByIdAndUpdate(id, { $set: mytablerec._doc }).then(async (rec) => { + return res.send(rec); + }).catch((e) => { + tools.mylog('error: ', e.message); + return res.status(400).send(e); + }) + } }); }); @@ -1120,6 +1136,8 @@ router.get('/loadsite/:userId/:idapp/:sall', authenticate_noerror, (req, res) => let gallery = Gallery.findAllIdApp(idapp); let producers = Producer.findAllIdApp(idapp); let groups = Group.findAllIdApp(idapp); + let resps = User.getusersRespList(idapp); + let workers = User.getusersWorkersList(idapp); let storehouses = Storehouse.findAllIdApp(idapp); let departments = Department.findAllIdApp(idapp); let cart = null; @@ -1136,7 +1154,7 @@ router.get('/loadsite/:userId/:idapp/:sall', authenticate_noerror, (req, res) => } - return Promise.all([bookedevent, eventlist, operators, wheres, contribtype, settings, permissions, disciplines, newstosent, mailinglist, mypage, gallery, paymenttype, calcstat, calzoom, producers, cart, storehouses, departments, orderscart, groups]) + return Promise.all([bookedevent, eventlist, operators, wheres, contribtype, settings, permissions, disciplines, newstosent, mailinglist, mypage, gallery, paymenttype, calcstat, calzoom, producers, cart, storehouses, departments, orderscart, groups, resps, workers]) .then((arrdata) => { // console.table(arrdata); const myuser = req.user; @@ -1166,6 +1184,8 @@ router.get('/loadsite/:userId/:idapp/:sall', authenticate_noerror, (req, res) => departments: arrdata[18], orders: arrdata[19], groups: arrdata[20], + resps: arrdata[21], + workers: arrdata[22], myuser, }); }) diff --git a/src/server/router/projects_router.js b/src/server/router/projects_router.js index 068b7e3..b220ec4 100755 --- a/src/server/router/projects_router.js +++ b/src/server/router/projects_router.js @@ -139,6 +139,24 @@ router.get('/', (req, res) => { }); }); +router.get('/calc/:id/:actualphase', authenticate, (req, res) => { + var id = req.params.id; + var actualphase = parseInt(req.params.actualphase); + + let rec = {}; + + return Todo.calculateTreeTodo(actualphase, '', id, false, id, false) + .then((rec) => { + return res.send({ rec }); + }) + .catch((err) => { + res.status(400).send(); + }); + +}) +; + + router.get('/:userId', authenticate, (req, res) => { const userId = req.params.userId; const idapp = req.query.idapp; @@ -173,7 +191,6 @@ router.get('/:userId', authenticate, (req, res) => { }); - // USATO SOLO LE PRIME VOLTE! O A RICHIESTA! async function calcProjects(userId, obj) { diff --git a/src/server/router/todos_router.js b/src/server/router/todos_router.js index 4b97bed..432eb3f 100755 --- a/src/server/router/todos_router.js +++ b/src/server/router/todos_router.js @@ -14,6 +14,8 @@ const Subscription = mongoose.model('subscribers'); var { Todo } = require('../models/todo'); +const Hours = require('../models/hours'); + const _ = require('lodash'); const { ObjectID } = require('mongodb'); @@ -79,7 +81,6 @@ router.patch('/:id', authenticate, (req, res) => { return res.status(404).send(); } - Todo.findByIdAndUpdate(id, { $set: body }, { new: true }) .then((todo) => { if (!todo) { @@ -111,6 +112,22 @@ router.patch('/:id', authenticate, (req, res) => { }); +router.get('/calc/:id', authenticate, (req, res) => { + var id = req.params.id; + + let rec = {}; + + Hours.calculateHoursTodo(id).then((hoursworked) => { + rec.hoursworked = hoursworked; + return res.send({ rec }); + }).catch((err) => { + res.status(400).send(); + }); + + return rec; + +}); + router.get('/:userId', authenticate, (req, res) => { var userId = req.params.userId; // var category = req.params.category; @@ -166,7 +183,7 @@ router.get('/test', (req, res) => { }); - res.send({ }); + res.send({}); }); diff --git a/src/server/tools/general.js b/src/server/tools/general.js index eab12d8..83c8549 100755 --- a/src/server/tools/general.js +++ b/src/server/tools/general.js @@ -597,7 +597,7 @@ module.exports = { allfieldTodo: function () { return ['userId', 'pos', 'category', 'descr', 'priority', 'statustodo', 'assignedToUsers', 'created_at', 'groupId', 'modify_at', - 'completed_at', 'expiring_at', 'enableExpiring', 'progress', 'modified', 'phase', 'assigned_to_userId', 'hoursplanned', 'hoursworked', 'start_date', 'themecolor', 'themebgcolor'] + 'completed_at', 'expiring_at', 'enableExpiring', 'progress', 'modified', 'phase', 'assigned_to_userId', 'assignedToUsers', 'hoursplanned', 'hoursworked', 'start_date', 'themecolor', 'themebgcolor'] }, allfieldMyEvent: function () { @@ -1039,6 +1039,26 @@ module.exports = { filtriadded.push({ $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }] }); + + // Hours + if (params.filterand.includes(shared_consts.FILTER_HOURS_ALL)) + filtriadded.push( + { + idapp, + todoId: params.codeId, + $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }] + } + ); + else if (params.filterand.includes(shared_consts.FILTER_HOURS_MYLIST)) + filtriadded.push( + { + idapp, + userId: ObjectID(params.userId), + todoId: params.codeId, + $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }] + } + ); + if (params.filterand.includes(shared_consts.FILTER_NASCOSTI)) filtriadded.push({ deleted: { $exists: true, $eq: true } @@ -1074,6 +1094,23 @@ module.exports = { if (numrowend < 0) numrowend = 1; + if (params.lk_tab) { + query.push( + { + $lookup: { + from: params.lk_tab, + localField: params.lk_LF, // field in my collection + foreignField: params.lk_FF, // field in the 'from' collection + as: params.lk_as + } + }, + { + $replaceRoot: { newRoot: { $mergeObjects: [{ $arrayElemAt: ['$' + params.lk_as, 0] }, "$$ROOT"] } } + }, + { $project: params.lk_proj } + ); + } + query.push( { $group: { diff --git a/src/server/tools/shared_nodejs.js b/src/server/tools/shared_nodejs.js index 21ce5d6..fbe7a4b 100755 --- a/src/server/tools/shared_nodejs.js +++ b/src/server/tools/shared_nodejs.js @@ -23,6 +23,8 @@ module.exports = { FILTER_NAVI_NON_PRESENTI: 8192, FILTER_QUALIFIED: 16384, FILTER_ASK_ZOOM_VISTO: 32768, + FILTER_HOURS_MYLIST: 65536, + FILTER_HOURS_ALL: 131072, Permissions: { Admin: 1,