const mongoose = require('mongoose').set('debug', false); const Schema = mongoose.Schema; const tools = require('../tools/general'); const shared_consts = require('../tools/shared_nodejs'); mongoose.Promise = global.Promise; mongoose.level = 'F'; const { ObjectID } = require('mongodb'); // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true; }); const MyGroupSchema = new Schema({ _id: { type: String, default: function () { return new ObjectID().toString(); }, }, idapp: { type: String, }, groupname: { type: String, }, title: { type: String, }, descr: { type: String, }, idCatGrp: { type: Number, }, userId: { type: String, }, photos: [ { imagefile: { type: String, }, alt: { type: String, }, description: { type: String, }, }], idCity: [ { type: Number, }], website: { type: String, }, link_telegram: { type: String, }, note: { type: String, default: '', }, //**ADDFIELD_MYGROUPS visibility: [ { type: Number, }, ], pwd_cryp: { type: String, }, createdBy: { type: String, }, admins: [ { username: { type: String }, perm: { type: Number }, date: { type: Date }, }, ], blocked: { type: Boolean, }, username_who_block: { type: String, }, date_created: { type: Date, }, date_updated: { type: Date, }, date_blocked: { type: Date, }, req_users: [ { _id: false, username: { type: String }, date: { type: Date }, }], // username refused_users: [ { _id: false, username: { type: String }, date: { type: Date }, }], // username deleted: { type: Boolean, default: false, }, mycircuits: [ { _id: false, circuitname: { type: String }, date: { type: Date }, }], lastdate_reqRisGroup: { type: Date, }, }); MyGroupSchema.statics.getFieldsForSearch = function () { return [{ field: 'descr', type: tools.FieldType.string }]; }; MyGroupSchema.statics.executeQueryTable = function (idapp, params, user) { params.fieldsearch = this.getFieldsForSearch(); const { User } = require('./user'); if (params.options) { if (tools.isBitActive(params.options, shared_consts.OPTIONS_SEARCH_USER_ONLY_FULL_WORDS)) { params.fieldsearch = User.getFieldsForSearchUserFriend(); } else if (tools.isBitActive(params.options, shared_consts.OPTIONS_SEARCH_USER_ALL_WORDS)) { params.fieldsearch = User.getFieldsForSearchUserFriend_AllWords(); } } return tools.executeQueryTable(this, idapp, params, user); }; MyGroupSchema.pre('save', async function (next) { if (this.isNew) { if (!this.date_created) this.date_created = new Date(); } next(); }); MyGroupSchema.statics.findAllIdApp = async function (idapp) { const myfind = { idapp }; return await MyGroup.find(myfind); }; MyGroupSchema.statics.findAllGroups = async function (idapp) { const whatToShow = this.getWhatToShow(idapp, ''); return await MyGroup.find({ idapp, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, whatToShow); }; // Rimuovo la Richiesta del Gruppo MyGroupSchema.statics.removeReqGroup = async function (idapp, username, groupnameDest) { return await MyGroup.updateOne({ idapp, groupname: groupnameDest }, { $pull: { req_users: { username: { $in: [username] } } } }); }; // Aggiungi agli utenti Rifiutati del Gruppo MyGroupSchema.statics.refuseReqGroup = async function (idapp, username, groupnameDest) { return await MyGroup.updateOne({ idapp, groupname: groupnameDest }, { $push: { refused_users: { username, date: new Date(), }, }, }); }; // Aggiungi agli Admin del Gruppo MyGroupSchema.statics.addToAdminOfMyGroup = async function (idapp, username, groupnameDest) { return await MyGroup.updateOne({ idapp, groupname: groupnameDest }, { $push: { admins: { username, date: new Date(), }, }, }); }; // Rimuovi dagli Admin del Gruppo MyGroupSchema.statics.removeAdminOfMyGroup = async function (idapp, username, groupnameDest) { return await MyGroup.updateOne({ idapp, groupname: groupnameDest }, { $pull: { admins: { username: { $in: [username] } } } }); }; MyGroupSchema.statics.getListAdminsByGroupName = async function (idapp, groupname) { let arr = await MyGroup.findOne({ idapp, groupname, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, { admins: 1 }).lean(); return arr && arr.admins ? arr.admins : []; }; MyGroupSchema.statics.getWhatToShow = function (idapp, username) { // FOR ME, PERMIT ALL return { groupname: 1, title: 1, descr: 1, visibility: 1, idCatGrp: 1, userId: 1, photos: 1, idCity: 1, website: 1, //**ADDFIELD_MYGROUPS link_telegram: 1, note: 1, admins: 1, blocked: 1, req_users: 1, refused_users: 1, createdBy: 1, date_created: 1, date_updated: 1, mycircuits: 1, lastdate_reqRisGroup: 1, }; }; MyGroupSchema.statics.getWhatToShow_Unknown = function (idapp, username) { return { groupname: 1, title: 1, descr: 1, photos: 1, visibility: 1, idCatGrp: 1, idCity: 1, note: 1, date_created: 1, date_updated: 1, mycircuits: 1, lastdate_reqRisGroup: 1, }; }; MyGroupSchema.statics.getArrUsernameFromFieldByGroupname = async function ( idapp, groupname, field) { const { User } = require('../models/user'); const myobj = {}; myobj[field + '.' + subfield] = 1; let arrrec = await User.findOne({ idapp, groupname, $or: [{ deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, myobj).then((ris) => ris ? ris._doc[field] : []); if (arrrec.length > 0) { return arrrec.map(m => m.username); } return []; }; MyGroupSchema.statics.getInfoGroupByGroupname = async function (idapp, groupname) { const whatToShow = this.getWhatToShow(idapp, groupname); const myfind = { idapp, groupname, }; const query = [ { $match: myfind }, { $lookup: { from: 'circuits', localField: 'mycircuits.circuitname', foreignField: 'name', as: 'mycircuits', }, }, { '$replaceRoot': { 'newRoot': { '$mergeObjects': [ { '$arrayElemAt': [ '$mycircuits', 0, ], }, '$$ROOT', ], }, }, }, { $project: whatToShow }, ]; try { const ris = await MyGroup.aggregate(query); if (ris && ris.length > 0) return ris[0]; } catch (e) { return null; } return null; }; MyGroupSchema.statics.deleteGroup = async function (idapp, usernameOrig, groupname) { console.log('Gruppo ' + groupname + ' rimosso da ' + usernameOrig); return await MyGroup.findOneAndRemove({ idapp, groupname }); }; MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req) { try { const { User } = require('../models/user'); const whatToShow = this.getWhatToShow(idapp, username); const whatToShow_Unknown = this.getWhatToShow_Unknown(idapp, username); const arrUsernameGroups = await User.getUsernameGroupsByUsername(idapp, username); // const arrUsernameReqGroups = await MyGroup.getUsernameReqGroupsByGroupname(idapp, username); let listUsersGroup = await User.find({ idapp, username: { $in: arrUsernameGroups }, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, whatToShow); let listgroups = await MyGroup.find({ idapp, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, whatToShow_Unknown); /*let listRequestUsersGroup = await User.find({ idapp, username: {$in: arrUsernameReqGroups}, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }, whatToShow_Unknown); */ let listSentRequestGroups = await MyGroup.find({ idapp, 'req_users': { $elemMatch: { username: { $eq: username } }, }, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, whatToShow_Unknown); let listRefusedGroups = await MyGroup.find({ idapp, 'refused_users': { $elemMatch: { username: { $eq: username } }, }, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, whatToShow_Unknown); return { listUsersGroup, listgroups, listSentRequestGroups, listRefusedGroups, mygroups: req.user.profile.mygroups, }; } catch (e) { console.log('Error', e); } return { listUsersGroup: [], listRequestUsersGroup: [], listTrusted: [], listSentRequestGroups: [], listRefusedGroups: [], }; }; MyGroupSchema.statics.extractCitiesName = async function (idapp, id) { try { let aggr1 = [ { $match: { idapp, _id: id }, }, { $lookup: { from: 'cities', localField: 'idCity', foreignField: '_id', as: 'mycities', }, }, { '$replaceRoot': { 'newRoot': { '$mergeObjects': [ { '$arrayElemAt': [ '$mycities', 0, ], }, '$$ROOT', ], }, }, }, { $project: { "mycities.comune": 1, "mycities.prov": 1 }, }, ]; ris = await this.aggregate(aggr1); return ris; } catch (e) { console.error('e', e); } }; MyGroupSchema.statics.ifCircuitAlreadyInGroup = async function (idapp, groupname, circuitname) { // Controllo se è stato già inserito il circuito sul gruppo return await this.findOne({ idapp, groupname, 'mycircuits': { $elemMatch: { circuitname: { $eq: circuitname } }, }, }).lean(); }; // aggiungo il Circuito all'interno del Gruppo MyGroupSchema.statics.addCircuitFromGroup = async function (idapp, groupname, circuitname) { return await this.updateOne({ idapp, groupname }, { $push: { 'mycircuits': { circuitname, date: new Date(), } } }); }; // Rimuovo il Circuito all'interno del Gruppo MyGroupSchema.statics.removeCircuitFromGroup = async function (idapp, groupname, circuitname) { const ris = await this.updateOne({ idapp, groupname }, { $pull: { 'mycircuits': { circuitname: { $in: [circuitname] } } } }); const circuitId = await Circuit.getCircuitIdByName(idapp, circuitname); let remove = false; // Se il mio account non è stato utilizzato, allora lo cancello anche questo const myaccount = await Account.getAccountByUsernameAndCircuitId(idapp, username, circuitId, false, false, groupname, ''); if (myaccount && myaccount.totTransato === 0) { remove = true; } else { remove = true; } if (remove) { await Account.removeAccount(myaccount._id); } }; MyGroupSchema.statics.getQueryReceiveRISGroups = function (idapp, hours) { const query = [ { $match: { idapp, 'lastdate_reqRisGroup': { $gte: tools.IncDateNow(-(1000 * 60 * 60 * hours)) }, $or: [ { deleted: { $exists: false } }, { deleted: { $exists: true, $eq: false } }], }, }, { $group: { _id: "$groupname", count: { $sum: 1, }, } }, { $sort: { 'lastdate_reqRisGroup': -1 } }, { $limit: 30 }, { $lookup: { from: "mygroups", let: { groupname: "$_id", idapp, }, pipeline: [ { $match: { $expr: { $and: [ { $eq: [ "$$groupname", "$groupname", ], }, { $eq: [ "$$idapp", "$idapp", ], }, ], }, }, }, ], as: "mygroup", }, }, { $unwind: "$mygroup" }, { $replaceRoot: { newRoot: { $mergeObjects: ["$mygroup", "$$ROOT"], }, }, }, { $project: { _id: 0, groupname: 1, title: 1, descr: 1, visibility: 1, idCatGrp: 1, userId: 1, photos: 1, idCity: 1, website: 1, link_telegram: 1, note: 1, admins: 1, blocked: 1, req_users: 1, createdBy: 1, date_created: 1, date_updated: 1, lastdate_reqRisGroup: 1, }, }, ]; return query; }; MyGroupSchema.statics.getReceiveRISGroups = async function (idapp) { return await this.aggregate(this.getQueryReceiveRISGroups(idapp, 8)).then(ris => { return ris; }); }; MyGroupSchema.statics.renameCircuitName = async function (idapp, oldcircuitname, newcircuitname) { return await this.updateMany({ idapp, 'mycircuits.circuitname': oldcircuitname }, { $set: { 'profile.mycircuits.$.circuitname': newcircuitname } }); }; MyGroupSchema.statics.setReceiveRisGroup = async function (idapp, groupname) { return await this.findOneAndUpdate({ idapp, groupname, }, { $set: { 'lastdate_reqRisGroup': new Date() } }, { new: false }).lean().then((record) => { return !!record; }); }; const MyGroup = mongoose.model('MyGroup', MyGroupSchema); MyGroup.createIndexes((err) => { if (err) throw err; }); module.exports = { MyGroup };