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 i18n = require('i18n'); // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true; }); const CircuitSchema = new Schema({ _id: { type: String, default: function () { return new ObjectID().toString() } }, idapp: { type: String, required: true, }, groupnameId: { type: String, }, name: { type: String, unique: true, }, path: { type: String, unique: true, }, subname: { type: String, }, idCity: [ { type: Number, }], pub_to_share: { type: Number, // PUB_TO_SHARE_ALL, PUB_TO_SHARE_ONLY_TABLE_FOLLOW }, visibility: [ { type: Number, }, ], longdescr: { type: String, }, regulation: { type: String, }, systemUserDescr: { type: String, }, systemUserId: { type: String, }, totCircolante: { type: Number, }, totTransato: { type: Number, }, nome_valuta: { type: String, maxlength: 20, }, symbol: { type: String, maxlength: 7, }, color: { type: String, }, abbrev: { type: String, maxlength: 7, }, compara_valuta: { type: Number, default: 1, }, compara_euro: { type: Number, default: 1, }, valuta_per_euro: { type: Number, default: 1, }, fido_scoperto_default: { type: Number, }, qta_max_default: { type: Number, }, data_costituz: { type: Date, }, deperimento: { type: Boolean, default: true, }, freq_deper: { // H, D, W, M, Y type: String, }, minuto_deper: { type: Number, }, ora_deper: { type: Number, }, giorno_deper: { type: Number, }, mese_deper: { type: Number, }, ultimo_deper: { type: Date, }, durata_deper: { type: Number, }, // ------------- createdBy: { type: String, }, date_created: { type: Date, }, date_updated: { type: Date, }, admins: [ { username: {type: String}, date: {type: Date}, }, ], photos: [ { imagefile: { type: String, }, alt: { type: String, }, description: { type: String, }, }], 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, }, }); CircuitSchema.pre('save', async function(next) { if (this.isNew) { this._id = new ObjectID().toString(); this.date_created = new Date(); } next(); }); CircuitSchema.statics.findAllIdApp = async function(idapp) { const Circuit = this; const myfind = {idapp, deleted: false}; const whatToShow = this.getWhatToShow(idapp, ''); return await Circuit.find(myfind, whatToShow, (err, arrrec) => { return arrrec; }); }; CircuitSchema.statics.getFieldsForSearch = function() { return [ {field: 'nome_circuito', type: tools.FieldType.string}, {field: 'sotto_nome', type: tools.FieldType.string}, {field: 'nome_valuta', type: tools.FieldType.string}, {field: 'descr', type: tools.FieldType.string}]; }; CircuitSchema.statics.executeQueryTable = function(idapp, params, user) { params.fieldsearch = this.getFieldsForSearch(); return tools.executeQueryTable(this, idapp, params, user); }; CircuitSchema.statics.getWhatToShow = function(idapp, username) { // FOR ME, PERMIT ALL return { _id: 1, groupnameId: 1, path: 1, name: 1, subname: 1, longdescr: 1, regulation: 1, totCircolante: 1, totTransato: 1, systemUserId: 1, createdBy: 1, date_created: 1, date_updated: 1, nome_valuta: 1, fido_scoperto_default: 1, qta_max_default: 1, symbol: 1, idCity: 1, pub_to_share: 1, visibility: 1, color: 1, abbrev: 1, data_costituz: 1, photos: 1, admins: 1, req_users: 1, refused_users: 1, 'mycities': 1, }; }; // Rimuovi dagli Admin del Circuito CircuitSchema.statics.removeAdminOfMyCircuit = async function(idapp, username, name) { return await Circuit.updateOne({idapp, name}, {$pull: {admins: {username: {$in: [username]}}}}); }; CircuitSchema.statics.getWhatToShow_Unknown = function(idapp, username) { return { groupnameId: 1, path: 1, name: 1, subname: 1, longdescr: 1, regulation: 1, systemUserId: 1, founderUserId: 1, nome_valuta: 1, totCircolante: 1, totTransato: 1, fido_scoperto_default: 1, qta_max_default: 1, symbol: 1, color: 1, idCity: 1, pub_to_share: 1, visibility: 1, abbrev: 1, data_costituz: 1, photos: 1, admins: 1, createdBy: 1, date_created: 1, date_updated: 1, req_users: 1, refused_users: 1, 'mycities': 1, }; }; CircuitSchema.statics.getCircuitsByUsername = async function(idapp, username, user) { try { const {User} = require('../models/user'); const {Account} = require('../models/account'); const whatToShow = this.getWhatToShow(idapp, username); const whatToShow_Unknown = this.getWhatToShow_Unknown(idapp, username); // const arrUsernameCircuits = await User.getUsernameCircuitsByUsername(idapp, username); // const arrUsernameReqCircuits = await MyCircuit.getUsernameReqCircuitsByCircuitname(idapp, username); const manage_mycircuits = await Circuit.find({ idapp, 'admins': { $elemMatch: {username: {$eq: username}}, }, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }).lean(); let listcircuits = await Circuit.find({ idapp, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }, whatToShow_Unknown).lean(); let asked_circuits = await Circuit.find({ idapp, 'req_users': { $elemMatch: {username: {$eq: username}}, }, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }, whatToShow_Unknown).lean(); let refused_circuits = await Circuit.find({ idapp, 'refused_users': { $elemMatch: {username: {$eq: username}}, }, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }, whatToShow_Unknown).lean(); return { listcircuits, asked_circuits, refused_circuits, manage_mycircuits, mycircuits: user.profile.mycircuits, }; } catch (e) { console.log('Error getCircuitsByUsername', e); } return { listUsersCircuit: [], listRequestUsersCircuit: [], listTrusted: [], asked_circuits: [], refused_circuits: [], }; }; CircuitSchema.statics.getInfoCircuitByName = async function(idapp, name) { const whatToShow = this.getWhatToShow(idapp, ''); const myfind = { idapp, name, }; try { return await Circuit.findOne(myfind, whatToShow).lean(); } catch (e) { return null; } }; CircuitSchema.statics.getCircuitByName = async function(idapp, name) { const myfind = { idapp, name, }; try { return await Circuit.findOne(myfind); } catch (e) { return null; } }; CircuitSchema.statics.getCircuitById = async function(circuitId) { const myfind = { _id: circuitId, }; try { return await Circuit.findOne(myfind); } catch (e) { return null; } }; CircuitSchema.statics.deleteCircuit = async function(idapp, usernameOrig, name) { console.log('Circuito ' + name + ' rimosso da ' + usernameOrig); return await Circuit.findOneAndRemove({idapp, name}); }; CircuitSchema.statics.getUserCircuits = async function(idapp, username) { try { let aggr1 = [ { $match: {idapp, username, $or: [ {deleted: {$exists: false}}, {deleted: {$exists: true, $eq: false}}], }, }, { $lookup: { from: 'circuits', localField: 'circuitId', foreignField: '_id', as: 'circuit', }, }, { '$replaceRoot': { 'newRoot': { '$mergeObjects': [ { '$arrayElemAt': [ '$circuit', 0, ], }, '$$ROOT', ], }, }, }, /* { $project: { "circuit.name": 1, }, }, */ ]; ris = await this.aggregate(aggr1); return ris; } catch (e) { console.error('e', e); } }; CircuitSchema.statics.getCircolanteSingolaTransaz = function(accountorigTable, accountdestTable) { let circolante = 0; if (accountdestTable.saldo > 0) circolante += accountdestTable.saldo; if (accountorigTable.saldo > 0) circolante += accountorigTable.saldo; return circolante; }; CircuitSchema.statics.sendCoins = async function(onlycheck, idapp, usernameOrig, extrarec) { const {Movement} = require('../models/movement'); const {Account} = require('../models/account'); let ris = { result: false, cansend: true, errormsg: '', rec: null, useraccounts: [], }; try { let circuittable = null; if (extrarec.circuitname) circuittable = await Circuit.getCircuitByName(idapp, extrarec.circuitname); if (extrarec.circuitId) circuittable = await Circuit.getCircuitById(idapp, extrarec.circuitId); if (circuittable) { const myqty = Math.abs(extrarec.qty); const accountdestTable = await Account.getAccountByUsernameAndCircuitId(idapp, extrarec.dest, { circuitId: circuittable._id }, true); const accountorigTable = await Account.getAccountByUsernameAndCircuitId(idapp, usernameOrig, { circuitId: circuittable._id }, true); const circolantePrec = this.getCircolanteSingolaTransaz(accountorigTable, accountdestTable); // Check if Sender has enough money if (accountorigTable.saldo - myqty < -accountorigTable.fidoConcesso) { ris.cansend = false; ris.errormsg = i18n.__('CIRCUIT_AMOUNT_EXCEED_FIDO', usernameOrig); } if (accountdestTable.saldo + myqty > accountorigTable.qta_maxConcessa) { ris.cansend = false; ris.errormsg = i18n.__('CIRCUIT_AMOUNT_EXCEED_QTAMAX', extrarec.dest); } if (!onlycheck) { // Add a Transaction ! if (ris.cansend) { ris.rec = await Movement.addMov(idapp, accountorigTable, accountdestTable, myqty, extrarec.causal); } if (ris.cansend && ris.rec) { const circolanteAtt = this.getCircolanteSingolaTransaz(accountorigTable, accountdestTable); // Somma di tutte le transazioni circuittable.totTransato += myqty; // circuittable.totCircolante = circuittable.totCircolante + (circolanteAtt - circolantePrec); circuittable.totCircolante = await Account.calcTotCircolante(idapp, circuittable._id); await circuittable.save(); ris.result = true; console.log('Inviate Monete da', usernameOrig, extrarec.dest, myqty, extrarec.causal); ris.useraccounts = await Account.getUserAccounts(idapp, usernameOrig); extrarec.saldoOrig = accountorigTable.saldo; extrarec.saldoDest = accountdestTable.saldo; } else { console.log('NON Inviate Monete da', usernameOrig, extrarec.dest, myqty, extrarec.causal); } } return ris; } } catch (e) { console.error('Err sendCoins', e); ris.result = false; return ris; } }; // Rimuovo la Richiesta del Circuito CircuitSchema.statics.removeReqCircuit = async function(idapp, username, name) { return await Circuit.updateOne({idapp, name}, {$pull: {req_users: {username: {$in: [username]}}}}); }; // Aggiungi agli utenti Rifiutati del Circuito CircuitSchema.statics.refuseReqCircuit = async function(idapp, username, name) { return await Circuit.updateOne({idapp, name}, { $push: { refused_users: { username, date: new Date(), }, }, }); }; const Circuit = mongoose.model('Circuit', CircuitSchema); module.exports = {Circuit};