const { isAPIKeyUser } = require("../../middlewares/accessValidator"); const routes = require("express").Router(); const SchemaValidator = require("../../middlewares/schemaValidator"); const FieldMiddleware = require("../../middlewares/fields"); const authController = require("../auth/auth.controller"); const eventController = require("./event.controller"); const eventInscriptionController = require("./events_inscriptions.controller"); const eventReservationController = require("./events_reservations.controller"); const eventValidation = require("./event.validations"); const { cacheSuccesses } = require("../../middlewares/cache"); const SortMiddleware = require("../../middlewares/sort"); const entityController = require("../entities/entity.controller"); const generalInvalidFields = [ "userId", "createdAt", "updatedAt", "assistants", "confirmed", "allow_multiple", "overflow_eventId", "state", "confirmed", "multiple_limit", "marketing_list", "state", "contact_person", "contact_email", "createdAt", "updatedAt", "gmt", "url_streaming", "url_poll", "url_registration", "featured", "virtual", "allow_questions", "assistanceType", "assistanceTypeText", "allow_overflow", "typeId", "venueId", "locationId", "sold_out", "level", ]; const eventDetailsFields = [ "id", "name", "description", "stateCode", "stateText", "campaign_text", "init_date", "end_date", ]; /** * @api {get} /web/events Obtener Eventos Disponibles * @apiName GetAvailableEvents * @apiGroup Eventos * @apiVersion 4.0.0 * @apiDescription Este endpoint devuelve una lista de eventos disponibles, incluyendo su estado de aforo. * * @apiSuccess {Object[]} events Lista de eventos disponibles. * @apiSuccess {String} events.id Identificador único del evento. * @apiSuccess {String} events.name Nombre del evento. * @apiSuccess {Object} events.location Ubicación del evento. * @apiSuccess {String} events.location.country País donde se realiza el evento. * @apiSuccess {String} events.location.city Ciudad donde se realiza el evento. * @apiSuccess {String} events.location.country_code Código del país del evento. * * @apiSuccessExample {json} Ejemplo de Respuesta: * [ * { * "id": "03f70b2d-53c5-11ed-9b36-000c29a89113", * "name": "Madrid 2022 - 16ª Edición", * "location": { * "country": "España", * "city": "Madrid", * "country_code": "ES" * }, * }, * { * "id": "b518e0f7-b2d1-11ed-9477-000c29e7c50f", * "name": "Sevilla 2023 - 22ª Edición", * "location": { * "country": "España", * "city": "Sevilla", * "country_code": "ES" * }, * } * ] */ routes.get( "/web/events/", isAPIKeyUser, FieldMiddleware.middleware({ validFields: ["id", "name"], }), (req, res, next) => { const scopes = ["defaultScope", "withOpenInscriptions"]; res.locals.v4 = {removeFields : ["partners", "speakers", "details", "multimedias", "type"]}; return eventController.find({ scopes })(req,res,next); } ); /** * @api {get} /api/v4/web/events/:eventId Obtener Datos del Evento * @apiName GetEventDetails * @apiGroup Eventos * @apiVersion 4.0.0 * @apiDescription Este endpoint devuelve los detalles de un evento específico. * * @apiParam {String} eventId Identificador único del evento. * * @apiSuccess {String} stateCode Código del estado del evento. * @apiSuccess {String} stateText Descripción del estado del evento. * @apiSuccess {String} id Identificador único del evento. * @apiSuccess {String} name Nombre del evento. * @apiSuccess {String} description Descripción del evento. * @apiSuccess {String} campaign_text Texto de campaña (si aplica). * @apiSuccess {String} init_date Fecha y hora de inicio del evento (ISO 8601). * @apiSuccess {String} end_date Fecha y hora de finalización del evento (ISO 8601). * @apiSuccess {Object} location Ubicación del evento. * @apiSuccess {String} location.country País donde se realiza el evento. * @apiSuccess {String} location.city Ciudad donde se realiza el evento. * @apiSuccess {String} location.country_code Código del país del evento. * * @apiSuccessExample {json} Ejemplo de Respuesta: * { * "stateCode": "registrations_open", * "stateText": "Inscripciones abiertas", * "id": "03f70b2d-53c5-11ed-9b36-000c29a89113", * "name": "Madrid 2022 - 16ª Edición", * "description": "Palacio Municipal de Congresos de Madrid, Campo de las Naciones, Avenida de la Capital de España s/n\n\nENTREGA PREMIO ALGO+Q1 CANCIÓN", * "campaign_text": "", * "init_date": "2024-08-29T00:00:00.000Z", * "end_date": "2024-12-01T14:30:00.000Z", * "location": { * "country": "España", * "city": "Madrid", * "country_code": "ES" * }, * } */ routes.get( "/web/events/:id", isAPIKeyUser, FieldMiddleware.middleware({ validFields: eventDetailsFields, invalidFields: generalInvalidFields, }), (req, res, next) => { const scopes = ["defaultScope"]; res.locals.v4 = {removeFields : ["partners", "speakers", "details", "multimedias", "type", "sold_out", "init_available_date", "end_available_date"]}; return eventController.findOne({ scopes })(req, res, next); } ); /** * @api {get} /api/v4/web/events/:id/check_capacity?group_size=xx Verificar Capacidad del Evento * @apiName CheckEventCapacity * @apiGroup Eventos * @apiVersion 1.0.0 * @apiDescription Determina si hay aforo suficiente para el tamaño de grupo que se ha indicado. * * @apiParam {String} id ID único del evento. * @apiParam {Number} group_size número de entradas solicitadas para evento el evento. * * @apiSuccess {String} eventId ID único del evento. * @apiSuccess {Number} group_size Tamaño del grupo para el cual se verifica el aforo. * @apiSuccess {Boolean} allow Indica si el grupo puede inscribirse al evento. * @apiSuccess {Boolean} allow_overflow Indica si el grupo puede inscribirse a la lista de espera del evento. * * @apiSuccessExample {json} Ejemplo de Respuesta: * HTTP/1.1 200 OK * { * "eventId": "03f70b2d-53c5-11ed-9b36-000c29a89113", * "group_size": 1, * "allow": true * "allow_overflow": true * } */ routes.get("/web/events/:id/check_capacity", isAPIKeyUser, FieldMiddleware.middleware({ invalidFields: generalInvalidFields, }), (req, res, next) => { res.locals.v4 = {removeFields : ["assistants", "confirmed", "sold_out", "assistants_overflow", "confirmed_overflow", "sold_out_overflow"]}; return eventController.checkCapacity(req, res, next); } ); /** * @api {get} /api/v4/web/events/:eventId/reservations/:encodedCode Verificar Código de Invitación * @apiName CheckInvitationCode * @apiGroup Eventos * @apiVersion 4.0.0 * @apiDescription Este endpoint verifica si un código de invitación es aplicable a un evento concreto. El código de invitación está codificado en Base64. * * @apiParam {String} eventId Identificador único del evento. * @apiParam {String} encodedCode Código de invitación codificado en Base64. Ejemplo, el código "MD22-4939" se codifica como "TUQyMi00OTM5" * * @apiSuccess {Boolean} applicable Indica si el código de invitación es aplicable (true) o no (false). * * @apiSuccessExample {json} Ejemplo de Respuesta Exitosa: * HTTP/1.1 200 OK * true * * @apiSuccessExample {json} Ejemplo de Respuesta Fallida: * HTTP/1.1 200 OK * false */ routes.get( "/web/events/:id/reservations/:encodedInvitationCode", isAPIKeyUser, eventReservationController.checkReservationCode ); /** * @api {post} /api/v4/web/events/:eventId/inscriptions/ Dar de Alta una Inscripción * @apiName CreateEventInscription * @apiGroup Inscriptions * @apiVersion 1.0.0 * @apiDescription Este endpoint permite registrar una inscripción a un evento específico. * * @apiParam {String} eventId Identificador único del evento. * * @apiBody {String} code Código opcional para la inscripción. * @apiBody {String} email Email del participante, debe ser válido. * @apiBody {String} name Nombre del participante. * @apiBody {String} [surname] Apellido del participante (opcional). * * * @apiSuccess {String} stateText Estado de la inscripción. * @apiSuccess {String} id Identificador único de la inscripción. * @apiSuccess {String} eventId Identificador único del evento. * @apiSuccess {Date} date Fecha de la inscripción. * @apiSuccess {String} userId Identificador único del usuario. * @apiSuccess {String} type Tipo de asistencia. * @apiSuccess {String} code_ticket Código del ticket generado. * @apiSuccess {String} source Fuente de la inscripción (ej. "app"). * @apiSuccess {Boolean} validated Estado de validación de la inscripción. * @apiSuccess {String} [reservationId] Identificador de la reserva si existe. * @apiSuccess {String} [overflowEventId] Identificador del evento de desborde si existe. * @apiSuccess {Date} updatedAt Fecha de la última actualización. * @apiSuccess {Date} createdAt Fecha de creación. * * @apiSuccessExample {json} Ejemplo de Respuesta 1: * { * "stateText": "Inscripción confirmada", * "id": "156e4aa1-cada-4e42-bdca-b458b798991c", * "eventId": "3028d48b-1f38-11ef-9b46-000c29a89113", * "date": "2024-07-02T09:30:07.973Z", * "userId": "6747d9eb-c64f-43a3-a4ac-6803b89966cb", * "type": "onsite", * "code_ticket": "ENT-77760177", * "source": "app", * "validated": true, * "reservationId": null, * "overflowEventId": null, * "updatedAt": "2024-07-02T09:30:07.974Z", * "createdAt": "2024-07-02T09:30:07.974Z" * } * * @apiSuccessExample {json} Ejemplo de Respuesta 2: * { * "reservation": { * "assistanceType": "onsite", * "assistanceTypeText": "asistencia presencial", * "stateText": "Inscripciones abiertas a la reserva", * "id": "b996c360-616d-46d4-856f-4dc0449b74f8", * "init_available_date": "2024-06-03T15:00:00.000Z", * "end_available_date": "2024-10-08T20:00:00.000Z", * "gmt": -5, * "state": "publish", * "assistants": 10, * "confirmed": 1, * "sold_out": false, * "allow_multiple": false, * "multiple_limit": 0, * "description": "Reserva", * "reservation_code": "TOL24-CIE339", * "color": "orange", * "allow_overflow": false, * "overflow_reservationId": null, * "marketing_list": null, * "virtual": false, * "createdAt": "2024-07-02T09:39:38.000Z", * "updatedAt": "2024-07-02T09:40:07.000Z", * "userId": "d3eba5de-76cd-44a0-9ebd-92cad7160e71", * "entityId": "9c910423-596b-11ea-bdd2-000c29a89113", * "eventId": "3028d48b-1f38-11ef-9b46-000c29a89113", * "Event": { * "stateCode": "registrations_open", * "stateText": "Inscripciones abiertas", * "assistanceType": "onsite", * "assistanceTypeText": "evento presencial", * "id": "3028d48b-1f38-11ef-9b46-000c29a89113", * "name": "Toluca 2024 - Teen - 6ª Edición", * "description": null, * "campaign_text": null, * "init_date": "2024-10-09T15:00:00.000Z", * "end_date": "2024-10-09T19:00:00.000Z", * "init_available_date": "2024-06-03T15:00:00.000Z", * "end_available_date": "2024-10-08T20:00:00.000Z", * "gmt": -5, * "assistants": 620, * "confirmed": 1, * "sold_out": false, * "allow_multiple": false, * "multiple_limit": null, * "allow_overflow": true, * "overflow_eventId": "36a1aed0-1f39-11ef-9b46-000c29a89113", * "state": "publish", * "typeId": "0", * "venueId": "2481e357-1dfb-4ab7-ba2b-5094620e0281", * "locationId": "df971e1c-c8de-11e9-b18d-000c295f0f58", * "url_streaming": null, * "url_poll": null, * "url_registration": null, * "marketing_list": null, * "userId": "0939bb2a-d33d-4290-ac81-fc9faa1c015e", * "featured": false, * "virtual": false, * "allow_questions": true, * "createdAt": "2024-05-31T12:26:05.000Z", * "updatedAt": "2024-07-02T09:40:07.000Z", * "type": { * "name": "conference", * "title": "Congreso LQDVI" * }, * "location": { * "country": "México", * "city": "Toluca", * "country_code": "MX" * } * }, * "Entity": { * "id": "9c910423-596b-11ea-bdd2-000c29a89113", * "name": "CIEMA A Coruña", * "state": "publish", * "contact_person": null, * "contact_email": null, * "level": null, * "country": "ES", * "createdAt": "2020-02-27T15:15:31.000Z", * "updatedAt": "2020-02-27T15:15:31.000Z" * } * }, * "stateText": "Inscripción confirmada", * "id": "2168615f-69b3-4045-a173-5b70f5ebfd1d", * "eventId": "3028d48b-1f38-11ef-9b46-000c29a89113", * "date": "2024-07-02T09:42:34.846Z", * "userId": "6747d9eb-c64f-43a3-a4ac-6803b89966cb", * "type": "onsite group", * "code_ticket": "ENT-31846388", * "source": "app", * "validated": true, * "reservationId": "b996c360-616d-46d4-856f-4dc0449b74f8", * "overflowEventId": null, * "updatedAt": "2024-07-02T09:42:34.847Z", * "createdAt": "2024-07-02T09:42:34.847Z" * } * * @apiSuccessExample {json} Ejemplo de Respuesta 3: * { * "stateText": "Inscripción confirmada a lista de espera", * "id": "9c6548df-37d8-46c1-8505-3de9e620fab1", * "eventId": "3028d48b-1f38-11ef-9b46-000c29a89113", * "date": "2024-07-02T09:32:45.727Z", * "userId": "6747d9eb-c64f-43a3-a4ac-6803b89966cb", * "type": "onsite", * "code_ticket": "ENT-26677167", * "source": "app", * "validated": false, * "reservationId": null, * "overflowEventId": "36a1aed0-1f39-11ef-9b46-000c29a89113", * "updatedAt": "2024-07-02T09:32:45.728Z", * "createdAt": "2024-07-02T09:32:45.728Z" * } */ routes.post( "/web/events/:id/inscriptions", isAPIKeyUser, SchemaValidator(eventValidation.webv4InscriptionInputType, true), //Prepara los datos de la inscripción tipo .... eventInscriptionController.prepareDataInscription, //Recupera la reservation si viene eventReservationController.recuperateReservationByCode, //Recupera a registra el usuario que se va a inscribir authController.getOrCreateUser, //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 eventInscriptionController.checkInscriptionByUser, //Si es un usuario tutor y solicita un group_size se crea la reserva eventReservationController.createReservationToEntity, eventReservationController.activeReservationToEntity, (req, res, next) => { if (res.locals.dataInscription.reservation) { console.log(">>>>>>>Incripcion con reserva"); eventReservationController.createInscriptionReservation(req, res, next); } else { console.log(">>>>>>>Incripcion sin reserva"); eventInscriptionController.createInscription(req, res, next); } //next(); } // eventInscriptionController.createInscriptionMarketingList ); /** * @api {get} /api/v4/web/entities/colleges Lista de Entidades Educativas * @apiName GetColleges * @apiGroup Entidades * @apiVersion 1.0.0 * @apiDescription Este endpoint devuelve una lista de entidades educativas, incluyendo su nombre, nivel y país. * * @apiSuccess {Object[]} colleges Lista de entidades educativas. * @apiSuccess {String} colleges.id Identificador único de la entidad educativa. * @apiSuccess {String} colleges.name Nombre de la entidad educativa. * @apiSuccess {String} colleges.country Código de país de la entidad educativa. * * @apiSuccessExample {json} Ejemplo de Respuesta: * [ * { * "id": "757de756-af85-11e9-aa90-001c295f0f58", * "name": "Academia Santa Teresa Málaga", * "country": "ES" * }, * { * "id": "7583028a-af85-11e9-aa90-000c395f0f58", * "name": "Academia Díaz Balaguer", * "country": "ES" * }, * { * "id": "758196a7-af85-11e9-aa90-000c294f0f58", * "name": "Agora Portals International School - Islas Baleares", * "country": "ES" * }, * ] */ routes.get( "/web/entities/colleges", isAPIKeyUser, //cacheSuccesses("24 hours"), FieldMiddleware.middleware({ invalidFields: generalInvalidFields, }), SortMiddleware.middleware({ default: "name" }), entityController.find({ scopes: ["defaultScope", "onlyColleges"], }) ); /** * @api {get} /api/v4/web/entities/partners Lista de Partners * @apiName GetPartners * @apiGroup Partners * @apiVersion 4.0.0 * @apiDescription Este endpoint devuelve una lista de partners disponibles, incluyendo su nombre, nivel y país. * * @apiSuccess {Object[]} partners Lista de partners disponibles. * @apiSuccess {String} partners.id Identificador único del partner. * @apiSuccess {String} partners.name Nombre del partner. * @apiSuccess {String} partners.country Código del país del partner. * * @apiSuccessExample {json} Ejemplo de Respuesta: * [ * { "id": "7dfc4513-ce5b-11e9-8055-000c29a89613", "name": "ABC", "country": "ES" }, { "id": "3c7950ac-48b4-11ee-9b36-000c29a59113", "name": "AECC", "country": "ES" }, { "id": "2b43d32b-d4d1-11e9-8055-000c29a69113", "name": "AGR FOOD MARKETING", "country": "ES" }, { "id": "6c2df93f-af83-11e9-aa90-000c29ef0f58", "name": "CAIXABANK", "country": "ES" }, * ... * ] */ routes.get( "/web/entities/partners", isAPIKeyUser, //cacheSuccesses("24 hours"), FieldMiddleware.middleware({ invalidFields: generalInvalidFields, }), SortMiddleware.middleware({ default: "name" }), entityController.find({ scopes: ["defaultScope", "onlyPartners"], }) ); module.exports = routes;