From 7923896dab94ef66a612078aca0509fd9394c40a Mon Sep 17 00:00:00 2001 From: David Date: Tue, 7 Jun 2022 10:33:00 +0200 Subject: [PATCH] =?UTF-8?q?.Repsaso=20de=20activar=20una=20reserva=20autom?= =?UTF-8?q?=C3=A1tica=20de=20cole?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- helpers/mail.helper.js | 42 ++++-- modules/events/event.controller.js | 7 +- modules/events/events_inscriptions.service.js | 18 +++ .../events_inscriptions_online.model.js | 72 +++++++++ .../events/events_reservations.controller.js | 141 ++++++++---------- modules/events/mail.service.js | 101 +++++++------ 6 files changed, 244 insertions(+), 137 deletions(-) create mode 100644 modules/events/events_inscriptions_online.model.js diff --git a/helpers/mail.helper.js b/helpers/mail.helper.js index 44838d0..3462b96 100644 --- a/helpers/mail.helper.js +++ b/helpers/mail.helper.js @@ -34,13 +34,13 @@ function send(header, body) { !header.bcc ? {} : { - Bcc: [ - { - Email: header.bcc, - Name: header.bccName, - }, - ], - }, + Bcc: [ + { + Email: header.bcc, + Name: header.bccName, + }, + ], + }, /* { "InlinedAttachments": [ @@ -126,7 +126,7 @@ function sendTicket(header, values) { ],*/ }; -console.log('sendTicket >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) + console.log('sendTicket >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) return send(header, body); } @@ -134,7 +134,7 @@ console.log('sendTicket >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) function sendTicketOnline(header, values) { //console.log('>>>>>>>>>>>>>>>>>>><>>', values); const body = { - TemplateID: 3717629, + TemplateID: 3717629, TemplateLanguage: true, TemplateErrorDeliver: true, TemplateErrorReporting: { @@ -197,7 +197,28 @@ function sendReservationCode(header, values) { reservationDescription: values.reservationDescription ? values.reservationDescription : "-", }, }; -console.log('sendReservationCode >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) + console.log('sendReservationCode >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) + return send(header, body); +} + +function sendReservationCodeCollege(header, values) { + const body = { + TemplateID: 3985837, + TemplateLanguage: true, + TemplateErrorDeliver: true, + TemplateErrorReporting: { + Email: "info@rodax-software.com", + Name: "Air traffic control", + }, + Variables: { + entityName: values.entityName, + eventName: values.eventName, + dateEvent: values.dateEvent, + reservationCode: values.reservationCode, + reservationDescription: values.reservationDescription ? values.reservationDescription : "-", + }, + }; + console.log('sendReservationCodeCollege >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) return send(header, body); } @@ -250,5 +271,6 @@ module.exports = { sendListaEspera, sendCancelacion, sendReservationCode, + sendReservationCodeCollege, sendTicketOnline, }; diff --git a/modules/events/event.controller.js b/modules/events/event.controller.js index 833d225..19169b0 100644 --- a/modules/events/event.controller.js +++ b/modules/events/event.controller.js @@ -153,12 +153,13 @@ const extraControllers = { try { - if (req.user.level === 8) result = await eventInscriptionService._getInscriptionByEvent(eventId); - else result = await eventInscriptionService._getInscriptionByEventAndUser(eventId, userId); + if (req.user.level === 8) result = await eventInscriptionService._getInscriptionOnlineByEvent(eventId); + //No se le llamará nunca desde la app, la app trata todas las incripciopnes como normales + // else result = await eventInscriptionService._getInscriptionByEventAndUser(eventId, userId); return handleResultResponse(result, null, params, res, result === null ? httpStatus.NOT_FOUND : httpStatus.OK); } catch (error) { - return handleErrorResponse(MODULE_NAME, "getInscriptions", error, res); + return handleErrorResponse(MODULE_NAME, "getInscriptionsOnline", error, res); } diff --git a/modules/events/events_inscriptions.service.js b/modules/events/events_inscriptions.service.js index a212780..235fa0b 100644 --- a/modules/events/events_inscriptions.service.js +++ b/modules/events/events_inscriptions.service.js @@ -223,6 +223,24 @@ const extraMethods = { ); }, + //Validamos la inscripcion del tutor que hizo la reserva + _validateInscriptionTutorOfReservation: (reservationId, userId) => { + return models.EventInscription.update( + { + validated: true, + overflowEventId: null, + validateUserId: userId, + }, + { + where: { + reservationId: reservationId, + userId: userId, + }, + } + ); + }, + + _getInscriptionsWithoutMemberId: (eventId) => { return models.EventInscription.scope(["includeEventAndVenue", "includeReservation", "defaultScope"]).findAll({ where: { diff --git a/modules/events/events_inscriptions_online.model.js b/modules/events/events_inscriptions_online.model.js new file mode 100644 index 0000000..63cddfa --- /dev/null +++ b/modules/events/events_inscriptions_online.model.js @@ -0,0 +1,72 @@ +"use strict"; +const Sequelize = require("sequelize"); + +/*const getStateText = (inscription) => { + if (inscription.type !== "online" && inscription !== "online group") { + if (inscription.validated == true) { + return "Inscripción confirmada"; + } else if (inscription.overflowEventId) { + return "Inscripción confirmada a lista de espera"; + } else if (inscription.reservationId) { + return "Inscripción confirmada a lista de espera de tu reserva"; + } else return "N/A"; + } else { + // online + return "Inscripción online confirmada"; + } +}; +*/ +module.exports = function (sequelize, DataTypes) { + const EventInscriptionOnline = sequelize.define( + "EventInscriptionOnline", + { + id: { + type: DataTypes.UUID, + defaultValue: DataTypes.UUIDV4, + primaryKey: true, + }, + eventId: { + type: DataTypes.UUID, + // foreignKey: true, + }, + userId: { + type: DataTypes.UUID, + // foreignKey: true, + }, + date: { + type: DataTypes.DATE, + }, + email: { + type: DataTypes.STRING, + allowNull: false, + // defaultValue: "regular", //grupal, invitacion-regular, invitation-grupal, online, online group, onsite, onsite group + }, + assistants: { + type: DataTypes.INTEGER, + }, + }, + { + tableName: "v_events_inscriptions_online", + freezeTableName: true, + timestamps: true, + + defaultScope: { + order: [["date", "DESC"]], + include: [ + { + model: sequelize.models.User, + as: "user", + include: [{ model: sequelize.models.Entity, attributes: ["id", "name"], required: false }], + }, + ], + }, + } + ); + + EventInscriptionOnline.associate = function (models) { + EventInscriptionOnline.Event = EventInscriptionOnline.belongsTo(models.Event, { foreignKey: "eventId", as: "event" }); + EventInscriptionOnline.User = EventInscriptionOnline.belongsTo(models.User, { foreignKey: "userId", as: "user" }); + }; + + return EventInscriptionOnline; +}; diff --git a/modules/events/events_reservations.controller.js b/modules/events/events_reservations.controller.js index 81c1084..3ae40bc 100644 --- a/modules/events/events_reservations.controller.js +++ b/modules/events/events_reservations.controller.js @@ -6,6 +6,7 @@ const eventService = require("./event.service"); const eventReservationService = require("./events_reservations.service"); const eventInscriptionService = require("./events_inscriptions.service"); const mailService = require("./mail.service"); +const userService = require("../auth/user.service"); const marketingListService = require("./marketing_list.service"); const { @@ -23,7 +24,7 @@ const MODULE_NAME = "[eventReservation.controller]"; const controllerOptions = { MODULE_NAME }; - +/*BORRAR TRAS COMPROBAR TODO async function _addConfirmedToEvent(confirmed, event) { const newConfirmed = event.confirmed + confirmed; if (event.assistants < newConfirmed) { @@ -41,54 +42,77 @@ async function _addConfirmedToEvent(confirmed, event) { return true; } +*/ +/**** Activa una reserva que está en borrador (Draft), descontando asistentes del aforo total del evento + * Devuelve la reserva pasada por parametro publicada (publish) o null en el caso de error + */ async function activeReservation(reservation) { if (!reservation) throw new Error("activeReservation: reservation should be an object"); - console.log('>>>>>>> ', reservation); - //La reserva puede estar asociada a la lista de espera es de donde se quitará aforo, si no al evento - const eventToDiscountAssistants = reservation.overflowEventId - ? await eventService._getEvent(reservation.overflowEventId) - : reservation.event; + const eventToDiscountAssistants = reservation.overflow_reservationId + ? await eventService._getEvent(reservation.overflow_reservationId) + : reservation.Event; - console.log(eventToDiscountAssistants); - return true; -} - -async function activeReservationById(id) { - //Buscar reserva con evento y entidad - let reservation = await eventReservationService._getReservaByIdWithEntityAndEvent(id); - return activeReservation(reservation); + //En el caso de ya estar publicada no hacemos nada se devuelve tal cual + if (reservation.state === 'publish') + return reservation; const plazasDisponibles = eventToDiscountAssistants.assistants - eventToDiscountAssistants.confirmed; - if (plazasDisponibles < dataInscription.reservation.assistants) - return handleResultResponse("Aforo lleno no es posible efectuar la reserva", null, params, res, httpStatus.NOT_FOUND) - - + if (plazasDisponibles < reservation.assistants) { + console.log("Aforo lleno no es posible efectuar la reserva"); + return null; + } + const newAforo = eventToDiscountAssistants.assistants - reservation.assistants; //Modificamos los asistentes de evento (AFORO) para quitar los de la reserva - if (!(await eventService._updateAssistantsEvent(reservation.eventId, newAforo))) - return handleResultResponse( - "No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas", - null, - params, - res, - httpStatus.NOT_FOUND - ); + if (!(await eventService._updateAssistantsEvent(eventToDiscountAssistants.id, newAforo))) { + console.log("No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas"); + return null; + } //Si se ha llenado ponemos el evento en SOLD_OUT if (eventToDiscountAssistants.confirmed >= newAforo) await eventService._updateSoldOutEvent(eventToDiscountAssistants.id, true); - - - - - if (await _addConfirmedToEvent(reservation.assistants, reservation.Event)) - if (!(await eventReservationService._updatePublishReservation(id))) { + //REvisar confirmados en lista de espera + //Finalmente publicamos la reserva solo si no está asociada a la lista de espera + if (!reservation.overflow_reservationId) { + if (!(await eventReservationService._updatePublishReservation(reservation.id))) { console.log("No se ha podido publicar la reserva del evento"); - return false; + return null; } + reservation.state = "publish"; + + //Finalmente hay que validar la inscripción del tutor + if ((await eventInscriptionService._validateInscriptionTutorOfReservation(reservation.id, reservation.userId)) <= 0) { + console.log("No se ha podido validar la inscripción del tutor"); + return null; + } + + //Mandamos el código de reserva para que registra a sus alumnos + const user = await userService._getUserById(reservation.userId); + reservation.contact_email = user.email; + reservation.contact_name = user.name; + reservation.event = reservation.Event; + + try { + mailService.sendReservationCollegeEmail(reservation); + } catch (error) { + console.log(error); + }; + + return reservation; + } +} + +async function activeReservationById(id) { + //Buscar reserva con evento y entidad + let reservation = await eventReservationService._getReservaByIdWithEntityAndEvent(id); + if (await activeReservation(reservation) === null) { + console.log("Error activeReservationById") + return false; + } return true; } @@ -360,58 +384,19 @@ const extraControllers = { return; }; - //Si es centro aliado if (dataUser.entityLevel === "aliado") { - //La reserva puede estar asociada a la lista de espera es de donde se quitará aforo, si no al evento - const eventToDiscountAssistants = dataInscription.reservation.overflowEventId - ? await eventService._getEvent(dataInscription.reservation.overflowEventId) - : dataInscription.event; - - const plazasDisponibles = eventToDiscountAssistants.assistants - eventToDiscountAssistants.confirmed; - if (plazasDisponibles < dataInscription.reservation.assistants) - return handleResultResponse("Aforo lleno no es posible efectuar la reserva", null, params, res, httpStatus.NOT_FOUND) - - const newAforo = eventToDiscountAssistants.assistants - dataInscription.reservation.assistants; - //Modificamos los asistentes de evento (AFORO) para quitar los de la reserva - if (!(await eventService._updateAssistantsEvent(eventToDiscountAssistants.id, newAforo))) + const reservationPublicada = await activeReservation(dataInscription.reservation); + if (reservationPublicada === null) return handleResultResponse( - "No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas", + "Error activeReservationToEntity requerida", null, params, res, - httpStatus.NOT_FOUND - ); + httpStatus.NOT_FOUND); + else dataInscription.reservation = reservationPublicada; + }; - //Si se ha llenado ponemos el evento en SOLD_OUT - if (eventToDiscountAssistants.confirmed >= newAforo) - await eventService._updateSoldOutEvent(eventToDiscountAssistants.id, true); - - //Finalmente publicamos la reserva solo si no está asociada a la lista de espera - if (!dataInscription.reservation.overflowEventId) { - if (!(await eventReservationService._updatePublishReservation(dataInscription.reservation.id))) - return handleResultResponse( - "No se ha podido publicar la reserva del evento", - null, - params, - res, - httpStatus.NOT_FOUND - ); - dataInscription.reservation.state = "publish"; - - //Mandamos el código de reserva para que registra a sus alumnos - dataInscription.reservation.contact_email = dataUser.email; - dataInscription.reservation.contact_name = dataUser.name; - dataInscription.reservation.event = dataInscription.event; - console.log('MANDAMOS CODIO RESERVA>>>>>>', dataInscription.reservation); - - try { - mailService.sendReservationEmail(dataInscription.reservation); - } catch (error) { - console.log(error); - } - } - } next(); }, diff --git a/modules/events/mail.service.js b/modules/events/mail.service.js index c07afda..aee628c 100644 --- a/modules/events/mail.service.js +++ b/modules/events/mail.service.js @@ -8,22 +8,22 @@ const emailHelper = require("../../helpers/mail.helper"); //////////////////////////////////////////////////////////////////// // dataInscription {incription:{...}, {..., event:{...}, reservation:{...}, user:{...}} //////////////////////////////////////////////////////////////////// - /*AHORA SE ALMACENA TODO EN UNA ÚNICA LISTA DE MAILCHIMP, QUE ES LA DEL EVENTO +/*AHORA SE ALMACENA TODO EN UNA ÚNICA LISTA DE MAILCHIMP, QUE ES LA DEL EVENTO (si en un futuro se quiere tener listas independientes, bastaría con tratarlo aqui los campos de marketinglist de la reserva ...) - if (dataInscription.inscription.reservationId) - marketingListOfInscription = dataInscription.reservation.marketingList - else if (dataInscription.inscription.overflowEventId) - marketingListOfInscription = (await _getEvent(dataInscription.inscription.overflowEventId)).marketingList; - else - marketingListOfInscription = dataInscription.event.marketingList; + if (dataInscription.inscription.reservationId) + marketingListOfInscription = dataInscription.reservation.marketingList + else if (dataInscription.inscription.overflowEventId) + marketingListOfInscription = (await _getEvent(dataInscription.inscription.overflowEventId)).marketingList; + else + marketingListOfInscription = dataInscription.event.marketingList; */ function _generateMailDTO(dataInscription) { let inscriptionDTO = {}; -//console.log('*******ENTRO****', dataInscription); + //console.log('*******ENTRO****', dataInscription); const inscription = dataInscription.inscription ? dataInscription.inscription : dataInscription; const event = dataInscription.event ? dataInscription.event : dataInscription.inscription.event; - const reservation = dataInscription.reservation ? dataInscription.reservation : null; - const user = dataInscription.user ? dataInscription.user : dataInscription.inscription.user; + const reservation = dataInscription.reservation ? dataInscription.reservation : null; + const user = dataInscription.user ? dataInscription.user : dataInscription.inscription.user; if (inscription) { inscriptionDTO.id = inscription.id; @@ -35,39 +35,39 @@ function _generateMailDTO(dataInscription) { inscriptionDTO.code_ticket = inscription.code_ticket; inscriptionDTO.validated = inscription.validated; inscriptionDTO.type = inscription.type; // inscription.tipoEntrada ? inscription.tipoEntrada : inscription.type; - + inscriptionDTO.reservation_code = reservation ? reservation.reservation_code : null; inscriptionDTO.color = reservation ? reservation.color : null; - inscriptionDTO.description = ((reservation ? reservation.description : "Entrada").toUpperCase() + (lodash.words(inscription.type).includes("online")? " online" : "")); - inscriptionDTO.qrConfig= null; - inscriptionDTO.qrCode= null; - + inscriptionDTO.description = ((reservation ? reservation.description : "Entrada").toUpperCase() + (lodash.words(inscription.type).includes("online") ? " online" : "")); + inscriptionDTO.qrConfig = null; + inscriptionDTO.qrCode = null; + if (user) { -//Era para mailchimp -/// inscriptionDTO.marketing_memberId = inscription.marketing_memberId ? inscription.marketing_memberId : null; - inscriptionDTO.email = user.email; - inscriptionDTO.name = user.name; - inscriptionDTO.surname = user.surname; - inscriptionDTO.userId = user.id; - inscriptionDTO.entity = reservation && reservation.Entity ? reservation.Entity.name : (user.Entity ? user.Entity.name : user.entityId); + //Era para mailchimp + /// inscriptionDTO.marketing_memberId = inscription.marketing_memberId ? inscription.marketing_memberId : null; + inscriptionDTO.email = user.email; + inscriptionDTO.name = user.name; + inscriptionDTO.surname = user.surname; + inscriptionDTO.userId = user.id; + inscriptionDTO.entity = reservation && reservation.Entity ? reservation.Entity.name : (user.Entity ? user.Entity.name : user.entityId); }; } -console.log('*******SALGO****', inscriptionDTO); + console.log('*******SALGO****', inscriptionDTO); return inscriptionDTO; } function generateHeaderMail(member) { let headerMail = null; - let AsuntoOnline = lodash.words(member.type).includes("online") ? "Inscripción online" : ""; - let AsuntoOnsite = member.validated ? "Entrada" : "Lista de espera"; + let AsuntoOnline = lodash.words(member.type).includes("online") ? "Inscripción online" : ""; + let AsuntoOnsite = member.validated ? "Entrada" : "Lista de espera"; if (member) { headerMail = { to: member.email, name: member.name + " " + member.surname, subject: - ((AsuntoOnline === "") ? AsuntoOnsite : AsuntoOnline) + " para el congreso " + member.event_name + " confirmada", + ((AsuntoOnline === "") ? AsuntoOnsite : AsuntoOnline) + " para el congreso " + member.event_name + " confirmada", }; } @@ -90,19 +90,19 @@ function generateHeaderMailReservation(reservation) { } function generateBodyMailReservation(reservation) { -console.log('generateBodyMailReservation>>>>>>>', reservation); + console.log('generateBodyMailReservation>>>>>>>', reservation); const event = reservation.Event ? reservation.Event : reservation.event; let bodyMail = null; if (reservation) { bodyMail = { - entityName: reservation.Entity? reservation.Entity.name : reservation.contact_name, + entityName: reservation.Entity ? reservation.Entity.name : reservation.contact_name, eventName: event.name, dateEvent: moment(event.init_date).format("D [de] MMMM [de] YYYY"), reservationCode: reservation.reservation_code, reservationDescription: reservation.description, }; } - console.log('generateBodyMailReservation>>>>>>>', bodyMail); + console.log('generateBodyMailReservation>>>>>>>', bodyMail); return bodyMail; } @@ -113,7 +113,7 @@ function generateBodyMail(member) { if (member) { bodyMail = { - tipoEntrada: tipoEntrada, + tipoEntrada: tipoEntrada, descriptionEntrada: member.description, qrCode: member.qrCode, qrCodeUrl: member.qrCodeUrl, @@ -138,21 +138,21 @@ async function sendEmailConfirm(dataUser, dataInscription) { mailDTO.qrCode = await QRHelper.getInscriptionQRCode(mailDTO.qrConfig); mailDTO.qrCodeUrl = QRHelper.getInscriptionQRCodeUrl(dataInscription.inscription.id); - console.log("Mandamos mail con entrada>>>>>>>>>>>>>>>>>>>>>>>>>>>"); - //console.log(headerMail, bodyMail); + console.log("Mandamos mail con entrada>>>>>>>>>>>>>>>>>>>>>>>>>>>"); + //console.log(headerMail, bodyMail); - try { - if (isOnline) - emailHelper.sendTicketOnline(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)) + try { + if (isOnline) + emailHelper.sendTicketOnline(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)) + else + if (dataInscription.inscription.validated) + emailHelper.sendTicket(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)); else - if (dataInscription.inscription.validated) - emailHelper.sendTicket(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)); - else - emailHelper.sendListaEspera(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)); - } catch (error) { - console.log("No se ha podido mandar email con entrada"); - } - + emailHelper.sendListaEspera(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)); + } catch (error) { + console.log("No se ha podido mandar email con entrada"); + } + return true; } @@ -168,14 +168,14 @@ async function sendEmailCancelate(inscription) { console.log("Mandamos mail con la cancelacion>>>>>>>>>>>>>>>>>>>>>>>>>>>"); try { emailHelper.sendCancelacion(headerMail, generateBodyMail(mailDTO)); - } catch (error) {console.log("No se ha podido mandar email con cancelación")}; + } catch (error) { console.log("No se ha podido mandar email con cancelación") }; return true; } async function _sendInscriptionEmail(dataInscription, member) { - let mailDTO = _generateMailDTO(inscription); + let mailDTO = _generateMailDTO(inscription); member.qrConfig = QRHelper.generateQRConfig(member); member.qrCode = await QRHelper.getInscriptionQRCode(member.qrConfig); member.qrCodeUrl = QRHelper.getInscriptionQRCodeUrl(dataInscription.inscription.id); @@ -199,14 +199,23 @@ async function sendReservationEmail(reservation) { } } +async function sendReservationCollegeEmail(reservation) { + try { + emailHelper.sendReservationCodeCollege(generateHeaderMailReservation(reservation), generateBodyMailReservation(reservation)); + } catch (error) { + console.log("No se ha podido mandar email _sendReservationCodeCollege", error); + } +} + module.exports = { sendEmailConfirm, sendEmailCancelate, sendReservationEmail, + sendReservationCollegeEmail, generateHeaderMail, generateHeaderMailReservation, generateBodyMail, - generateBodyMailReservation, + generateBodyMailReservation, };