app2-api/modules/events/event.model.js
2019-08-27 16:46:20 +02:00

406 lines
12 KiB
JavaScript

'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,
},
city: {
type: DataTypes.STRING,
foreignKey: true,
// references: {
// model: 'Location',
// key : 'city',
// }
},
country: {
type: DataTypes.STRING,
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,
indexes: [{
unique: false,
fields: ['country', 'city']
}],
defaultScope: {
where: {
state: 'publish',
typeId: { [Sequelize.Op.ne]: 2 },
},
include: [{
model: sequelize.models.EventType,
as: 'type',
attributes: ['name', 'title'],
}]
},
});
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" });
//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.Location = Event.belongsTo(models.Location, {
foreignKey: ['country', 'city'],
// sourceKey: ['country', 'city'],
as: "location",
required: false,
// constraints: 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('includeLocation', () => {
return {
include: [
{ model: sequelize.models.Location, as: "location", foreignKey: ['country', 'city'], required: false,}
]
}
});
*/
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}
]
}
});
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').utc(),
[Sequelize.Op.lt]: moment().add(1, 'days').startOf('day').utc(),
}
}
});
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', {
include : [{ model: sequelize.models.EventType, as: 'type', attributes:['name', 'title'] }],
group: ['city', 'country', 'typeId'],
attributes: ['city', 'country', 'type.name', 'type.title', [sequelize.fn('COUNT', sequelize.col('typeId')), 'ediciones'], [sequelize.fn('SUM', sequelize.col('assistants')), 'assistants']]
});
Event.addScope('onlyOfCity', (city) => {
return {
where: {
city: {
[Sequelize.Op.eq]: city
}
},
}
});
return Event;
};