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 { Account } = require('../models/account'); // Resolving error Unknown modifier: $pushAll mongoose.plugin(schema => { schema.options.usePushEach = true; }); const MovementSchema = new Schema({ _id: { type: String, default: function () { return new ObjectID().toString(); }, }, idapp: { type: String, }, notifId: { type: String, }, transactionDate: { type: Date, }, accountFromId: { type: String, }, accountToId: { type: String, }, idOrdersCart: { type: Schema.Types.ObjectId, ref: 'OrdersCart' }, causal_table: { type: String, }, causal_IdRec: { type: String, }, amount: { type: Number, }, causal: { type: String, default: '', }, residual: { type: Number, default: 0, }, expiringDate: { type: Date, }, confirmed: { type: Boolean, default: false, }, }); MovementSchema.statics.findAllIdApp = async function (idapp) { const MyMovement = this; const myfind = { idapp }; return await MyMovement.find(myfind, (err, arrrec) => { return arrrec; }); }; MovementSchema.pre('save', async function (next) { if (this.isNew) { this.transactionDate = new Date(); } next(); }); MovementSchema.statics.getFieldsForSearch = function () { return [ { field: 'causal', type: tools.FieldType.string }, { field: 'amount', type: tools.FieldType.number }, ]; }; MovementSchema.statics.executeQueryTable = function (idapp, params) { params.fieldsearch = this.getFieldsForSearch(); return tools.executeQueryTable(this, 0, params); }; MovementSchema.statics.addMov = async function (idapp, accountFromIdTable, accountToIdTable, amount, causal, notifId, idOrdersCart) { try { // Only positive values amount = Math.abs(amount); let mymov = await Movement.create( { idapp, transactionDate: new Date(), accountFromId: accountFromIdTable._id, accountToId: accountToIdTable._id, idOrdersCart, amount, causal, residual: 0, notifId, // expiringDate: }, ); if (mymov) { // Update saldo dell'Account await Account.addtoSaldo(accountToIdTable, amount, true); await Account.addtoSaldo(accountFromIdTable, -amount, false); return mymov; } } catch (e) { console.error('Error in addMov', e.message); } }; MovementSchema.statics.getQueryMovsByCircuitId = async function (idapp, username, groupname, contocom, circuitId) { try { if (!circuitId) { return []; } const myaccount = await Account.getAccountByUsernameAndCircuitId(idapp, username, circuitId, false, true, groupname, contocom); if (myaccount) { let aggr1 = [ { $match: { idapp, $or: [ { accountFromId: myaccount._id }, { accountToId: myaccount._id }], }, }, { $lookup: { from: 'accounts', localField: 'accountFromId', foreignField: '_id', as: 'accfrom', }, }, { $unwind: '$accfrom' }, { $lookup: { from: 'users', let: { username: '$accfrom.username', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$username', '$username'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'userfrom', }, }, { $unwind: { path: '$userfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'mygroups', let: { groupname: '$accfrom.groupname', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$groupname', '$groupname'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'groupfrom', }, }, { $unwind: { path: '$groupfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'circuits', let: { contocom: '$accfrom.contocom', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$contocom', '$path'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'contocomfrom', }, }, { $unwind: { path: '$contocomfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'accounts', localField: 'accountToId', foreignField: '_id', as: 'accto', }, }, { $unwind: '$accto' }, { $lookup: { from: 'circuits', localField: 'accfrom.circuitId', foreignField: '_id', as: 'circuitfrom', }, }, { $unwind: '$circuitfrom', }, { $lookup: { from: 'circuits', localField: 'accto.circuitId', foreignField: '_id', as: 'circuitto', }, }, { $unwind: '$circuitto', }, { $lookup: { from: 'users', let: { username: '$accto.username', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$username', '$username'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'userto', }, }, { $unwind: { path: '$userto', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'mygroups', let: { groupname: '$accto.groupname', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$groupname', '$groupname'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'groupto', }, }, { $unwind: { path: '$groupto', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'circuits', let: { contocom: '$accto.contocom', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$contocom', '$path'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'contocomto', }, }, { $unwind: { path: '$contocomto', preserveNullAndEmptyArrays: true, }, }, { $project: { transactionDate: 1, amount: 1, causal: 1, notifId: 1, 'circuitfrom.symbol': 1, 'circuitto.symbol': 1, 'userfrom.username': 1, 'userfrom.profile.img': 1, 'userto.username': 1, 'userto.profile.img': 1, 'groupfrom.groupname': 1, 'groupfrom.title': 1, 'groupfrom.photos': 1, 'groupto.groupname': 1, 'groupto.title': 1, 'groupto.photos': 1, 'contocomfrom.path': 1, 'contocomfrom.name': 1, 'contocomto.path': 1, 'contocomto.name': 1, }, }, ]; return aggr1; } } catch (e) { return []; } return []; }; MovementSchema.statics.getQueryAllUsersMovsByCircuitId = async function (idapp, circuitId) { try { if (!circuitId) { return []; } let aggr1 = [ { $match: { idapp, }, }, { $lookup: { from: 'accounts', localField: 'accountFromId', foreignField: '_id', as: 'accfrom', }, }, { $unwind: '$accfrom' }, { $lookup: { from: 'users', let: { username: '$accfrom.username', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$username', '$username'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'userfrom', }, }, { $unwind: { path: '$userfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'mygroups', let: { groupname: '$accfrom.groupname', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$groupname', '$groupname'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'groupfrom', }, }, { $unwind: { path: '$groupfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'circuits', let: { contocom: '$accfrom.contocom', idapp: '$accfrom.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$contocom', '$path'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'contocomfrom', }, }, { $unwind: { path: '$contocomfrom', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'accounts', localField: 'accountToId', foreignField: '_id', as: 'accto', }, }, { $unwind: { path: '$accto', preserveNullAndEmptyArrays: true, }, }, { $match: { 'accto.circuitId': circuitId }, }, { '$lookup': { 'from': 'circuits', 'localField': 'accfrom.circuitId', 'foreignField': '_id', 'as': 'circuitfrom', }, }, { $unwind: { path: '$circuitfrom', preserveNullAndEmptyArrays: true, }, }, { '$lookup': { 'from': 'circuits', 'localField': 'accto.circuitId', 'foreignField': '_id', 'as': 'circuitto', }, }, { $unwind: { path: '$circuitto', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'users', let: { username: '$accto.username', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$username', '$username'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'userto', }, }, { $unwind: { path: '$userto', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'mygroups', let: { groupname: '$accto.groupname', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$groupname', '$groupname'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'groupto', }, }, { $unwind: { path: '$groupto', preserveNullAndEmptyArrays: true, }, }, { $lookup: { from: 'circuits', let: { contocom: '$accto.contocom', idapp: '$accto.idapp' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$$contocom', '$path'] }, { $eq: ['$$idapp', '$idapp'] }, ], }, }, }, ], as: 'contocomto', }, }, { $unwind: { path: '$contocomto', preserveNullAndEmptyArrays: true, }, }, { $project: { transactionDate: 1, amount: 1, causal: 1, notifId: 1, 'circuitfrom.symbol': 1, 'circuitto.symbol': 1, 'userfrom.username': 1, 'userfrom.profile.img': 1, 'userto.username': 1, 'userto.profile.img': 1, 'groupfrom.groupname': 1, 'groupfrom.title': 1, 'groupto.groupname': 1, 'groupto.title': 1, 'contocomfrom.path': 1, 'contocomfrom.name': 1, 'contocomfrom.title': 1, 'contocomto.path': 1, 'contocomto.name': 1, 'contocomto.title': 1, }, }, ]; return aggr1; } catch (e) { return []; } return []; }; MovementSchema.statics.getMovsByCircuitId = async function (idapp, username, circuitId) { const MyMovement = this; const myquery = await MyMovement.getQueryMovsByCircuitId(idapp, username, '', '', circuitId); if (myquery && myquery.length > 0) { ris = await MyMovement.aggregate(myquery); return ris; } return []; }; MovementSchema.statics.checkIfCoinsAlreadySent = async function (notifId) { const MyMovement = this; try { const rec = await MyMovement.findOne({ notifId }, { _id: 1 }); return !!rec; } catch (e) { // If Error, don't send the coins return true; } }; const Movement = mongoose.model('Movement', MovementSchema); Movement.createIndexes((err) => { if (err) throw err; }); module.exports = { Movement };