'use strict'; const moment = require('moment'); const Sequelize = require('sequelize'); moment.locale('es'); const getStateCode = (event) => { var currentDate = moment().utc(), initDate = moment.utc(event.ini_date), endDate = moment.utc(event.end_date), init_availableDate = moment.utc(event.init_available_date), end_availableDate = moment.utc(event.end_available_date); if (moment(currentDate).isBetween(initDate, endDate)) { return 'current_event'; } else { if (moment(endDate).isBefore(currentDate)) { return 'closed_event'; } else { if (moment(currentDate).isBefore(init_availableDate)){ return 'future_registrations' } else { if (moment(currentDate).isBetween(init_availableDate, end_availableDate)) { return (event.sold_out == 1) ? 'waitinglist_open' : 'registrations_open'; } else { if (moment(currentDate).isAfter(end_availableDate)) return 'closed_registrations' else return 'N/A'; } } } }; }; const getStateText = (event) => { var currentDate = moment().utc(), initDate = moment.utc(event.ini_date), endDate = moment.utc(event.end_date), init_availableDate = moment.utc(event.init_available_date), end_availableDate = moment.utc(event.end_available_date); if (moment(currentDate).isBetween(initDate, endDate)) { return 'Congreso en curso'; } else { if (moment(endDate).isBefore(currentDate)) { return 'Congreso finalizado'; } else { if (moment(currentDate).isBefore(init_availableDate)) { return 'Inscripciones a partir del ' + moment(init_availableDate).format('D [de] MMMM'); } else { if (moment(currentDate).isBetween(init_availableDate, end_availableDate)) { return (event.sold_out == 1) ? 'Inscripciones abiertas a lista de espera' : 'Inscripciones abiertas'; } else { if (moment(currentDate).isAfter(end_availableDate)) return 'Inscripciones cerradas' else return 'N/A'; } } } }; }; module.exports = function (sequelize, DataTypes) { const Event = sequelize.define('Event', { id: { type: DataTypes.UUID, defaultValue: DataTypes.UUIDV4, primaryKey: true, }, name: { type: DataTypes.STRING, allowNull: false, }, description: { type: DataTypes.STRING, }, campaign_text: { type: DataTypes.TEXT, allowNull: true }, init_date: { type: DataTypes.DATE, allowNull: false, }, end_date: { type: DataTypes.DATE, }, init_available_date: { type: DataTypes.DATE, }, end_available_date: { type: DataTypes.DATE, }, gmt: { type: DataTypes.INTEGER, defaultValue: 1, }, assistants: { type: DataTypes.INTEGER, }, confirmed: { type: DataTypes.INTEGER, }, sold_out: { //Se han vendido todas y se ha abierto lista de espera si hay asignada type: DataTypes.BOOLEAN, defaultValue: false, }, allow_multiple: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, }, multiple_limit: { type: DataTypes.INTEGER, }, allow_overflow: { type: DataTypes.BOOLEAN, allowNull: false, defaultValue: false, }, overflow_eventId: { type: DataTypes.UUID, foreignKey: true, require: false, }, state: { type: DataTypes.STRING, allowNull: false, defaultValue: 'draft' }, stateCode: { type: Sequelize.VIRTUAL(Sequelize.STRING, ['init_date', 'end_date', 'init_available_date', 'end_available_date', 'sold_out']), get: function () { return getStateCode(this); }, }, stateText: { type: Sequelize.VIRTUAL(Sequelize.STRING, ['init_date', 'end_date', 'init_available_date', 'end_available_date', 'sold_out']), get: function () { return getStateText(this); }, }, typeId: { type: DataTypes.UUID, foreignKey: true, }, venueId: { type: DataTypes.UUID, foreignKey: true, }, locationId:{ type: DataTypes.UUID, foreignKey: true, }, url_streaming: { type: DataTypes.STRING, }, url_poll: { type: DataTypes.STRING, }, url_registration: { type: DataTypes.STRING, }, marketing_list: { type: DataTypes.STRING, }, userId: { type: DataTypes.UUID, foreignKey: true, }, }, { tableName: 'events', freezeTableName: true, timestamps: true, defaultScope: { where: { state: 'publish', typeId: { [Sequelize.Op.ne]: 2 }, }, include: [{ model: sequelize.models.EventType, as: 'type', attributes: ['name', 'title'], }, { association: 'location', attributes: ['country', 'city'], require:false, }], }, }); Event.associate = function (models) { Event.OverflowEvent = Event.belongsTo(models.Event, { as: 'overflowEvent', foreignKey: 'overflow_eventId', required: false }); Event.Type = Event.belongsTo(models.EventType, { foreignKey: 'typeId', as: "type" }); Event.UserCreate = Event.belongsTo(models.User, { foreignKey: 'userId', as: "user" }); Event.Venue = Event.belongsTo(models.Venue, { foreignKey: 'venueId', as: "venue", required: false}); Event.Details = Event.hasMany(models.EventDetail, { foreignKey: 'eventId', as: "details" }); Event.Location = Event.belongsTo(models.Location, { foreignKey: 'locationId', as: "location" }); //OJO antes de force comentar // OJO GENERA UN FOREIGN KEY Con eventos y habrĂ¡ ID de otras entidades que no exitan en la tabla eventos, porque son post o speakers Event.Comments = Event.hasMany(models.Comment, { foreignKey: 'entityId', scope: { entityName: 'event' }, as: "comments", required: false, }); Event.Multimedias = Event.hasMany(models.Multimedia, { foreignKey: 'entityId', as: { singular: 'multimedia', plural: 'multimedias' }, required: false, }); Event.Reservations = Event.hasMany(models.EventReservation, { foreignKey: 'eventId', as: "reservations", required: false, }); Event.Inscriptions = Event.hasMany(models.EventInscription, { foreignKey: 'eventId', as: "inscriptions", required: false, }); Event.Questions = Event.hasMany(models.EventQuestion, { foreignKey: 'eventId', as: "questions" , required: false, }); }; Event.addScope('includeVenue', () => { return { include: [ { model: sequelize.models.Venue, as: 'venue' } ] } }); Event.addScope('includeMultimedias', () => { return { include: [{ model: sequelize.models.Multimedia, as: { singular: 'multimedia', plural: 'multimedias' }, required: false, include : [{ model: sequelize.models.MultimediaFile, as: "multimediaFile" }] }, ] } }); Event.addScope('includeInscription', (userId) => { return { include: [ { model: sequelize.models.EventInscription, as: 'inscriptions', required: false, where: { userId: userId } } ] } }); Event.addScope('includeOverflowEvent', () => { return { include: [ { model: sequelize.models.Event, as: 'overflowEvent', required: false, where: { typeId: { [Sequelize.Op.ne]: null}}, // attributes: ['assistants', 'confirmed'], } ] } }); Event.addScope('includeDetails', () => { return { include: [{ model: sequelize.models.EventDetail, as: 'details', required: false, include: [{ model: sequelize.models.Speaker, as: 'speaker', required: false, include : [{ model: sequelize.models.Multimedia, as: { singular: 'multimedia', plural: 'multimedias' }, required: false, include: [{ model: sequelize.models.MultimediaFile, as: "multimediaFile" }] }] }] }] } }); Event.addScope('next', { where: { init_date: { [Sequelize.Op.gte]: moment().add(1, 'days').startOf('day').utc() } }, }); Event.addScope('today', { where: { init_date: { [Sequelize.Op.gte]: moment().startOf('day'), [Sequelize.Op.lt]: moment().add(1, 'days').startOf('day'), } } }); Event.addScope('current', { where: { init_date: { [Sequelize.Op.lte]: moment().utc(), }, end_date:{ [Sequelize.Op.gt]: moment().utc(), }, } }); Event.addScope('past', { where: { init_date: { [Sequelize.Op.lt]: moment().startOf('day').utc() } } }); Event.addScope('withOpenInscriptions', { where: { init_available_date: { [Sequelize.Op.lte]: moment().utc() }, end_available_date: { [Sequelize.Op.gt]: moment().utc() } }, }); Event.addScope('CitiesOfEvents', () => { return { include: [{ model: sequelize.models.Location, as: 'location', required: false, include: [{ model: sequelize.models.Multimedia, as: { singular: 'multimedia', plural: 'multimedias' }, required: false, attributes: ['type'], include: [{ model: sequelize.models.MultimediaFile, as: "multimediaFile", attributes: ['name', 'description', 'class', 'provider', 'url'] },] }] }, { model: sequelize.models.EventType, as: 'type', attributes: ['name', 'title'] }], group: ['location.country', 'location.city', 'Event.typeId',], attributes: ['location.country', 'location.city', 'type.name', 'type.title', [sequelize.fn('COUNT', sequelize.col('Event.typeId')), 'ediciones'], [sequelize.fn('SUM', sequelize.col('Event.assistants')), 'assistants']] } }); Event.addScope('onlyOfLocation', (location) => { return { where: { locationId: { [Sequelize.Op.eq]: location } }, } }); return Event; };