.Repsaso de activar una reserva automática de cole

This commit is contained in:
David Arranz 2022-06-07 10:33:00 +02:00
parent 2d91689f95
commit 7923896dab
6 changed files with 244 additions and 137 deletions

View File

@ -34,13 +34,13 @@ function send(header, body) {
!header.bcc !header.bcc
? {} ? {}
: { : {
Bcc: [ Bcc: [
{ {
Email: header.bcc, Email: header.bcc,
Name: header.bccName, Name: header.bccName,
}, },
], ],
}, },
/* /*
{ {
"InlinedAttachments": [ "InlinedAttachments": [
@ -126,7 +126,7 @@ function sendTicket(header, values) {
],*/ ],*/
}; };
console.log('sendTicket >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body) console.log('sendTicket >>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<', header, body)
return send(header, body); return send(header, body);
} }
@ -197,7 +197,28 @@ function sendReservationCode(header, values) {
reservationDescription: values.reservationDescription ? values.reservationDescription : "-", 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); return send(header, body);
} }
@ -250,5 +271,6 @@ module.exports = {
sendListaEspera, sendListaEspera,
sendCancelacion, sendCancelacion,
sendReservationCode, sendReservationCode,
sendReservationCodeCollege,
sendTicketOnline, sendTicketOnline,
}; };

View File

@ -153,12 +153,13 @@ const extraControllers = {
try { try {
if (req.user.level === 8) result = await eventInscriptionService._getInscriptionByEvent(eventId); if (req.user.level === 8) result = await eventInscriptionService._getInscriptionOnlineByEvent(eventId);
else result = await eventInscriptionService._getInscriptionByEventAndUser(eventId, userId); //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); return handleResultResponse(result, null, params, res, result === null ? httpStatus.NOT_FOUND : httpStatus.OK);
} catch (error) { } catch (error) {
return handleErrorResponse(MODULE_NAME, "getInscriptions", error, res); return handleErrorResponse(MODULE_NAME, "getInscriptionsOnline", error, res);
} }

View File

@ -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) => { _getInscriptionsWithoutMemberId: (eventId) => {
return models.EventInscription.scope(["includeEventAndVenue", "includeReservation", "defaultScope"]).findAll({ return models.EventInscription.scope(["includeEventAndVenue", "includeReservation", "defaultScope"]).findAll({
where: { where: {

View File

@ -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;
};

View File

@ -6,6 +6,7 @@ const eventService = require("./event.service");
const eventReservationService = require("./events_reservations.service"); const eventReservationService = require("./events_reservations.service");
const eventInscriptionService = require("./events_inscriptions.service"); const eventInscriptionService = require("./events_inscriptions.service");
const mailService = require("./mail.service"); const mailService = require("./mail.service");
const userService = require("../auth/user.service");
const marketingListService = require("./marketing_list.service"); const marketingListService = require("./marketing_list.service");
const { const {
@ -23,7 +24,7 @@ const MODULE_NAME = "[eventReservation.controller]";
const controllerOptions = { MODULE_NAME }; const controllerOptions = { MODULE_NAME };
/*BORRAR TRAS COMPROBAR TODO
async function _addConfirmedToEvent(confirmed, event) { async function _addConfirmedToEvent(confirmed, event) {
const newConfirmed = event.confirmed + confirmed; const newConfirmed = event.confirmed + confirmed;
if (event.assistants < newConfirmed) { if (event.assistants < newConfirmed) {
@ -41,54 +42,77 @@ async function _addConfirmedToEvent(confirmed, event) {
return true; 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) { async function activeReservation(reservation) {
if (!reservation) if (!reservation)
throw new Error("activeReservation: reservation should be an object"); throw new Error("activeReservation: reservation should be an object");
console.log('>>>>>>> ', reservation); const eventToDiscountAssistants = reservation.overflow_reservationId
//La reserva puede estar asociada a la lista de espera es de donde se quitará aforo, si no al evento ? await eventService._getEvent(reservation.overflow_reservationId)
const eventToDiscountAssistants = reservation.overflowEventId : reservation.Event;
? await eventService._getEvent(reservation.overflowEventId)
: reservation.event;
console.log(eventToDiscountAssistants); //En el caso de ya estar publicada no hacemos nada se devuelve tal cual
return true; if (reservation.state === 'publish')
} return reservation;
async function activeReservationById(id) {
//Buscar reserva con evento y entidad
let reservation = await eventReservationService._getReservaByIdWithEntityAndEvent(id);
return activeReservation(reservation);
const plazasDisponibles = eventToDiscountAssistants.assistants - eventToDiscountAssistants.confirmed; const plazasDisponibles = eventToDiscountAssistants.assistants - eventToDiscountAssistants.confirmed;
if (plazasDisponibles < dataInscription.reservation.assistants) if (plazasDisponibles < reservation.assistants) {
return handleResultResponse("Aforo lleno no es posible efectuar la reserva", null, params, res, httpStatus.NOT_FOUND) 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 //Modificamos los asistentes de evento (AFORO) para quitar los de la reserva
if (!(await eventService._updateAssistantsEvent(reservation.eventId, newAforo))) if (!(await eventService._updateAssistantsEvent(eventToDiscountAssistants.id, newAforo))) {
return handleResultResponse( console.log("No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas");
"No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas", return null;
null, }
params,
res,
httpStatus.NOT_FOUND
);
//Si se ha llenado ponemos el evento en SOLD_OUT //Si se ha llenado ponemos el evento en SOLD_OUT
if (eventToDiscountAssistants.confirmed >= newAforo) if (eventToDiscountAssistants.confirmed >= newAforo)
await eventService._updateSoldOutEvent(eventToDiscountAssistants.id, true); await eventService._updateSoldOutEvent(eventToDiscountAssistants.id, true);
//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))) {
if (await _addConfirmedToEvent(reservation.assistants, reservation.Event))
if (!(await eventReservationService._updatePublishReservation(id))) {
console.log("No se ha podido publicar la reserva del evento"); 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; return true;
} }
@ -360,58 +384,19 @@ const extraControllers = {
return; return;
}; };
//Si es centro aliado //Si es centro aliado
if (dataUser.entityLevel === "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 reservationPublicada = await activeReservation(dataInscription.reservation);
const eventToDiscountAssistants = dataInscription.reservation.overflowEventId if (reservationPublicada === null)
? 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)))
return handleResultResponse( return handleResultResponse(
"No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas", "Error activeReservationToEntity requerida",
null, null,
params, params,
res, 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(); next();
}, },

View File

@ -8,18 +8,18 @@ const emailHelper = require("../../helpers/mail.helper");
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// dataInscription {incription:{...}, {..., event:{...}, reservation:{...}, user:{...}} // 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 ...) (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) if (dataInscription.inscription.reservationId)
marketingListOfInscription = dataInscription.reservation.marketingList marketingListOfInscription = dataInscription.reservation.marketingList
else if (dataInscription.inscription.overflowEventId) else if (dataInscription.inscription.overflowEventId)
marketingListOfInscription = (await _getEvent(dataInscription.inscription.overflowEventId)).marketingList; marketingListOfInscription = (await _getEvent(dataInscription.inscription.overflowEventId)).marketingList;
else else
marketingListOfInscription = dataInscription.event.marketingList; marketingListOfInscription = dataInscription.event.marketingList;
*/ */
function _generateMailDTO(dataInscription) { function _generateMailDTO(dataInscription) {
let inscriptionDTO = {}; let inscriptionDTO = {};
//console.log('*******ENTRO****', dataInscription); //console.log('*******ENTRO****', dataInscription);
const inscription = dataInscription.inscription ? dataInscription.inscription : dataInscription; const inscription = dataInscription.inscription ? dataInscription.inscription : dataInscription;
const event = dataInscription.event ? dataInscription.event : dataInscription.inscription.event; const event = dataInscription.event ? dataInscription.event : dataInscription.inscription.event;
const reservation = dataInscription.reservation ? dataInscription.reservation : null; const reservation = dataInscription.reservation ? dataInscription.reservation : null;
@ -38,36 +38,36 @@ function _generateMailDTO(dataInscription) {
inscriptionDTO.reservation_code = reservation ? reservation.reservation_code : null; inscriptionDTO.reservation_code = reservation ? reservation.reservation_code : null;
inscriptionDTO.color = reservation ? reservation.color : null; inscriptionDTO.color = reservation ? reservation.color : null;
inscriptionDTO.description = ((reservation ? reservation.description : "Entrada").toUpperCase() + (lodash.words(inscription.type).includes("online")? " online" : "")); inscriptionDTO.description = ((reservation ? reservation.description : "Entrada").toUpperCase() + (lodash.words(inscription.type).includes("online") ? " online" : ""));
inscriptionDTO.qrConfig= null; inscriptionDTO.qrConfig = null;
inscriptionDTO.qrCode= null; inscriptionDTO.qrCode = null;
if (user) { if (user) {
//Era para mailchimp //Era para mailchimp
/// inscriptionDTO.marketing_memberId = inscription.marketing_memberId ? inscription.marketing_memberId : null; /// inscriptionDTO.marketing_memberId = inscription.marketing_memberId ? inscription.marketing_memberId : null;
inscriptionDTO.email = user.email; inscriptionDTO.email = user.email;
inscriptionDTO.name = user.name; inscriptionDTO.name = user.name;
inscriptionDTO.surname = user.surname; inscriptionDTO.surname = user.surname;
inscriptionDTO.userId = user.id; inscriptionDTO.userId = user.id;
inscriptionDTO.entity = reservation && reservation.Entity ? reservation.Entity.name : (user.Entity ? user.Entity.name : user.entityId); 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; return inscriptionDTO;
} }
function generateHeaderMail(member) { function generateHeaderMail(member) {
let headerMail = null; let headerMail = null;
let AsuntoOnline = lodash.words(member.type).includes("online") ? "Inscripción online" : ""; let AsuntoOnline = lodash.words(member.type).includes("online") ? "Inscripción online" : "";
let AsuntoOnsite = member.validated ? "Entrada" : "Lista de espera"; let AsuntoOnsite = member.validated ? "Entrada" : "Lista de espera";
if (member) { if (member) {
headerMail = { headerMail = {
to: member.email, to: member.email,
name: member.name + " " + member.surname, name: member.name + " " + member.surname,
subject: subject:
((AsuntoOnline === "") ? AsuntoOnsite : AsuntoOnline) + " para el congreso " + member.event_name + " confirmada", ((AsuntoOnline === "") ? AsuntoOnsite : AsuntoOnline) + " para el congreso " + member.event_name + " confirmada",
}; };
} }
@ -90,12 +90,12 @@ function generateHeaderMailReservation(reservation) {
} }
function generateBodyMailReservation(reservation) { function generateBodyMailReservation(reservation) {
console.log('generateBodyMailReservation>>>>>>>', reservation); console.log('generateBodyMailReservation>>>>>>>', reservation);
const event = reservation.Event ? reservation.Event : reservation.event; const event = reservation.Event ? reservation.Event : reservation.event;
let bodyMail = null; let bodyMail = null;
if (reservation) { if (reservation) {
bodyMail = { bodyMail = {
entityName: reservation.Entity? reservation.Entity.name : reservation.contact_name, entityName: reservation.Entity ? reservation.Entity.name : reservation.contact_name,
eventName: event.name, eventName: event.name,
dateEvent: moment(event.init_date).format("D [de] MMMM [de] YYYY"), dateEvent: moment(event.init_date).format("D [de] MMMM [de] YYYY"),
reservationCode: reservation.reservation_code, reservationCode: reservation.reservation_code,
@ -138,20 +138,20 @@ async function sendEmailConfirm(dataUser, dataInscription) {
mailDTO.qrCode = await QRHelper.getInscriptionQRCode(mailDTO.qrConfig); mailDTO.qrCode = await QRHelper.getInscriptionQRCode(mailDTO.qrConfig);
mailDTO.qrCodeUrl = QRHelper.getInscriptionQRCodeUrl(dataInscription.inscription.id); mailDTO.qrCodeUrl = QRHelper.getInscriptionQRCodeUrl(dataInscription.inscription.id);
console.log("Mandamos mail con entrada>>>>>>>>>>>>>>>>>>>>>>>>>>>"); console.log("Mandamos mail con entrada>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//console.log(headerMail, bodyMail); //console.log(headerMail, bodyMail);
try { try {
if (isOnline) if (isOnline)
emailHelper.sendTicketOnline(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)) emailHelper.sendTicketOnline(generateHeaderMail(mailDTO), generateBodyMail(mailDTO))
else
if (dataInscription.inscription.validated)
emailHelper.sendTicket(generateHeaderMail(mailDTO), generateBodyMail(mailDTO));
else else
if (dataInscription.inscription.validated) emailHelper.sendListaEspera(generateHeaderMail(mailDTO), generateBodyMail(mailDTO));
emailHelper.sendTicket(generateHeaderMail(mailDTO), generateBodyMail(mailDTO)); } catch (error) {
else 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; return true;
} }
@ -168,7 +168,7 @@ async function sendEmailCancelate(inscription) {
console.log("Mandamos mail con la cancelacion>>>>>>>>>>>>>>>>>>>>>>>>>>>"); console.log("Mandamos mail con la cancelacion>>>>>>>>>>>>>>>>>>>>>>>>>>>");
try { try {
emailHelper.sendCancelacion(headerMail, generateBodyMail(mailDTO)); 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; return true;
} }
@ -199,11 +199,20 @@ 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 = { module.exports = {
sendEmailConfirm, sendEmailConfirm,
sendEmailCancelate, sendEmailCancelate,
sendReservationEmail, sendReservationEmail,
sendReservationCollegeEmail,
generateHeaderMail, generateHeaderMail,
generateHeaderMailReservation, generateHeaderMailReservation,
generateBodyMail, generateBodyMail,