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} /api/v4/web/events Obtener Eventos Disponibles (GetAvailableEvents) * @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"]; const scopes = ["defaultScope", "withSevilla"]; 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 (GetEventDetails) * @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 (CheckEventCapacity) * @apiName CheckEventCapacity * @apiGroup Eventos * @apiVersion 4.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=10] Tamaño del grupo para el cual se verifica el aforo (Parámetro de consulta). * * @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/reservations/code/:encodedCode Recupera la reserva asociada al Código de Invitación (GetReservationFromCode) * @apiName GetReservationFromCode * @apiGroup Eventos * @apiVersion 4.0.0 * @apiDescription Este endpoint verifica un código de reserva devolviendo al evento y entidad a la que pertenece. El código de invitación está codificado en Base64. * * @apiParam {String} encodedCode Código de invitación codificado en Base64. Ejemplo, el código "MD22-4939" se codifica como "TUQyMi00OTM5" * * @apiSuccess {String} id indica si el Id de la reserva. * @apiSuccess {String} stateText indica la situación de la reserva. * @apiSuccess {String} code el código de la reserva sin codificar. * @apiSuccess {String} eventId indica el id del evento al que pertenece la reserva. * @apiSuccess {String} eventName indica el nombre del evento al que pertenece la reserva. * @apiSuccess {String} entityId indica el id de la entidad a la que pertenece la reserva. * @apiSuccess {String} entityName indica el nombre de la entidad a la que pertenece la reserva. * * @apiError (Error 404) NotFound Código de reserva no encontrado. * * @apiErrorExample {json} Ejemplo de Respuesta Fallida: * HTTP/1.1 404 Not Found * { * "message": "Código de reserva no encontrado" * } * @apiSuccessExample {json} Ejemplo de Respuesta Exitosa: * HTTP/1.1 200 OK * { * "id": "d8af01cf-b86d-4e10-9c84-442cd31a7fb8", * "stateText": "Inscripciones abiertas a la reserva", * "code": "MAD24DEF218", * "eventId": "84613446-765a-11ef-9b46-000c29a89113", * "eventName": "Madrid 2024 - 18ª Edición", * "entityId": "a015dcef-8213-11ee-9b36-000c29a89113", * "entityName": "Alianza para la FP Dual - Barcelona" * } */ routes.get( "/web/reservations/code/:code", isAPIKeyUser, FieldMiddleware.middleware({ invalidFields: generalInvalidFields, }), (req, res, next) => { res.locals.v4 = { removeFields: [ "assistanceType", "assistanceTypeText", "state", ], }; return eventReservationController.getReservationFromCode(req, res, next); } ); /** * @api {get} /api/v4/web/events/:eventId/reservations/:encodedCode Verificar Código de Invitación (CheckInvitationCode) * @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 (CreateEventInscription) * @apiName CreateEventInscription * @apiGroup Inscriptions * @apiVersion 4.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 - Si viene código. * @apiBody {String} email Email del participante, debe ser válido. * @apiBody {String} name Nombre del participante. * @apiBody {String} Apellido del participante. * @apiBody {String} profile Tipo de participante (student/tutor/guest/free). * @apiBody {String} country País del participante (ES/MX). * @apiBody {String} [entityId] Entidad del participante - Opcional - solo si son student/tutor/guest.* * @apiBody {number} [group_size] Cantidad participantes a solicitar - Opcional - solo si son tutores.* * * * @apiSuccess {String} id ID de la inscripción. * @apiSuccess {String} stateText Estado de la inscripción. * @apiSuccess {String} type Tipo de asistencia. * @apiSuccess {String} code_ticket Código del ticket generado. * @apiSuccess {Boolean} validated Estado de validación de la inscripción. * * @apiSuccessExample {json} Ejemplo de Respuesta 1: * ENVIO * { * "code" : "B24URD397", * "email" : "rbrrbr2005@gmail.com", * "name" : "aaa", * "surname" : "a", * "profile": "student", * "country": "ES", * } * RESPUESTA * { * "id": "003fb9ae-a8e7-41dc-802b-15dc0e1d4702", * "stateText": "Inscripción confirmada", * "type": "onsite group", * "code_ticket": "ENT-02220012", * "validated": true * } * * @apiSuccessExample {json} Ejemplo de Respuesta 2: * ENVIO * { * "code" : "BIL24-DEF219", - Reserva en lista de espera * "email" : "rbrrbr20067@gmail.com", * "name" : "aaa", * "surname" : "a", * "profile": "studient", * } * RESPUESTA * { * "id": "002610be-96bb-4f56-91fc-c181d354beeb", * "stateText": "Reserva pendiente de confirmaci\xF3n", * "type": "onsite group", * "code_ticket": "ENT-60030638", * "validated": false * } * * @apiSuccessExample {json} Ejemplo de Respuesta 3: Profesor solicita una reserva grupal * ENVIO * { * "code" : "", * "email" : "rbrrbr20167@gmail.com", * "name" : "aaa", * "surname" : "a", * "profile": "tutor", * "country": "ES", * "entityId": "757e6018-af85-11e9-aa90-000c295f0f58", * "group_size": 5 * } * RESPUESTA * { "id": "00011602-8345-46e6-8c2a-7a54214cf526", * "stateText": "Reserva pendiente de confirmaci\xF3n", * "type": "onsite group", * "code_ticket": "ENT-19161191", * "validated": false * } */ 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) => { res.locals.v4 = { removeFields: [ "reservation", "eventId", "date", "userId", "source", "reservationId", "overflowEventId", "updatedAt", "createdAt", ], }; 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/events/:id/inscriptions/:email Comprobar Inscripción (CheckInscription) * @apiName CheckInscription * @apiGroup Inscriptions * @apiVersion 4.0.0 * @apiDescription Este endpoint verifica si el correo electrónico proporcionado tiene una inscripción para el evento concreto. * * @apiParam {String} id Identificador único del evento. * @apiParam {String} email Correo electrónico a comprobar. * * @apiSuccess {String} message Mensaje que indica el estado de la inscripción. * @apiSuccessExample {json} Ejemplo de Respuesta Exitosa: * HTTP/1.1 200 OK * { * "message": "Inscripción confirmada" * } * * @apiError (Error 404) NotFound No hay inscripción con el correo electrónico proporcionado. * @apiErrorExample {json} Ejemplo de Respuesta Fallida: * HTTP/1.1 404 Not Found * { * "message": "No hay inscripción con ese email" * } */ // Comprobar si estoy inscrito al congreso por la web routes.get("/web/events/:id/inscriptions/:email", isAPIKeyUser, eventInscriptionController.checkInscriptionByMail); /** * @api {get} /api/v4/web/inscriptions/:id Obtener datos de la Inscripción (GetInscription) * @apiName GetInscription * @apiGroup Inscriptions * @apiVersion 4.0.0 * @apiDescription Este endpoint devuelve la inscripción correspondiente al id proporcionado. * * @apiParam {String} id Identificador único de la inscripcion. * * @apiSuccess {String} message datos de la inscripción. * @apiSuccessExample {json} Ejemplo de Respuesta Exitosa: * HTTP/1.1 200 OK * { * "id": "4043a096-f598-4dba-b34e-ac96fdbd1b0a", * "stateText": "Inscripción confirmada", * "code_ticket": "ENT-87491914", * "eventName": "Bilbao 2024 - XVI Edición", * "userName": "aaa", * "userSurname": "a" * } * * @apiError (Error 404) NotFound No hay inscripción con el id proporcionado. * @apiErrorExample {json} Ejemplo de Respuesta Fallida: * HTTP/1.1 404 Not Found * { * "message": "Inscripción no encontrada" * } */ // Esto da la inscripción de un usuario routes.get("/web/inscriptions/:id", isAPIKeyUser, FieldMiddleware.middleware({ }), (req, res, next) => { res.locals.v4 = { removeFields: [ "code_ticket_qr", ], }; return eventInscriptionController.getInscription(req, res, next); } ); /** * * @api {delete} /api/v4/web/inscriptions/:id Eliminar inscripcion (DeleteInscription) * @apiName DeleteInscription * @apiGroup Inscriptions * @apiVersion 4.0.0 * @apiDescription Este endpoint elimina inscripción. * * @apiParam {String} id Identificador único de la inscripcion. * * @apiSuccess {String} message Mensaje que indica resultado. * @apiSuccessExample {json} Ejemplo de Respuesta Exitosa: * HTTP/1.1 200 OK * { * "message": "Inscripción eliminada" * } * * @apiError (Error 404) NotFound Error al eliminar inscripción. * @apiErrorExample {json} Ejemplo de Respuesta Fallida: * HTTP/1.1 404 Not Found * { * "message": "Error al eliminar inscripción" * } */ // Borrar una inscripción routes.delete("/web/inscriptions/:id", isAPIKeyUser, eventInscriptionController.deleteInscription); /** * @api {get} /api/v4/web/entities/colleges Lista de Entidades Educativas (GetColleges) * @apiName GetColleges * @apiGroup Entidades * @apiVersion 4.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 (GetPartners) * @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;