"use strict"; const moment = require("moment"); const Sequelize = require("sequelize"); moment.locale("es"); const getStateCode = (event) => { var currentDate = moment(), initDate = moment(event.init_date), endDate = moment(event.end_date), init_availableDate = moment(event.init_available_date), end_availableDate = moment(event.end_available_date); if (currentDate.isBetween(initDate, endDate)) { return "current_event"; } else { if (endDate.isBefore(currentDate)) { return "closed_event"; } else { if (currentDate.isBefore(init_availableDate)) { return "future_registrations"; } else { if (currentDate.isBetween(init_availableDate, end_availableDate)) { if (event.url_registration) { return "url_registrations_open"; } else { return event.sold_out == 1 ? "waitinglist_open" : "registrations_open"; } } else { if (currentDate.isAfter(end_availableDate)) return "closed_registrations"; else return "N/A"; } } } } }; const getStateText = (event) => { var currentDate = moment(), initDate = moment(event.init_date), endDate = moment(event.end_date), init_availableDate = moment(event.init_available_date), end_availableDate = moment(event.end_available_date); if (currentDate.isBetween(initDate, endDate)) { return "Congreso en curso"; } else { if (endDate.isBefore(currentDate)) { return "Congreso finalizado"; } else { if (currentDate.isBefore(init_availableDate)) { return "Inscripciones a partir del " + init_availableDate.format("D [de] MMMM"); } else { if (currentDate.isBetween(init_availableDate, end_availableDate)) { if (event.url_registration) { return "Inscripciones abiertas"; } else { return event.sold_out == 1 ? "Inscripciones abiertas a lista de espera" : "Inscripciones abiertas"; } } else { if (currentDate.isAfter(end_availableDate)) return "Inscripciones cerradas"; else return "N/A"; } } } } }; const getAssistanceType = (event) => { if (event.virtual) { if (event.assistants > 0) { return "onsite, online"; } else { return "online"; } } else { return "onsite"; } }; const getAssistanceTypeText = (event) => { if (event.virtual) { if (event.assistants > 0) { return "evento presencial y online"; } else { return "evento online"; } } else { return "evento presencial"; } }; 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, }, featured: { type: DataTypes.BOOLEAN, defaultValue: false, }, virtual: { type: DataTypes.BOOLEAN, defaultValue: false, }, allow_questions: { type: DataTypes.BOOLEAN, defaultValue: true, }, assistanceType: { type: Sequelize.VIRTUAL(Sequelize.STRING, ["virtual", "assistants"]), get: function () { return getAssistanceType(this); }, }, assistanceTypeText: { type: Sequelize.VIRTUAL(Sequelize.STRING, ["virtual", "assistants"]), get: function () { return getAssistanceTypeText(this); }, }, }, { 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", "country_code"], 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("featured", { where: { featured: true, }, }); 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", }, ], order: [["type", "ASC"]], // <- esto no funciona por ahora en Sequelize }, ], }; }); Event.addScope("includeMultimediaAvatar", () => { return { include: [ { model: sequelize.models.Multimedia, as: { singular: "multimedia", plural: "multimedias" }, where: { type: "avatar" }, 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("includeComments", () => { return { include: [ { model: sequelize.models.Comment, as: "comments", required: false, include: [ { model: sequelize.models.User, as: "user", }, ], }, ], }; }); Event.addScope("next", { where: { init_date: { [Sequelize.Op.gte]: moment().add(1, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("today", { where: { init_date: { [Sequelize.Op.gte]: moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), [Sequelize.Op.lt]: moment().add(1, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("current", { where: { init_date: { [Sequelize.Op.lte]: moment().format("YYYY-MM-DD HH:mm:ss"), }, end_date: { [Sequelize.Op.gt]: moment().format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("tomorrow", { where: { init_date: { [Sequelize.Op.gte]: moment().add(1, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"), [Sequelize.Op.lt]: moment().add(2, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("yesterday", { where: { init_date: { [Sequelize.Op.gte]: moment().add(-1, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"), [Sequelize.Op.lt]: moment().add("day").startOf("day").format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("past", { where: { init_date: { [Sequelize.Op.lt]: moment().startOf("day").format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("withOpenInscriptions", { where: { init_available_date: { [Sequelize.Op.lte]: moment().format("YYYY-MM-DD HH:mm:ss"), }, end_available_date: { [Sequelize.Op.gt]: moment().format("YYYY-MM-DD HH:mm:ss"), }, }, }); Event.addScope("withSevilla", { where: { id: { [Sequelize.Op.eq]: "f1aa418a-d196-11ef-8ecf-000c29a89113", }, }, }); 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; };