122 lines
3.6 KiB
JavaScript
122 lines
3.6 KiB
JavaScript
'use strict';
|
|
|
|
const
|
|
mongoose = require('mongoose'),
|
|
Schema = mongoose.Schema,
|
|
mongoUtil = require('../helpers/mongo'),
|
|
Setting = require('./setting'),
|
|
RptVar = require('./rpt_var'),
|
|
Country = require('./country'),
|
|
uniqid = require('uniqid'),
|
|
{ DEFAULT_LANG } = require('../helpers/constants'),
|
|
{ AppInputError } = require('../helpers/app_error');
|
|
|
|
const schema = new Schema({
|
|
/*
|
|
The username is for uniquely identify a user and also used for sending mails to.
|
|
For example: send user the password-reset email, sending reports, etc.
|
|
*/
|
|
username: {
|
|
type: String, trim: true,
|
|
index: {
|
|
unique: true,
|
|
partialFilterExpression: { username: { $type: 'string' } }
|
|
},
|
|
set: v => (v === '' ? null : v)
|
|
},
|
|
password: {
|
|
type: String, trim: true, required: false,
|
|
set: v => (v === '' ? null : v)
|
|
},
|
|
|
|
name: { type: String, required: false },
|
|
address: { type: String, required: false },
|
|
phone: { type: String, required: false },
|
|
email: { type: String, required: false, unique: false },
|
|
active: { type: Boolean, default: true },
|
|
/* The preffered language from the available ones within the FE (English(en) - default, Spanish(es), Portuguese(pt)) */
|
|
lang: { type: String, default: DEFAULT_LANG },
|
|
|
|
parent: { type: Schema.Types.ObjectId, ref: 'User', required: false },
|
|
|
|
loggedInAt: { type: Date },
|
|
|
|
markedDelete: { type: Boolean, default: false }
|
|
|
|
}, { timestamps: true, discriminatorKey: 'kind', toJSON: { virtuals: true }, toObject: { virtuals: true }, strictQuery: false });
|
|
|
|
schema.virtual('Country', {
|
|
ref: 'Country',
|
|
localField: 'country',
|
|
foreignField: 'code',
|
|
justOne: true,
|
|
});
|
|
|
|
class UserBaseSchema {
|
|
|
|
static toUser(srcOjb) {
|
|
if (!srcOjb) AppInputError.throw(); //throw new Error('Blank User is not supported !');
|
|
|
|
if (srcOjb['Country'] && typeof srcOjb['Country'] === 'object' && srcOjb['Country'].code) {
|
|
srcOjb['country'] = srcOjb['Country'].code;
|
|
}
|
|
return srcOjb;
|
|
}
|
|
|
|
async markAsDeleted(session) {
|
|
session && (session.startTransaction(mongoUtil.getTranOps()));
|
|
try {
|
|
// De-activate the username so same username can be re-used
|
|
this.username && (this.username = this.username + '#' + uniqid());
|
|
this.active && (this.active = false);
|
|
|
|
this.markedDelete = true;
|
|
|
|
await this.save({ session });
|
|
} catch (error) {
|
|
session && (session.abortTransaction());
|
|
throw error;
|
|
}
|
|
session && await mongoUtil.commitWithRetry(session);
|
|
}
|
|
|
|
async deleteMarked(session) {
|
|
session && (session.startTransaction(mongoUtil.getTranOps()));
|
|
try {
|
|
await this.remove({ session });
|
|
} catch (error) {
|
|
session && (session.abortTransaction());
|
|
throw error;
|
|
}
|
|
session && await mongoUtil.commitWithRetry(session);
|
|
}
|
|
}
|
|
schema.loadClass(UserBaseSchema);
|
|
|
|
async function clearRelatedData(doc) {
|
|
if (!doc) return;
|
|
await Setting.deleteMany({ userId: doc._id }).session(doc.$session());
|
|
await RptVar.deleteMany({ userId: doc._id }).session(doc.$session());
|
|
}
|
|
|
|
/**
|
|
* Handle pre-update hooks middleware before updating one user.
|
|
*/
|
|
schema.pre(['updateOne', 'findOneAndUpdate'], function () {
|
|
// Convert ref objects to its code/id for storate
|
|
if (this._update['Country'] && typeof this._update['Country'] === 'object' && this._update['Country'].code) {
|
|
this._update['country'] = this._update['Country'].code;
|
|
}
|
|
});
|
|
|
|
schema.post('remove', async function () {
|
|
await clearRelatedData(this);
|
|
});
|
|
schema.post('findOneAndRemove', async function (doc) {
|
|
await clearRelatedData(doc);
|
|
});
|
|
schema.post('findOneAndDelete', async function (doc) {
|
|
await clearRelatedData(doc);
|
|
});
|
|
|
|
module.exports = mongoose.model('User', schema); |