Ordenar los próximos eventos poniendo primero los del país del usuario o dispositivo
This commit is contained in:
parent
d2e27c02af
commit
abc9bb4dee
@ -155,3 +155,4 @@ const generateControllers = (service, extraControllers = {}, options = {}) => {
|
|||||||
|
|
||||||
module.exports = generateControllers;
|
module.exports = generateControllers;
|
||||||
module.exports.buildContext = buildContext;
|
module.exports.buildContext = buildContext;
|
||||||
|
module.exports.defaultOptions = defaultOptions;
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
const express = require('express');
|
const express = require("express");
|
||||||
//const morgan = require('morgan');
|
//const morgan = require('morgan');
|
||||||
const bodyParser = require('body-parser');
|
const bodyParser = require("body-parser");
|
||||||
const compress = require('compression');
|
const compress = require("compression");
|
||||||
const responseTime = require('response-time');
|
const responseTime = require("response-time");
|
||||||
const methodOverride = require('method-override');
|
const methodOverride = require("method-override");
|
||||||
const cors = require('cors');
|
const cors = require("cors");
|
||||||
const helmet = require('helmet');
|
const helmet = require("helmet");
|
||||||
const passport = require('passport');
|
const passport = require("passport");
|
||||||
|
|
||||||
const config = require('../config');
|
const config = require("../config");
|
||||||
const router = require('./router');
|
const router = require("./router");
|
||||||
const error = require('../middlewares/error');
|
const error = require("../middlewares/error");
|
||||||
|
|
||||||
|
const deviceCountryMiddleware = require("../middlewares/deviceCountry");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Express instance
|
* Express instance
|
||||||
@ -24,10 +26,13 @@ const app = express();
|
|||||||
//app.use(morgan(logs));
|
//app.use(morgan(logs));
|
||||||
|
|
||||||
// parse body params and attache them to req.body
|
// parse body params and attache them to req.body
|
||||||
app.use(bodyParser.json({ limit: '5mb' }));
|
app.use(bodyParser.json({ limit: "5mb" }));
|
||||||
app.use(bodyParser.urlencoded({
|
app.use(
|
||||||
limit: '5mb', extended: true
|
bodyParser.urlencoded({
|
||||||
}));
|
limit: "5mb",
|
||||||
|
extended: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
// set up the response-time middleware
|
// set up the response-time middleware
|
||||||
app.use(responseTime());
|
app.use(responseTime());
|
||||||
@ -43,14 +48,23 @@ app.use(methodOverride());
|
|||||||
app.use(helmet());
|
app.use(helmet());
|
||||||
|
|
||||||
// enable CORS - Cross Origin Resource Sharing
|
// enable CORS - Cross Origin Resource Sharing
|
||||||
//var allowedOrigins = ['http://localhost:8080', 'http://127.0.0.1:8080', 'https://adminapp2.loquedeverdadimporta.org'];
|
//var allowedOrigins = ['http://localhost:8080', 'http://127.0.0.1:8080', 'https://adminapp2.loquedeverdadimporta.org'];
|
||||||
|
|
||||||
// enable CORS - Cross Origin Resource Sharing
|
// enable CORS - Cross Origin Resource Sharing
|
||||||
app.use(cors({
|
app.use(
|
||||||
exposedHeaders: ['Content-Disposition', 'Content-Type', 'Content-Length',
|
cors({
|
||||||
'X-Total-Count', 'Pagination-Count', 'Pagination-Page', 'Pagination-Limit'],
|
exposedHeaders: [
|
||||||
}));
|
"X-Country",
|
||||||
|
"Content-Disposition",
|
||||||
|
"Content-Type",
|
||||||
|
"Content-Length",
|
||||||
|
"X-Total-Count",
|
||||||
|
"Pagination-Count",
|
||||||
|
"Pagination-Page",
|
||||||
|
"Pagination-Limit",
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
/*app.use(cors({
|
/*app.use(cors({
|
||||||
origin: function (origin, callback) {
|
origin: function (origin, callback) {
|
||||||
@ -74,7 +88,6 @@ app.use(cors({
|
|||||||
}
|
}
|
||||||
}));*/
|
}));*/
|
||||||
|
|
||||||
|
|
||||||
/*app.use(cors({
|
/*app.use(cors({
|
||||||
origin: '*',
|
origin: '*',
|
||||||
exposeHeaders: [
|
exposeHeaders: [
|
||||||
@ -113,14 +126,14 @@ app.use(cors({
|
|||||||
],
|
],
|
||||||
}));*/
|
}));*/
|
||||||
|
|
||||||
|
app.use(deviceCountryMiddleware.middleware());
|
||||||
|
|
||||||
// Access validator
|
// Access validator
|
||||||
app.use(passport.initialize());
|
app.use(passport.initialize());
|
||||||
require('./passport');
|
require("./passport");
|
||||||
|
|
||||||
// Set routes
|
// Set routes
|
||||||
app.use('/api', router());
|
app.use("/api", router());
|
||||||
|
|
||||||
// if error is not an instanceOf APIError, convert it.
|
// if error is not an instanceOf APIError, convert it.
|
||||||
app.use(error.converter);
|
app.use(error.converter);
|
||||||
@ -131,4 +144,4 @@ app.use(error.notFound);
|
|||||||
// error handler, send stacktrace only during development
|
// error handler, send stacktrace only during development
|
||||||
app.use(error.handler);
|
app.use(error.handler);
|
||||||
|
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
|
|||||||
17
middlewares/deviceCountry.js
Normal file
17
middlewares/deviceCountry.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
const middleware = (config) => {
|
||||||
|
return function (req, res, next) {
|
||||||
|
const country = req.headers["x-country"];
|
||||||
|
|
||||||
|
if (country) {
|
||||||
|
req.deviceCountry = country;
|
||||||
|
} else {
|
||||||
|
req.deviceCountry = "ES";
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
middleware,
|
||||||
|
};
|
||||||
@ -2,6 +2,7 @@
|
|||||||
const moment = require("moment");
|
const moment = require("moment");
|
||||||
const httpStatus = require("http-status");
|
const httpStatus = require("http-status");
|
||||||
const generateControllers = require("../../core/controllers");
|
const generateControllers = require("../../core/controllers");
|
||||||
|
const { defaultOptions, buildContext } = require("../../core/controllers");
|
||||||
const QRHelper = require("../../helpers/qr.helper");
|
const QRHelper = require("../../helpers/qr.helper");
|
||||||
const emailHelper = require("../../helpers/mail.helper");
|
const emailHelper = require("../../helpers/mail.helper");
|
||||||
const notificationHelper = require("../../helpers/notification.helpers");
|
const notificationHelper = require("../../helpers/notification.helpers");
|
||||||
@ -31,7 +32,7 @@ const MODULE_NAME = "[event.controller]";
|
|||||||
|
|
||||||
const controllerOptions = {
|
const controllerOptions = {
|
||||||
MODULE_NAME,
|
MODULE_NAME,
|
||||||
findOneCallback: eventInscriptionService._fillInscriptionsColor
|
findOneCallback: eventInscriptionService._fillInscriptionsColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
function generateMemberInscription(user, inscription, reservation) {
|
function generateMemberInscription(user, inscription, reservation) {
|
||||||
@ -61,8 +62,6 @@ function generateMemberInscription(user, inscription, reservation) {
|
|||||||
return memberInscription;
|
return memberInscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const extraControllers = {
|
const extraControllers = {
|
||||||
checkCapacity: async (req, res, next) => {
|
checkCapacity: async (req, res, next) => {
|
||||||
const params = extractParamsFromRequest(req, res, {});
|
const params = extractParamsFromRequest(req, res, {});
|
||||||
@ -72,7 +71,7 @@ const extraControllers = {
|
|||||||
allow: false,
|
allow: false,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
};
|
};
|
||||||
console.log('>>>>>>>>>>>>>>>>>>>>>>>checkCapacity', result);
|
console.log(">>>>>>>>>>>>>>>>>>>>>>>checkCapacity", result);
|
||||||
|
|
||||||
if (!result.eventId) {
|
if (!result.eventId) {
|
||||||
return handleResultResponse(null, null, params, res, httpStatus.BAD_REQUEST);
|
return handleResultResponse(null, null, params, res, httpStatus.BAD_REQUEST);
|
||||||
@ -123,8 +122,6 @@ const extraControllers = {
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
var result = null;
|
var result = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log(params, req.user.level);
|
console.log(params, req.user.level);
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
try {
|
try {
|
||||||
@ -138,7 +135,7 @@ const extraControllers = {
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
result = await eventInscriptionService._getInscriptionsUser(userId);
|
result = await eventInscriptionService._getInscriptionsUser(userId);
|
||||||
result = result.map(row => row.toJSON());
|
result = result.map((row) => row.toJSON());
|
||||||
// Asigno colores a las entradas normales
|
// Asigno colores a las entradas normales
|
||||||
result = eventInscriptionService._fillInscriptionsColor(result);
|
result = eventInscriptionService._fillInscriptionsColor(result);
|
||||||
return handleResultResponse(result, null, params, res, result === null ? httpStatus.NOT_FOUND : httpStatus.OK);
|
return handleResultResponse(result, null, params, res, result === null ? httpStatus.NOT_FOUND : httpStatus.OK);
|
||||||
@ -156,8 +153,7 @@ const extraControllers = {
|
|||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
var result = null;
|
var result = null;
|
||||||
|
|
||||||
if (!eventId)
|
if (!eventId) return handleResultResponse("Es necesario el ID del evento", null, params, res, httpStatus.NOT_FOUND);
|
||||||
return handleResultResponse("Es necesario el ID del evento", null, params, res, httpStatus.NOT_FOUND);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = await eventInscriptionService._getInscriptionOnlineByEvent(eventId);
|
result = await eventInscriptionService._getInscriptionOnlineByEvent(eventId);
|
||||||
@ -167,26 +163,53 @@ const extraControllers = {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
return handleErrorResponse(MODULE_NAME, "getInscriptionsOnline", error, res);
|
return handleErrorResponse(MODULE_NAME, "getInscriptionsOnline", error, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getInscriptionsOfNextEventsCount: async (req, res, next) => {
|
getInscriptionsOfNextEventsCount: async (req, res, next) => {
|
||||||
const params = extractParamsFromRequest(req, res, {});
|
const params = extractParamsFromRequest(req, res, {});
|
||||||
const userId = req.user.id;
|
const userId = req.user.id;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await eventInscriptionService._getInscriptionsOfNextEventsUser(userId);
|
const result = await eventInscriptionService._getInscriptionsOfNextEventsUser(userId);
|
||||||
console.log("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
|
|
||||||
return handleResultResponse({ count: result }, null, params, res, httpStatus.OK);
|
return handleResultResponse({ count: result }, null, params, res, httpStatus.OK);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("aaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
|
||||||
return handleErrorResponse(MODULE_NAME, "getInscriptionsOfNextEventsCount", error, res);
|
return handleErrorResponse(MODULE_NAME, "getInscriptionsOfNextEventsCount", error, res);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
findNextEventsByCountry: (config) => {
|
||||||
|
function placesCountrysEventsFirst(rows, countryCode) {
|
||||||
|
const countryEvents = [];
|
||||||
|
const restEvents = [];
|
||||||
|
|
||||||
|
for (const event of rows) {
|
||||||
|
if (event.location.country_code === countryCode) {
|
||||||
|
countryEvents.push(event);
|
||||||
|
} else {
|
||||||
|
restEvents.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return countryEvents.concat(restEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
return async (req, res, next) => {
|
||||||
|
config = config || {
|
||||||
|
scopes: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const params = extractParamsFromRequest(req, res, defaultOptions.params.find);
|
||||||
|
try {
|
||||||
|
const result = await eventService.fetchAll(params, buildContext(req, config));
|
||||||
|
|
||||||
|
const orderedRows = placesCountrysEventsFirst(result.rows, req.user ? req.user.country : req.deviceCountry);
|
||||||
|
|
||||||
|
console.log(orderedRows);
|
||||||
|
return handleResultResponse(orderedRows, result.count, params, res);
|
||||||
|
} catch (error) {
|
||||||
|
return handleErrorResponse(MODULE_NAME, "findNextEventsByCountry", error, res);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
findPartners: async (req, res, next) => {
|
findPartners: async (req, res, next) => {
|
||||||
const params = extractParamsFromRequest(req, res, {});
|
const params = extractParamsFromRequest(req, res, {});
|
||||||
@ -326,11 +349,15 @@ const extraControllers = {
|
|||||||
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>><syncronizeMarketingList");
|
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>><syncronizeMarketingList");
|
||||||
|
|
||||||
if (marketingListService.syncronizeEventWithMarketingList(eventId))
|
if (marketingListService.syncronizeEventWithMarketingList(eventId))
|
||||||
return handleResultResponse("La sincronización se ha realizado correctamente", null, params, res, httpStatus.DELETEOK);
|
return handleResultResponse(
|
||||||
|
"La sincronización se ha realizado correctamente",
|
||||||
|
null,
|
||||||
|
params,
|
||||||
|
res,
|
||||||
|
httpStatus.DELETEOK
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
getQRCodeInscription: async (req, res, next) => {
|
getQRCodeInscription: async (req, res, next) => {
|
||||||
const params = extractParamsFromRequest(req, res, {});
|
const params = extractParamsFromRequest(req, res, {});
|
||||||
const inscriptionId = params.params.id;
|
const inscriptionId = params.params.id;
|
||||||
@ -381,7 +408,8 @@ const extraControllers = {
|
|||||||
//console.log(headerMail, bodyMail);
|
//console.log(headerMail, bodyMail);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (member.validated) emailHelper.sendTicket(mailService.generateHeaderMail(member), mailService.generateBodyMail(member));
|
if (member.validated)
|
||||||
|
emailHelper.sendTicket(mailService.generateHeaderMail(member), mailService.generateBodyMail(member));
|
||||||
else emailHelper.sendListaEspera(mailService.generateHeaderMail(member), mailService.generateBodyMail(member));
|
else emailHelper.sendListaEspera(mailService.generateHeaderMail(member), mailService.generateBodyMail(member));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("No se ha podido mandar email con entrada");
|
console.log("No se ha podido mandar email con entrada");
|
||||||
|
|||||||
@ -1,496 +1,544 @@
|
|||||||
'use strict';
|
"use strict";
|
||||||
const moment = require('moment');
|
const moment = require("moment");
|
||||||
const Sequelize = require('sequelize');
|
const Sequelize = require("sequelize");
|
||||||
moment.locale('es');
|
moment.locale("es");
|
||||||
|
|
||||||
const getStateCode = (event) => {
|
const getStateCode = (event) => {
|
||||||
var currentDate = moment(),
|
var currentDate = moment(),
|
||||||
initDate = moment(event.init_date),
|
initDate = moment(event.init_date),
|
||||||
endDate = moment(event.end_date),
|
endDate = moment(event.end_date),
|
||||||
init_availableDate = moment(event.init_available_date),
|
init_availableDate = moment(event.init_available_date),
|
||||||
end_availableDate = moment(event.end_available_date);
|
end_availableDate = moment(event.end_available_date);
|
||||||
|
|
||||||
if (currentDate.isBetween(initDate, endDate)) {
|
if (currentDate.isBetween(initDate, endDate)) {
|
||||||
return 'current_event';
|
return "current_event";
|
||||||
|
} else {
|
||||||
|
if (endDate.isBefore(currentDate)) {
|
||||||
|
return "closed_event";
|
||||||
} else {
|
} else {
|
||||||
if (endDate.isBefore(currentDate)) {
|
if (currentDate.isBefore(init_availableDate)) {
|
||||||
return 'closed_event';
|
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 {
|
} else {
|
||||||
if (currentDate.isBefore(init_availableDate)){
|
if (currentDate.isAfter(end_availableDate)) return "closed_registrations";
|
||||||
return 'future_registrations'
|
else return "N/A";
|
||||||
} 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) => {
|
const getStateText = (event) => {
|
||||||
var currentDate = moment(),
|
var currentDate = moment(),
|
||||||
initDate = moment(event.init_date),
|
initDate = moment(event.init_date),
|
||||||
endDate = moment(event.end_date),
|
endDate = moment(event.end_date),
|
||||||
init_availableDate = moment(event.init_available_date),
|
init_availableDate = moment(event.init_available_date),
|
||||||
end_availableDate = moment(event.end_available_date);
|
end_availableDate = moment(event.end_available_date);
|
||||||
|
|
||||||
if (currentDate.isBetween(initDate, endDate)) {
|
if (currentDate.isBetween(initDate, endDate)) {
|
||||||
return 'Congreso en curso';
|
return "Congreso en curso";
|
||||||
|
} else {
|
||||||
|
if (endDate.isBefore(currentDate)) {
|
||||||
|
return "Congreso finalizado";
|
||||||
} else {
|
} else {
|
||||||
if (endDate.isBefore(currentDate)) {
|
if (currentDate.isBefore(init_availableDate)) {
|
||||||
return 'Congreso finalizado';
|
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 {
|
} else {
|
||||||
if (currentDate.isBefore(init_availableDate)) {
|
if (currentDate.isAfter(end_availableDate)) return "Inscripciones cerradas";
|
||||||
return 'Inscripciones a partir del ' + init_availableDate.format('D [de] MMMM');
|
else return "N/A";
|
||||||
} 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) => {
|
const getAssistanceType = (event) => {
|
||||||
if (event.virtual) {
|
if (event.virtual) {
|
||||||
if (event.assistants > 0) {
|
if (event.assistants > 0) {
|
||||||
return 'onsite, online';
|
return "onsite, online";
|
||||||
} else {
|
|
||||||
return 'online';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return 'onsite';
|
return "online";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return "onsite";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAssistanceTypeText = (event) => {
|
const getAssistanceTypeText = (event) => {
|
||||||
if (event.virtual) {
|
if (event.virtual) {
|
||||||
if (event.assistants > 0) {
|
if (event.assistants > 0) {
|
||||||
return 'evento presencial y online';
|
return "evento presencial y online";
|
||||||
} else {
|
|
||||||
return 'evento online';
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return 'evento presencial';
|
return "evento online";
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
return "evento presencial";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = function (sequelize, DataTypes) {
|
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,
|
||||||
|
|
||||||
const Event = sequelize.define('Event', {
|
defaultScope: {
|
||||||
id: {
|
where: {
|
||||||
type: DataTypes.UUID,
|
state: "publish",
|
||||||
defaultValue: DataTypes.UUIDV4,
|
typeId: { [Sequelize.Op.ne]: 2 },
|
||||||
primaryKey: true,
|
|
||||||
},
|
},
|
||||||
name: {
|
include: [
|
||||||
type: DataTypes.STRING,
|
{
|
||||||
allowNull: false,
|
model: sequelize.models.EventType,
|
||||||
},
|
as: "type",
|
||||||
description: {
|
attributes: ["name", "title"],
|
||||||
type: DataTypes.STRING,
|
},
|
||||||
},
|
{
|
||||||
campaign_text: {
|
association: "location",
|
||||||
type: DataTypes.TEXT,
|
attributes: ["country", "city", "country_code"],
|
||||||
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,
|
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);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
}, {
|
Event.associate = function (models) {
|
||||||
tableName: 'events',
|
Event.OverflowEvent = Event.belongsTo(models.Event, {
|
||||||
freezeTableName: true,
|
as: "overflowEvent",
|
||||||
timestamps: true,
|
foreignKey: "overflow_eventId",
|
||||||
|
required: false,
|
||||||
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, {
|
Event.Type = Event.belongsTo(models.EventType, { foreignKey: "typeId", as: "type" });
|
||||||
as: 'overflowEvent',
|
Event.UserCreate = Event.belongsTo(models.User, { foreignKey: "userId", as: "user" });
|
||||||
foreignKey: 'overflow_eventId',
|
Event.Venue = Event.belongsTo(models.Venue, { foreignKey: "venueId", as: "venue", required: false });
|
||||||
required: false });
|
Event.Details = Event.hasMany(models.EventDetail, { foreignKey: "eventId", as: "details" });
|
||||||
|
Event.Location = Event.belongsTo(models.Location, { foreignKey: "locationId", as: "location" });
|
||||||
|
|
||||||
Event.Type = Event.belongsTo(models.EventType, { foreignKey: 'typeId', as: "type" });
|
//OJO antes de force comentar
|
||||||
Event.UserCreate = Event.belongsTo(models.User, { foreignKey: 'userId', as: "user" });
|
// 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.Venue = Event.belongsTo(models.Venue, { foreignKey: 'venueId', as: "venue", required: false});
|
Event.Comments = Event.hasMany(models.Comment, {
|
||||||
Event.Details = Event.hasMany(models.EventDetail, { foreignKey: 'eventId', as: "details" });
|
foreignKey: "entityId",
|
||||||
Event.Location = Event.belongsTo(models.Location, { foreignKey: 'locationId', as: "location" });
|
scope: {
|
||||||
|
entityName: "event",
|
||||||
|
},
|
||||||
|
as: "comments",
|
||||||
|
required: false,
|
||||||
|
});
|
||||||
|
|
||||||
//OJO antes de force comentar
|
Event.Multimedias = Event.hasMany(models.Multimedia, {
|
||||||
// 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
|
foreignKey: "entityId",
|
||||||
Event.Comments = Event.hasMany(models.Comment, {
|
as: { singular: "multimedia", plural: "multimedias" },
|
||||||
foreignKey: 'entityId',
|
required: false,
|
||||||
scope: {
|
});
|
||||||
entityName: 'event'
|
|
||||||
},
|
|
||||||
as: "comments",
|
|
||||||
required: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
Event.Multimedias = Event.hasMany(models.Multimedia, {
|
Event.Reservations = Event.hasMany(models.EventReservation, {
|
||||||
foreignKey: 'entityId',
|
foreignKey: "eventId",
|
||||||
as: { singular: 'multimedia', plural: 'multimedias' },
|
as: "reservations",
|
||||||
required: false,
|
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.Reservations = Event.hasMany(models.EventReservation, {
|
Event.addScope("featured", {
|
||||||
foreignKey: 'eventId', as: "reservations",
|
where: {
|
||||||
required: false,
|
featured: true,
|
||||||
});
|
},
|
||||||
Event.Inscriptions = Event.hasMany(models.EventInscription, {
|
});
|
||||||
foreignKey: 'eventId', as: "inscriptions",
|
|
||||||
required: false,
|
Event.addScope("includeVenue", () => {
|
||||||
});
|
return {
|
||||||
Event.Questions = Event.hasMany(models.EventQuestion, {
|
include: [{ model: sequelize.models.Venue, as: "venue" }],
|
||||||
foreignKey: 'eventId', as: "questions" ,
|
|
||||||
required: false,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
});
|
||||||
Event.addScope('featured', {
|
|
||||||
where: {
|
Event.addScope("includeMultimedias", () => {
|
||||||
featured: true
|
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('includeVenue', () => {
|
Event.addScope("includeMultimediaAvatar", () => {
|
||||||
return {
|
return {
|
||||||
include: [
|
include: [
|
||||||
{ model: sequelize.models.Venue, as: 'venue' }
|
{
|
||||||
]
|
model: sequelize.models.Multimedia,
|
||||||
}
|
as: { singular: "multimedia", plural: "multimedias" },
|
||||||
});
|
where: { type: "avatar" },
|
||||||
|
required: false,
|
||||||
Event.addScope('includeMultimedias', () => {
|
include: [
|
||||||
return {
|
{
|
||||||
include: [{
|
model: sequelize.models.MultimediaFile,
|
||||||
model: sequelize.models.Multimedia,
|
as: "multimediaFile",
|
||||||
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', () => {
|
Event.addScope("includeInscription", (userId) => {
|
||||||
return {
|
return {
|
||||||
include: [{
|
include: [
|
||||||
model: sequelize.models.Multimedia,
|
{ model: sequelize.models.EventInscription, as: "inscriptions", required: false, where: { userId: userId } },
|
||||||
as: { singular: 'multimedia', plural: 'multimedias' },
|
],
|
||||||
where: { type: 'avatar'},
|
};
|
||||||
required: false,
|
});
|
||||||
include: [{
|
|
||||||
model: sequelize.models.MultimediaFile,
|
|
||||||
as: "multimediaFile"
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Event.addScope('includeInscription', (userId) => {
|
Event.addScope("includeOverflowEvent", () => {
|
||||||
return {
|
return {
|
||||||
include: [
|
include: [
|
||||||
{ model: sequelize.models.EventInscription, as: 'inscriptions',
|
{
|
||||||
required: false,
|
model: sequelize.models.Event,
|
||||||
where: { userId: userId } }
|
as: "overflowEvent",
|
||||||
]
|
required: false,
|
||||||
}
|
where: { typeId: { [Sequelize.Op.ne]: null } },
|
||||||
});
|
// attributes: ['assistants', 'confirmed'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
Event.addScope('includeOverflowEvent', () => {
|
Event.addScope("includeDetails", () => {
|
||||||
return {
|
return {
|
||||||
include: [
|
include: [
|
||||||
{ model: sequelize.models.Event,
|
{
|
||||||
as: 'overflowEvent',
|
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,
|
required: false,
|
||||||
where: { typeId: { [Sequelize.Op.ne]: null}},
|
include: [
|
||||||
// attributes: ['assistants', 'confirmed'],
|
{
|
||||||
}
|
model: sequelize.models.MultimediaFile,
|
||||||
]
|
as: "multimediaFile",
|
||||||
}
|
},
|
||||||
});
|
],
|
||||||
|
},
|
||||||
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', {
|
Event.addScope("includeComments", () => {
|
||||||
where: {
|
return {
|
||||||
init_date: {
|
include: [
|
||||||
[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'),
|
model: sequelize.models.Comment,
|
||||||
}
|
as: "comments",
|
||||||
}
|
required: false,
|
||||||
});
|
include: [
|
||||||
|
{
|
||||||
Event.addScope('current', {
|
model: sequelize.models.User,
|
||||||
where: {
|
as: "user",
|
||||||
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('CitiesOfEvents', () => {
|
Event.addScope("next", {
|
||||||
return {
|
where: {
|
||||||
include: [{
|
init_date: {
|
||||||
model: sequelize.models.Location, as: 'location', required: false,
|
[Sequelize.Op.gte]: moment().add(1, "days").startOf("day").format("YYYY-MM-DD HH:mm:ss"),
|
||||||
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) => {
|
Event.addScope("today", {
|
||||||
return {
|
where: {
|
||||||
where: { locationId: { [Sequelize.Op.eq]: location } },
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
return Event;
|
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("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;
|
||||||
|
};
|
||||||
|
|||||||
@ -64,6 +64,7 @@ routes.get(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Esta ruta se dejará de usar a favor de "/events/next_by_country"
|
||||||
routes.get(
|
routes.get(
|
||||||
"/events/next",
|
"/events/next",
|
||||||
isOptionalUser,
|
isOptionalUser,
|
||||||
@ -78,11 +79,29 @@ routes.get(
|
|||||||
if (isLogged) {
|
if (isLogged) {
|
||||||
scopes.push({ method: ["includeInscription", req.user.id] });
|
scopes.push({ method: ["includeInscription", req.user.id] });
|
||||||
}
|
}
|
||||||
// console.log(moment().add(1, 'days').startOf('day').format('YYYY-MM-DD HH:mm:ss'));
|
|
||||||
return eventController.find({ scopes })(req, res, next);
|
return eventController.find({ scopes })(req, res, next);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Sustituye a "/events/next" a partir de la versión de la APP 1.4.4
|
||||||
|
routes.get(
|
||||||
|
"/events/next_by_country",
|
||||||
|
isOptionalUser,
|
||||||
|
FieldMiddleware.middleware({
|
||||||
|
invalidFields: generalInvalidFields,
|
||||||
|
}),
|
||||||
|
PaginateMiddleware.middleware(),
|
||||||
|
SortMiddleware.middleware({ default: "init_available_date" }),
|
||||||
|
(req, res, next) => {
|
||||||
|
const isLogged = req.user && req.user.id;
|
||||||
|
const scopes = ["defaultScope", "next", "includeVenue", "includeMultimedias"];
|
||||||
|
if (isLogged) {
|
||||||
|
scopes.push({ method: ["includeInscription", req.user.id] });
|
||||||
|
}
|
||||||
|
return eventController.findNextEventsByCountry({ scopes })(req, res, next);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
routes.get(
|
routes.get(
|
||||||
"/events/past",
|
"/events/past",
|
||||||
isOptionalUser,
|
isOptionalUser,
|
||||||
@ -274,7 +293,7 @@ routes.get(
|
|||||||
eventInscriptionController.getInscription
|
eventInscriptionController.getInscription
|
||||||
);
|
);
|
||||||
|
|
||||||
// Hacer una inscripción
|
// Hacer una inscripción
|
||||||
routes.post(
|
routes.post(
|
||||||
"/events/:id/inscriptions",
|
"/events/:id/inscriptions",
|
||||||
isLoggedUser,
|
isLoggedUser,
|
||||||
@ -285,7 +304,7 @@ routes.post(
|
|||||||
eventReservationController.recuperateReservationByCode,
|
eventReservationController.recuperateReservationByCode,
|
||||||
//Recupera a registra el usuario que se va a inscribir
|
//Recupera a registra el usuario que se va a inscribir
|
||||||
authController.getOrCreateUser,
|
authController.getOrCreateUser,
|
||||||
//Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
|
//Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
|
||||||
//si no es así es el caso de un usuario que se reinscribe con otro código de reserva
|
//si no es así es el caso de un usuario que se reinscribe con otro código de reserva
|
||||||
eventInscriptionController.checkInscriptionByUser,
|
eventInscriptionController.checkInscriptionByUser,
|
||||||
//Si es un usuario tutor y solicita un group_size se crea la reserva
|
//Si es un usuario tutor y solicita un group_size se crea la reserva
|
||||||
@ -357,7 +376,7 @@ routes.post(
|
|||||||
eventReservationController.recuperateReservationByCode,
|
eventReservationController.recuperateReservationByCode,
|
||||||
//Recupera a registra el usuario que se va a inscribir
|
//Recupera a registra el usuario que se va a inscribir
|
||||||
authController.getOrCreateUser,
|
authController.getOrCreateUser,
|
||||||
//Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
|
//Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
|
||||||
//si no es así es el caso de un usuario que se reinscribe con otro código de reserva
|
//si no es así es el caso de un usuario que se reinscribe con otro código de reserva
|
||||||
eventInscriptionController.checkInscriptionByUser,
|
eventInscriptionController.checkInscriptionByUser,
|
||||||
//Al ser via web siempre será inscripción con codigo de reserva
|
//Al ser via web siempre será inscripción con codigo de reserva
|
||||||
@ -535,8 +554,8 @@ routes.put(
|
|||||||
"/admin/reservations/:id",
|
"/admin/reservations/:id",
|
||||||
isAdministratorUser,
|
isAdministratorUser,
|
||||||
//SchemaValidator(eventValidation.ReservationInputType, true),
|
//SchemaValidator(eventValidation.ReservationInputType, true),
|
||||||
eventReservationController.checkAssitantsUpdate,
|
eventReservationController.checkAssitantsUpdate,
|
||||||
eventReservationController.update()
|
eventReservationController.update()
|
||||||
);
|
);
|
||||||
|
|
||||||
routes.put(
|
routes.put(
|
||||||
|
|||||||
@ -46,9 +46,10 @@ async function activeReservation(reservation) {
|
|||||||
}
|
}
|
||||||
reservation.state = "publish";
|
reservation.state = "publish";
|
||||||
|
|
||||||
//Finalmente hay que validar la inscripción del tutor
|
//Finalmente hay que validar la inscripción del tutor en el caso de aquellos centros que no son aliados
|
||||||
if ((await eventInscriptionService._validateInscriptionTutorOfReservation(reservation.id, reservation.userId)) <= 0) {
|
if ((await eventInscriptionService._validateInscriptionTutorOfReservation(reservation.id, reservation.userId)) <= 0) {
|
||||||
console.log("No se ha podido validar la inscripción del tutor por ser de un centro aliado se hace a posteriori en este caso");
|
//En el caso de ser un centro aliado no se puede validar la inscripcion ya que se hace a posteriori por lo tanto no se hace nada
|
||||||
|
// console.log("No se ha podido validar la inscripción del tutor por ser de un centro aliado se hace a posteriori en este caso");
|
||||||
// return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,93 +1,109 @@
|
|||||||
const Sequelize = require('sequelize');
|
const Sequelize = require("sequelize");
|
||||||
|
|
||||||
module.exports = function (sequelize, DataTypes) {
|
module.exports = function (sequelize, DataTypes) {
|
||||||
const Location = sequelize.define('Location', {
|
const Location = sequelize.define(
|
||||||
id: {
|
"Location",
|
||||||
type: DataTypes.UUID,
|
{
|
||||||
defaultValue: DataTypes.UUIDV4,
|
id: {
|
||||||
primaryKey: true,
|
type: DataTypes.UUID,
|
||||||
|
defaultValue: DataTypes.UUIDV4,
|
||||||
|
primaryKey: true,
|
||||||
|
},
|
||||||
|
country: {
|
||||||
|
type: DataTypes.STRING(125),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
city: {
|
||||||
|
type: DataTypes.STRING(125),
|
||||||
|
allowNull: false,
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
},
|
||||||
|
country_code: {
|
||||||
|
type: DataTypes.STRING(2),
|
||||||
|
default: "ES",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tableName: "locations",
|
||||||
|
freezeTableName: true,
|
||||||
|
timestamps: true,
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
unique: true,
|
||||||
|
fields: ["country", "city"],
|
||||||
},
|
},
|
||||||
country: {
|
{
|
||||||
type: DataTypes.STRING(125),
|
unique: false,
|
||||||
allowNull: false,
|
fields: ["country_code"],
|
||||||
},
|
},
|
||||||
city: {
|
],
|
||||||
type: DataTypes.STRING(125),
|
}
|
||||||
allowNull: false,
|
);
|
||||||
},
|
|
||||||
description: {
|
Location.associate = function (models) {
|
||||||
type: DataTypes.STRING,
|
Location.Events = Location.hasMany(models.Event, { as: "events", foreignKey: "locationId" });
|
||||||
},
|
|
||||||
}, {
|
//OJO antes de force comentar
|
||||||
tableName: 'locations',
|
// 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
|
||||||
freezeTableName: true,
|
Location.Multimedias = Location.hasMany(models.Multimedia, {
|
||||||
timestamps: true,
|
foreignKey: "entityId",
|
||||||
indexes: [{
|
as: { singular: "multimedia", plural: "multimedias" },
|
||||||
unique: true,
|
|
||||||
fields: ['country', 'city']
|
|
||||||
}]
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
Location.associate = function (models) {
|
Location.addScope("includeMultimedias", () => {
|
||||||
Location.Events = Location.hasMany(models.Event, {as: 'events', foreignKey: 'locationId'});
|
return {
|
||||||
|
include: [
|
||||||
//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
|
model: sequelize.models.Multimedia,
|
||||||
Location.Multimedias = Location.hasMany(models.Multimedia, {
|
as: { singular: "multimedia", plural: "multimedias" },
|
||||||
foreignKey: 'entityId',
|
required: false,
|
||||||
as: { singular: 'multimedia', plural: 'multimedias' },
|
include: [
|
||||||
});
|
{
|
||||||
|
model: sequelize.models.MultimediaFile,
|
||||||
|
as: "multimediaFile",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
});
|
||||||
|
|
||||||
Location.addScope('includeMultimedias', () => {
|
Location.addScope("includeEvents", () => {
|
||||||
return {
|
return {
|
||||||
include: [{
|
include: [
|
||||||
model: sequelize.models.Multimedia,
|
{
|
||||||
as: { singular: 'multimedia', plural: 'multimedias' },
|
model: sequelize.models.Event,
|
||||||
required: false,
|
as: "events",
|
||||||
include: [{
|
required: false,
|
||||||
model: sequelize.models.MultimediaFile,
|
// group: ['typeId'],
|
||||||
as: "multimediaFile"
|
// attributes: ['name', 'type.title',] //[sequelize.fn('COUNT', sequelize.col('events.typeId')), 'ediciones'],] // [sequelize.fn('SUM', sequelize.col('Event.assistants')), 'assistants']]
|
||||||
}]
|
// attributes: [[sequelize.fn('COUNT', sequelize.col('typeId')), 'ediciones'],] // [sequelize.fn('SUM', sequelize.col('Event.assistants')), 'assistants']]
|
||||||
},
|
// include: [{
|
||||||
]
|
// model: sequelize.models.MultimediaFile,
|
||||||
}
|
// as: "multimediaFile"
|
||||||
});
|
// }]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
Location.addScope("includeGroupEvents", () => {
|
||||||
|
return {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
as: "events",
|
||||||
|
required: false,
|
||||||
|
// include: [{
|
||||||
|
// model: sequelize.models.MultimediaFile,
|
||||||
|
// as: "multimediaFile"
|
||||||
|
// }]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
Location.addScope('includeEvents', () => {
|
return Location;
|
||||||
return {
|
};
|
||||||
include: [{
|
|
||||||
model: sequelize.models.Event,
|
|
||||||
as: 'events',
|
|
||||||
required: false,
|
|
||||||
// group: ['typeId'],
|
|
||||||
// attributes: ['name', 'type.title',] //[sequelize.fn('COUNT', sequelize.col('events.typeId')), 'ediciones'],] // [sequelize.fn('SUM', sequelize.col('Event.assistants')), 'assistants']]
|
|
||||||
// attributes: [[sequelize.fn('COUNT', sequelize.col('typeId')), 'ediciones'],] // [sequelize.fn('SUM', sequelize.col('Event.assistants')), 'assistants']]
|
|
||||||
// include: [{
|
|
||||||
// model: sequelize.models.MultimediaFile,
|
|
||||||
// as: "multimediaFile"
|
|
||||||
// }]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Location.addScope('includeGroupEvents', () => {
|
|
||||||
return {
|
|
||||||
include: [{
|
|
||||||
|
|
||||||
as: 'events',
|
|
||||||
required: false,
|
|
||||||
// include: [{
|
|
||||||
// model: sequelize.models.MultimediaFile,
|
|
||||||
// as: "multimediaFile"
|
|
||||||
// }]
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
return Location;
|
|
||||||
};
|
|
||||||
|
|||||||
@ -118,7 +118,7 @@ const extraControllers = {
|
|||||||
* "segment": "ALL" | "ALL_VALIDATED" | "ALL_NOT_VALIDATED" |
|
* "segment": "ALL" | "ALL_VALIDATED" | "ALL_NOT_VALIDATED" |
|
||||||
* "PARTNERS_ALL" | "PARTNERS_VALIDATED" | "PARTNERS_NOT_VALIDATED" |
|
* "PARTNERS_ALL" | "PARTNERS_VALIDATED" | "PARTNERS_NOT_VALIDATED" |
|
||||||
* "COLLEGE_ALL" | "COLLEGE_VALIDATED" | "COLLEGE_NOT_VALIDATED"
|
* "COLLEGE_ALL" | "COLLEGE_VALIDATED" | "COLLEGE_NOT_VALIDATED"
|
||||||
* OPCION 3 - A todos los dispositivos activos
|
* OPCION 3 - A todos los dispositivos activos de un país
|
||||||
* "deviceIds": ["*" | "ExponentPushToken[YbOS1AIZjQbchZbxNaVRqC]", ...]
|
* "deviceIds": ["*" | "ExponentPushToken[YbOS1AIZjQbchZbxNaVRqC]", ...]
|
||||||
* "country": "*" | "ES" | "MX"
|
* "country": "*" | "ES" | "MX"
|
||||||
* },
|
* },
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lqdvi-api3",
|
"name": "lqdvi-api3",
|
||||||
"version": "1.4.1",
|
"version": "1.4.4",
|
||||||
"description": "",
|
"description": "",
|
||||||
"author": "Rodax Software",
|
"author": "Rodax Software",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user