/* Account is a User's single Circuit */ const mongoose = require('mongoose').set('debug', false); const Schema = mongoose.Schema; mongoose.Promise = global.Promise; mongoose.level = 'F'; const tools = require('../tools/general'); const { ObjectID } = require('mongodb'); const shared_consts = require('../tools/shared_nodejs'); // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true; }); const AccountSchema = new Schema({ _id: { type: String, default: function () { return new ObjectID().toString(); }, }, idapp: { type: String, }, username: { type: String, }, groupname: { // For the Groups type: String, }, circuitId: { // ----- REF TO Circuit type: String, }, name: { type: String, }, deperibile: { type: Boolean, }, fidoConcesso: { type: Number, }, qta_maxConcessa: { type: Number, }, importo_iniziale: { type: Number, }, saldo: { type: Number, }, totTransato: { type: Number, }, regulation_ok: { type: Boolean, }, deleted: { type: Boolean, default: false, }, date_created: { type: Date, default: Date.now, }, date_updated: { type: Date, }, }); AccountSchema.statics.findAllIdApp = async function (idapp) { const Account = this; const myfind = { idapp, deleted: false }; return await Account.find(myfind, (err, arrrec) => { return arrrec; }); }; AccountSchema.pre('save', async function (next) { if (this.isNew) { this._id = new ObjectID().toString(); } next(); }); AccountSchema.statics.getFieldsForSearch = function () { return [ { field: 'name', type: tools.FieldType.string }, ]; }; AccountSchema.statics.executeQueryTable = function (idapp, params) { params.fieldsearch = this.getFieldsForSearch(); return tools.executeQueryTable(this, idapp, params); }; AccountSchema.statics.getAccountsByUsername = async function (idapp, username) { const Account = this; if (username === undefined) return false; const myquery = { 'idapp': idapp, 'username': username, }; return await Account.find(myquery).lean(); }; AccountSchema.statics.calcTotCircolante = async function (idapp, circuitId) { const Account = this; try { let aggr1 = [ { $match: { idapp, circuitId, saldo: { $gt: 0 } }, }, { $group: { _id: null, count: { $sum: '$saldo' } } } ]; ris = await Account.aggregate(aggr1); return ris ? ris[0].count : 0; } catch (e) { console.error('err', e); } }; AccountSchema.methods.addtoSaldoSave = async function (amount) { const account = this; if (account) { account.saldo = account.saldo + amount; if (!account.totTransato) { account.totTransato = 0; } account.totTransato += Math.abs(amount); account.date_updated = new Date(); return await account.save(); } return null; }; AccountSchema.statics.addtoSaldo = async function (myaccount, amount) { const Account = this; try { let myaccountupdate = {}; if (myaccount) { myaccount.saldo = myaccount.saldo + amount; if (!myaccount.totTransato) { myaccount.totTransato = 0; } myaccount.totTransato += Math.abs(amount); myaccount.date_updated = new Date(); myaccountupdate.saldo = myaccount.saldo; myaccountupdate.totTransato = myaccount.totTransato; myaccountupdate.date_updated = myaccount.date_updated; return await Account.updateOne({ _id: myaccount.id }, { $set: myaccountupdate }); } } catch (e) { console.error('error', e); } return null; }; AccountSchema.pre('save', async function (next) { if (this.isNew) { this.date_created = new Date(); } next(); }); AccountSchema.statics.getAccountByUsernameAndCircuitId = async function (idapp, username, circuitId, createifnotexist, groupname = '') { const Account = this; try { const { Circuit } = require('../models/circuit'); if (username === undefined) return false; let myquery = { idapp, circuitId, }; if (groupname) { myquery.groupname = groupname; } else { myquery.username = username; } let mycircuit = await Circuit.getCircuitById(circuitId); if (mycircuit) { let myaccount = await Account.findOne(myquery); if (!myaccount && createifnotexist) { myaccount = new Account({ _id: new ObjectID().toString(), idapp, username, groupname, circuitId: mycircuit._id, deperibile: false, importo_iniziale: 0, saldo: 0, fidoConcesso: 0, qta_maxConcessa: 0, }); if (!mycircuit.fido_scoperto_default_grp) mycircuit.fido_scoperto_default_grp = shared_consts.CIRCUIT_PARAMS.SCOPERTO_MIN_GRP; if (!mycircuit.qta_max_default_grp) mycircuit.qta_max_default_grp = shared_consts.CIRCUIT_PARAMS.SCOPERTO_MAX_GRP; if (groupname) { myaccount.fidoConcesso = mycircuit.fido_scoperto_default_grp; myaccount.qta_maxConcessa = mycircuit.qta_max_default_grp; } else { myaccount.fidoConcesso = mycircuit.fido_scoperto_default; myaccount.qta_maxConcessa = mycircuit.qta_max_default; } return await myaccount.save(); } return myaccount; } return null; } catch (e) { console.error('error', e); } }; AccountSchema.statics.createAccount = async function (idapp, username, circuitName, groupname = '') { const { Circuit } = require('../models/circuit'); try { mycircuit = await Circuit.findOne({ name: circuitName }, {_id: 1}); if (mycircuit) { return await Account.getAccountByUsernameAndCircuitId(idapp, username, mycircuit._id, true, groupname); } else { return null; } } catch (e) { console.error('error', e); return null; } }; AccountSchema.statics.getUserAccounts = async function (idapp, username) { try { let aggr1 = [ { $match: { idapp, username }, }, { $lookup: { from: 'circuits', localField: 'circuitId', foreignField: '_id', as: 'circuit', }, }, { $unwind: '$circuit' }, { $lookup: { from: 'sendnotifs', as: 'notifspending', let: { circuitname: '$circuit.name', username: '$username', idapp: '$idapp', typedir: shared_consts.TypeNotifs.TYPEDIR_CIRCUITS, typeid: shared_consts.TypeNotifs.ID_CIRCUIT_SENDCOINSREQ, }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$typedir', '$$typedir'] }, { $eq: ['$typeid', '$$typeid'] }, { $eq: ['$status', 0] }, { $eq: ['$sender', '$$username'] }, { $eq: ['$idapp', '$$idapp'] }, { $eq: ['$extrarec.circuitname', '$$circuitname'] }, ], }, }, }, ], }, }, ]; ris = await this.aggregate(aggr1); const { SendNotif } = require('../models/sendnotif'); if (ris) { for (const account of ris) { const pendingtransactions = await SendNotif.getSumPendingTransactions(idapp, username, account.circuit.name); const saldopending = pendingtransactions.reduce((sum, rec) => sum + rec.extrarec.qty, 0); account.saldo -= saldopending; } } return ris; } catch (e) { console.error('e', e); } }; AccountSchema.statics.getGroupAccounts = async function (idapp, groupname) { try { let aggr1 = [ { $match: { idapp, groupname }, }, { $lookup: { from: 'circuits', localField: 'circuitId', foreignField: '_id', as: 'circuit', }, }, { $unwind: '$circuit' }, { $lookup: { from: 'sendnotifs', as: 'notifspending', let: { circuitname: '$circuit.name', groupname: '$groupname', idapp: '$idapp', typedir: shared_consts.TypeNotifs.TYPEDIR_CIRCUITS, typeid: shared_consts.TypeNotifs.ID_CIRCUIT_SENDCOINSREQ, }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$typedir', '$$typedir'] }, { $eq: ['$typeid', '$$typeid'] }, { $eq: ['$status', 0] }, { $eq: ['$sender', '$$username'] }, { $eq: ['$idapp', '$$idapp'] }, { $eq: ['$extrarec.circuitname', '$$circuitname'] }, ], }, }, }, ], }, }, ]; ris = await this.aggregate(aggr1); const { SendNotif } = require('../models/sendnotif'); if (ris) { for (const account of ris) { const pendingtransactions = await SendNotif.getSumPendingTransactions(idapp, '', account.circuit.name, groupname); const saldopending = pendingtransactions.reduce((sum, rec) => sum + rec.extrarec.qty, 0); account.saldo -= saldopending; } } return ris; } catch (e) { console.error('e', e); } }; // Aggiungi agli Admin del Account AccountSchema.statics.addToPeopleOfMyAccount = async function (idapp, username, circuitId, person_username, perm) { return await Account.updateOne({ idapp, username, circuitId }, { $push: { people: { username: person_username, perm, date: new Date(), }, }, }); }; // Rimuovi dagli Admin del Account AccountSchema.statics.removeAdminOfAccount = async function (idapp, username, circuitId, person_username, perm) { return await Circuit.updateOne({ idapp, username, circuitId }, { $pull: { people: { username: { $in: [person_username] } } } }); }; const Account = mongoose.model('Account', AccountSchema); module.exports = { Account };