Migración a HubSpot

This commit is contained in:
David Arranz 2024-05-31 12:06:36 +02:00
parent 2cea881495
commit f129c19c91
11 changed files with 305 additions and 308 deletions

13
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Node: Nodemon",
"processId": "${command:PickProcess}",
"restart": true,
"protocol": "inspector"
}
]
}

View File

@ -1,51 +1,58 @@
module.exports = {
database: {
username: 'lqdvi',
password: 'Z286y386*a',
database: 'lqdvi_v2',
host: 'localhost',
dialect: 'mysql',
},
database: {
username: "lqdvi",
password: "Z286y386*a",
database: "lqdvi_v2",
host: "localhost",
dialect: "mysql",
},
cache: {
enabled: false,
defaultDuration: '1 minute',
debug: true,
},
cache: {
enabled: false,
defaultDuration: "1 minute",
debug: true,
},
session: {
secret_token: process.env.SECRET_TOKEN || "B57J=7B`NQ$y98|~5;hc715bo09^5oz8NR+]n9r~215B91Nd9P%25_N6r!GHcOKp|18y5-73Dr5^@9k7n]5l<-41D1o",
token_expires_in: '365d'
},
session: {
secret_token:
process.env.SECRET_TOKEN ||
"B57J=7B`NQ$y98|~5;hc715bo09^5oz8NR+]n9r~215B91Nd9P%25_N6r!GHcOKp|18y5-73Dr5^@9k7n]5l<-41D1o",
token_expires_in: "365d",
},
server: {
hostname: process.env.HOSTNAME || '127.0.0.1',
port: process.env.PORT || 19999,
public_url: ""
},
server: {
hostname: process.env.HOSTNAME || "127.0.0.1",
port: process.env.PORT || 19999,
public_url: "",
},
cdn: {
hostname: "https://cdnapp2.loquedeverdadimporta.org",
},
cdn: {
hostname: "https://cdnapp2.loquedeverdadimporta.org",
},
uploads: {
path: "/home/rodax/Documentos/cdn2",
thumb_size: 300,
thumb_prefix: "th_",
},
uploads: {
path: "/home/rodax/Documentos/cdn2",
thumb_size: 300,
thumb_prefix: "th_",
},
paginate: {
limit: 10,
maxLimit: 50
},
paginate: {
limit: 10,
maxLimit: 50,
},
vimeo: {
CLIENT_ID: '9581f2d0ed211dc1e31b5c825117dc1f00d77ba0',
CLIENT_SECRET: '3kf0hQ63OXSPm7z2X1qyOV4iH57Xha0cyRXn0VJneq8zHbWKjfB1/9H8KcgBgzgkzw0Y9x/xFLUAauuHLEkqHxLBw8QueanCgIZev1L5xoksrKuKX7gMvErqqP+uFNnA',
ACCESS_TOKEN: 'fcc7b31fe690a768efa920e13d750449'
},
vimeo: {
CLIENT_ID: "9581f2d0ed211dc1e31b5c825117dc1f00d77ba0",
CLIENT_SECRET:
"3kf0hQ63OXSPm7z2X1qyOV4iH57Xha0cyRXn0VJneq8zHbWKjfB1/9H8KcgBgzgkzw0Y9x/xFLUAauuHLEkqHxLBw8QueanCgIZev1L5xoksrKuKX7gMvErqqP+uFNnA",
ACCESS_TOKEN: "fcc7b31fe690a768efa920e13d750449",
},
sendinblue: {
API_KEY: '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'
}
}
sendinblue: {
API_KEY: "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",
},
hubspot: {
API_KEY: "pat-eu1-36a3fff1-1877-44ae-a32e-00e91c3e650b",
},
};

View File

@ -1,60 +1,66 @@
module.exports = {
database: {
username: 'lqdvi',
password: 'Z286y386*a',
database: 'lqdvi_v2',
host: 'localhost',
dialect: 'mysql',
database: {
username: "lqdvi",
password: "Z286y386*a",
database: "lqdvi_v2",
host: "localhost",
dialect: "mysql",
/*
/*
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
host: process.env.DB_HOSTNAME,
dialect: 'mysql',
*/
},
},
cache: {
enabled: true,
defaultDuration: '1 minute',
debug: true,
},
cache: {
enabled: true,
defaultDuration: "1 minute",
debug: true,
},
session: {
secret_token:
process.env.SECRET_TOKEN ||
"B57J=7B`NQ$y98|~5;hc715bo09^5oz8NR+]n9r~215B91Nd9P%25_N6r!GHcOKp|18y5-73Dr5^@9k7n]5l<-41D1o",
token_expires_in: "365d",
},
session: {
secret_token: process.env.SECRET_TOKEN || "B57J=7B`NQ$y98|~5;hc715bo09^5oz8NR+]n9r~215B91Nd9P%25_N6r!GHcOKp|18y5-73Dr5^@9k7n]5l<-41D1o",
token_expires_in: '365d'
},
server: {
hostname: process.env.HOSTNAME || "127.0.0.1",
port: process.env.PORT || 19999,
public_url: "https://apiapp3.loquedeverdadimporta.org/api/v3",
},
server: {
hostname: process.env.HOSTNAME || '127.0.0.1',
port: process.env.PORT || 19999,
public_url: "https://apiapp3.loquedeverdadimporta.org/api/v3"
},
cdn: {
hostname: "https://cdnapp2.loquedeverdadimporta.org",
},
cdn: {
hostname: "https://cdnapp2.loquedeverdadimporta.org",
},
uploads: {
path: "/opt/app2/cdn2",
thumb_size: 300,
thumb_prefix: "th_",
},
uploads: {
path: "/opt/app2/cdn2",
thumb_size: 300,
thumb_prefix: "th_",
},
paginate: {
limit: 10,
maxLimit: 50,
},
paginate: {
limit: 10,
maxLimit: 50
},
vimeo: {
CLIENT_ID: "9581f2d0ed211dc1e31b5c825117dc1f00d77ba0",
CLIENT_SECRET:
"3kf0hQ63OXSPm7z2X1qyOV4iH57Xha0cyRXn0VJneq8zHbWKjfB1/9H8KcgBgzgkzw0Y9x/xFLUAauuHLEkqHxLBw8QueanCgIZev1L5xoksrKuKX7gMvErqqP+uFNnA",
ACCESS_TOKEN: "fcc7b31fe690a768efa920e13d750449",
},
vimeo: {
CLIENT_ID: '9581f2d0ed211dc1e31b5c825117dc1f00d77ba0',
CLIENT_SECRET: '3kf0hQ63OXSPm7z2X1qyOV4iH57Xha0cyRXn0VJneq8zHbWKjfB1/9H8KcgBgzgkzw0Y9x/xFLUAauuHLEkqHxLBw8QueanCgIZev1L5xoksrKuKX7gMvErqqP+uFNnA',
ACCESS_TOKEN: 'fcc7b31fe690a768efa920e13d750449'
},
sendinblue: {
API_KEY: "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",
},
sendinblue: {
API_KEY: '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'
}
}
hubspot: {
API_KEY: "pat-eu1-36a3fff1-1877-44ae-a32e-00e91c3e650b",
},
};

View File

@ -15,8 +15,6 @@ function _getMemberByEmail(userEmail) {
const defaultClient = new hubspot.Client({ accessToken: config.hubspot.API_KEY });
return new Promise(function (resolve, reject) {
console.debug("_existsMember HS:", userEmail);
defaultClient.crm.contacts.searchApi
.doSearch({
filterGroups: [
@ -63,7 +61,6 @@ function _getMemberByEmail(userEmail) {
],
}
*/
console.debug("HS API called successfully. Returned total: " + data.total);
if (data.total === 1) {
resolve(data.results[0]);
} else {
@ -82,8 +79,6 @@ function _createMember(member) {
const defaultClient = new hubspot.Client({ accessToken: config.hubspot.API_KEY });
return new Promise(function (resolve, reject) {
console.debug("_createMember HS:", member.email);
/**
* member = {
id: "3cc58b92-d144-492d-a8e8-9e1294b5b10b",
@ -118,13 +113,11 @@ function _createMember(member) {
entidad_protagonista: member.entity ? member.entity : "",
};
console.debug(newContact);
defaultClient.crm.contacts.basicApi
.create({
properties: newContact,
})
.then(function (newContact) {
console.debug("HS API called successfully. Returned data: " + newContact.id);
resolve(newContact);
})
.catch(function (error) {
@ -139,8 +132,6 @@ function _updateMember(email, member) {
const defaultClient = new hubspot.Client({ accessToken: config.hubspot.API_KEY });
return new Promise(function (resolve, reject) {
console.debug("_updateMember HS:", email);
/**
* member = {
email: "darranz@rodax-software.com",
@ -165,7 +156,7 @@ function _updateMember(email, member) {
entidad_protagonista: member.entity ? member.entity : "",
},
})
.then(function (response) {
.then(function (updatedContact) {
/**
* response = {
createdAt: "2023-07-25T08:19:05.729Z",
@ -190,7 +181,6 @@ function _updateMember(email, member) {
}}
*/
console.debug("HS API called successfully. Returned data: " + response);
resolve(updatedContact);
})
.catch(function (error) {
@ -207,14 +197,11 @@ function _deleteMember(email) {
const defaultClient = new hubspot.Client({ accessToken: config.hubspot.API_KEY });
return new Promise(function (resolve, reject) {
console.debug("_deleteMember HS:", email);
_getMemberByEmail(email).then((data) => {
if (data && data.id) {
defaultClient.crm.contacts.basicApi
.archive(data.id)
.then(function (response) {
console.debug("HS API called successfully. Returned data: " + response);
resolve();
})
.catch(function (error) {
@ -289,13 +276,9 @@ async function _addInscriptionToMember(hbContact, member) {
}
async function _deleteInscriptionFromMember(hbContact, inscription) {
/**
* arg1: {id: 'c8a39de5-2de6-45e8-84b5-bda22ff81492', source: 'app', event_name: 'Sevilla 2023 - 22ª Edición', event_date: Mon Jun 03 2024 09:00:00 GMT+0200 (hora de verano de Europa central), event_marketing_list: null, }
*/
console.log(inscription);
const {
event: {
init_date,
location: { city: delete_city, country: delete_country },
},
} = inscription;
@ -304,37 +287,38 @@ async function _deleteInscriptionFromMember(hbContact, inscription) {
let ciudad_del_evento = String(properties.ciudad_del_evento || "").split(";");
if (ciudad_del_evento.includes(delete_city)) {
if (ciudad_del_evento.length > 1) {
ciudad_del_evento = ciudad_del_evento.filter((ciudad) => ciudad !== delete_city);
ciudad_del_evento = ciudad_del_evento.join(";");
} else {
ciudad_del_evento = null; //
ciudad_del_evento = ciudad_del_evento.filter((ciudad) => ciudad !== delete_city);
}
const delete_year = String(new Date(init_date).getUTCFullYear());
let ano_del_congreso = String(properties.ano_del_congreso || "").split(";");
if (ano_del_congreso.includes(delete_year)) {
if (ano_del_congreso.length > 1 || ciudad_del_evento.length === 0) {
ano_del_congreso = ano_del_congreso.filter((year) => year !== delete_year);
}
}
let pais = String(properties.pais || "").split(";");
if (pais.includes(delete_country)) {
if (pais.length > 1) {
pais = pais.filter((ciudad) => ciudad !== delete_city);
pais = pais.join(";");
} else {
pais = null; //
if (pais.length > 1 || ciudad_del_evento.length === 0) {
pais = pais.filter((item) => item !== delete_country);
}
}
const defaultClient = new hubspot.Client({ accessToken: config.hubspot.API_KEY });
const updatedContact = await defaultClient.crm.contacts.basicApi.update(hbContact.id, {
properties: {
ciudad_del_evento,
//pais,
//ano_del_congreso,
tipo_de_evento: "Congreso",
ciudad_del_evento: ciudad_del_evento.join(";"),
pais: pais.join(";"),
ano_del_congreso: ano_del_congreso.join(";"),
},
});
return;
return updatedContact;
}
/***************************************************************************** */
async function addMemberToList(listId, member) {
let hbContact = await _getMemberByEmail(member.email);
if (hbContact && hbContact.id) {
@ -356,20 +340,6 @@ async function deleteMemberFromList(listId, userEmail, inscription) {
let hbContact = await _getMemberByEmail(userEmail);
if (hbContact && hbContact.id) {
await _deleteInscriptionFromMember(hbContact, inscription);
/*
_deleteInscriptionFromMember(hbContact, inscription).then(() => {
// ¿debo archivarlo?
// si-> _deleteMemeber(userEmail);
})
if (_hbContactWithLastInscription(hbContact)) {
return _deleteMember(userEmail);
} else {
return _updateMember(email, inscription)
}
} else {
return _createMember(member);
}*/
}
return;
}

View File

@ -1,7 +1,9 @@
const { Expo } = require('expo-server-sdk');
// Create a new Expo SDK client
const expo = new Expo();
const expo = new Expo({
useFcmV1: true // this can be set to true in order to use the FCM v1 API
});
const createPushMessage = (data) => {
const pushMessage = {

View File

@ -8,7 +8,7 @@ const crypto = require("crypto");
const securityHelper = require("../../helpers/security.helper");
const authService = require("./auth.service");
const userService = require("./user.service");
const marketing = require("../../helpers/sendinblue.helper");
const marketing = require("../../helpers/hubspot.helper");
const marketingService = require("../events/marketing_list.service");
const eventInscriptionService = require("../events/events_inscriptions.service");
const { RequestContactImportNewList } = require("sib-api-v3-sdk");

View File

@ -298,19 +298,27 @@ const extraControllers = {
httpStatus.NOT_FOUND
);
try {
//Eliminamos miembro de la lista de mailchimp a la que está asociado
if (marketingListIdOverflow) {
try {
//Eliminamos miembro de la lista de mailchimp a la que está asociado
await marketingListService._deleteMember(marketingListIdOverflow, inscription.user.email); // inscription.marketing_memberId);
} catch (error) {
console.log("validate incription", error);
await marketingListService._deleteMember(marketingListIdOverflow, inscription.user.email); // inscription.marketing_memberId);
} catch (error) {
console.log("validate incription", error);
}
}
//Mandar correo de confirmacion de inscripcion
try {
var member = generateMemberInscription(inscription.user, inscription, inscription.reservation);
/**** */
member.marketing_memberId = await eventInscriptionService._addMember(marketingListIdEvent, member);
eventInscriptionService._updateMarketingMemberOfInscription(inscription.id, member.marketing_memberId);
/*** */
member.qrConfig = QRHelper.generateQRConfig(member);
member.qrCode = await QRHelper.getInscriptionQRCode(member.qrConfig);
member.qrCodeUrl = QRHelper.getInscriptionQRCodeUrl(inscription.id);

View File

@ -8,7 +8,11 @@ const eventService = require("./event.service");
const mailService = require("./mail.service");
const marketingListService = require("./marketing_list.service");
const QRHelper = require("../../helpers/qr.helper");
const { extractParamsFromRequest, handleResultResponse, handleErrorResponse } = require("../../helpers/controller.helper");
const {
extractParamsFromRequest,
handleResultResponse,
handleErrorResponse,
} = require("../../helpers/controller.helper");
const { data } = require("../../core/logger");
const lodash = require("lodash");
const userService = require("../auth/user.service");
@ -17,41 +21,34 @@ const userService = require("../auth/user.service");
const MODULE_NAME = "[eventInscription.controller]";
const controllerOptions = { MODULE_NAME };
async function refreshConfirmed(inscription) {
if (!inscription) {
throw new Error("Error al eliminar inscripción, no puedo cambiar confirmados a la reserva asociada");
};
}
if (inscription.type === "online")
return true;
if (inscription.type === "online") return true;
//En caso de inscripciones
const EventOrReservationChangeId = inscription.reservationId
? inscription.reservationId
: inscription.overflowEventId
? inscription.overflowEventId
: inscription.eventId;
? inscription.overflowEventId
: inscription.eventId;
let NewConfirmed = 0;
let NewConfirmed = 0;
//Si la inscripción viene por una reserva modificamos los confirmados de la reserva
if (inscription.reservationId != null) {
console.log("Tengo reservation>>>>>>>>>>>>>>>>>>", inscription.reservationId);
NewConfirmed = await eventInscriptionService._getCountInscriptionsWithReservation(
EventOrReservationChangeId
);
NewConfirmed = await eventInscriptionService._getCountInscriptionsWithReservation(EventOrReservationChangeId);
//No se tienen en cuenta los marketinglist de las otras estructuras si lo tuviera seria esto
// marketingListId = (await eventReservationService._getReservaById(EventOrReservationChangeId))
// .marketing_list;
//Inscripcion de lista de espera bien de reserva o de evento de lista de espera
//Inscripcion de lista de espera bien de reserva o de evento de lista de espera
} else if (inscription.overflowEventId != null) {
console.log("Tengo overflow>>>>>>>>>>>>>>>>>>", inscription.overflowEventId);
NewConfirmed = await eventInscriptionService._getCountInscriptionsWithOverflowEventId(
EventOrReservationChangeId
);
NewConfirmed = await eventInscriptionService._getCountInscriptionsWithOverflowEventId(EventOrReservationChangeId);
//No se tienen en cuenta los marketinglist de las otras estructuras si lo tuviera seria esto
/// marketingListId = (await eventService._getEvent(EventOrReservationChangeId)).marketing_list;
@ -61,9 +58,9 @@ async function refreshConfirmed(inscription) {
EventOrReservationChangeId
);
//No se tienen en cuenta los marketinglist de las otras estructuras si lo tuviera seria esto
//No se tienen en cuenta los marketinglist de las otras estructuras si lo tuviera seria esto
//marketingListId = (await eventService._getEvent(EventOrReservationChangeId)).marketing_list;
};
}
//Actualizamos aforo del evento o de la reserva
if (inscription.reservationId != null) {
@ -78,7 +75,7 @@ async function refreshConfirmed(inscription) {
if (!(await eventService._updateConfirmedEvent(EventOrReservationChangeId, NewConfirmed))) {
throw new Error("Error al eliminar inscripción, no puedo cambiar confirmados a la inscripcion");
}
};
}
}
const extraControllers = {
@ -88,21 +85,19 @@ const extraControllers = {
prepareDataInscription: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
//Si no viene type es porque es una inscripción con la app antigua y el valor por defecto es onsite
//Si no viene type es porque es una inscripción con la app antigua y el valor por defecto es onsite
let typeInscription = "onsite";
if ((req.body.type) && (req.body.type === "online"))
typeInscription = "online";
if (req.body.type && req.body.type === "online") typeInscription = "online";
//Si viene code es la appa antigua o la nueva
if (((req.body.code) && (req.body.code !== ""))
|| ((req.body.group_size) && (req.body.group_size > 1)))
//Si viene code es la appa antigua o la nueva
if ((req.body.code && req.body.code !== "") || (req.body.group_size && req.body.group_size > 1))
typeInscription = typeInscription + " group";
let dataInscription = {
eventId: params.params.id,
reservationCode: req.user ? req.body.code : Buffer.from(req.body.code, "base64").toString("ascii"),
type: typeInscription,
groupSize: req.body.group_size ? req.body.group_size : 1, //Si no viene group_size será uno porque es una inscripcion de la APP antigua
groupSize: req.body.group_size ? req.body.group_size : 1, //Si no viene group_size será uno porque es una inscripcion de la APP antigua
source: req.user ? "app" : "web", //En el caso de tener ya usuario viene por APP sino viene por web
validated: false, //si no esta validado la inscripción es a la lista de espera
inscriptionsWithoutReservationAndOverflowCount: null, //nº total de inscritos sin reserva y sin overflow asignada
@ -162,16 +157,15 @@ const extraControllers = {
);
if (dataInscription.inscription) {
console.log("esta es la inscripcion que ya tengo>>>>",
dataInscription.inscription
);
console.log("esta es la inscripcion que ya tengo>>>>", dataInscription.inscription);
//Si la inscripcion no tiene reserva o la tiene y es la misma de la insripcion devuelvo la inscripcion
if ((!dataInscription.inscription.reservationId)
|| ((dataInscription.reservation) && (dataInscription.inscription.reservationId == dataInscription.reservation.id)))
if (
!dataInscription.inscription.reservationId ||
(dataInscription.reservation && dataInscription.inscription.reservationId == dataInscription.reservation.id)
)
return handleResultResponse(dataInscription.inscription, null, params, res, httpStatus.OK);
//En caso contrario devuelvo la plaza a la reserva que tenia la inscripción anterior y apunto la inscripción a la nueva reserva
//ACTUALIZAMOS LA RESERVA DE LA INSCRIPCION CON LA NUEVA Y CAMBIAMOS COMFIRMADOS DEVOLVIENDO LA INSCRIPCIÓN CON LA NUEVA RESERVA
let CountConfirmedOldReservation = await eventInscriptionService._getCountInscriptionsWithReservation(
@ -198,11 +192,10 @@ const extraControllers = {
dataInscription.inscription = await eventInscriptionService._getInscriptionById(dataInscription.inscription.id);
return handleResultResponse(dataInscription.inscription, null, params, res, httpStatus.OK);
};
}
} catch (error) {
return handleResultResponse("Error checkInscriptionByUser", error, params, res, httpStatus.NOT_FOUND);
};
}
next();
},
@ -226,17 +219,16 @@ const extraControllers = {
inscription.code_ticket_qr = await QRHelper.getInscriptionQRCode(member.qrConfig);
//Si el usuario de la inscripción no es tutor limpiamos la información de la reserva
if (inscription.user.profile !== 'tutor')
if (inscription.reservation) inscription.reservation.assistants = null;
if (inscription.user.profile !== "tutor") if (inscription.reservation) inscription.reservation.assistants = null;
if (inscription.reservation === null) {
console.log('asigno green');
inscription.color = 'green';
console.log("asigno green");
inscription.color = "green";
/* parche */
inscription.reservation = {
color: 'green',
description: 'Entrada',
color: "green",
description: "Entrada",
};
}
@ -268,7 +260,6 @@ const extraControllers = {
}
},
///////////////////////////////////////////////////////////////////
//Esta función se llama solo desde APP
//Inscripción sin CODIGO DE RESERVA, SE MODIFICA EL CONFIRMED DEL EVENTO, YA QUE SE DESCONTARA DEL AFORO DEL EVENTO
@ -280,13 +271,7 @@ const extraControllers = {
let dataInscription = res.locals.dataInscription;
if (!dataInscription || !dataInscription.event)
return handleResultResponse(
"Error prepareDataInscription requerida",
null,
params,
res,
httpStatus.NOT_FOUND
);
return handleResultResponse("Error prepareDataInscription requerida", null, params, res, httpStatus.NOT_FOUND);
let dataUser = res.locals.dataUser;
if (!dataUser)
@ -302,7 +287,6 @@ const extraControllers = {
);
try {
//ONLINE
//Si es una inscripcion online no se validan aforos se crea inscripción y ya esta
if (dataInscription.type === "online" || dataInscription.type === "online group") {
@ -317,23 +301,22 @@ const extraControllers = {
null
);
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ENTRADA ONLINE", dataInscription.inscription);
};
}
//ONSITE INDIVIDUAL
if (!dataInscription.inscription) {
let inscriptionsWithoutReservationAndOverflowCount =
await eventInscriptionService._getCountInscriptionsWithoutReservationAndOverflow(dataInscription.event.id);
++inscriptionsWithoutReservationAndOverflowCount;
console.log('Vamos a ver si hay aforo>>>>', inscriptionsWithoutReservationAndOverflowCount)
console.log("Vamos a ver si hay aforo>>>>", inscriptionsWithoutReservationAndOverflowCount);
//COMPROBAMOS SI ES VALIDO O HAY QUE APUNTARLE A LA LISTA DE ESPERA DEL EVENTO
if (
dataInscription.event.sold_out == 0 &&
dataInscription.event.assistants >= inscriptionsWithoutReservationAndOverflowCount
) {
dataInscription.validated = true;
console.log('actualizamos afoorooo>>>');
console.log("actualizamos afoorooo>>>");
//Actualizamos aforo del evento y creamos inscripcion
if (
await eventService._updateConfirmedEvent(
@ -350,10 +333,11 @@ const extraControllers = {
dataInscription.source,
null,
null
)
} catch (error) { console.log('SSSSSSSSSSSSSSSSSSSSSSSSS', error) }
}
else
);
} catch (error) {
console.log("SSSSSSSSSSSSSSSSSSSSSSSSS", error);
}
} else
return handleResultResponse(
"No se ha podido actualizar el aforo del evento",
null,
@ -361,7 +345,7 @@ const extraControllers = {
res,
httpStatus.NOT_FOUND
);
console.log('Inscripcion hecha>>>', dataInscription.inscription);
console.log("Inscripcion hecha>>>", dataInscription.inscription);
//Ponemos el evento en SOLD_OUT
if (dataInscription.event.assistants == inscriptionsWithoutReservationAndOverflowCount)
@ -381,7 +365,7 @@ const extraControllers = {
res,
httpStatus.NOT_FOUND
);
};
}
//recuperamos la cantidad de apuntados al evento overflow (lista de espera)
let ConfirmedWaitList = await eventInscriptionService._getCountInscriptionsWithOverflowEventId(
@ -389,8 +373,10 @@ const extraControllers = {
);
//recuperamos aforo de la lista de espera
dataInscription.overflow_event = await eventService._getEvent(dataInscription.event.overflow_eventId);
console.log("cantidad apuntados a lista de espera asociado, aforo >>>>>>>>>>>>>>>>>>>>>",
ConfirmedWaitList, dataInscription.overflow_event.assistants
console.log(
"cantidad apuntados a lista de espera asociado, aforo >>>>>>>>>>>>>>>>>>>>>",
ConfirmedWaitList,
dataInscription.overflow_event.assistants
);
//Si no hay espacio a lista de espera damos el mismo error que no hay lista de espera
@ -403,12 +389,10 @@ const extraControllers = {
res,
httpStatus.NOT_FOUND
);
};
}
//Creamos inscripción a lista de espera
if (
await eventService._updateConfirmedEvent(dataInscription.event.overflow_eventId, ConfirmedWaitList)
) {
if (await eventService._updateConfirmedEvent(dataInscription.event.overflow_eventId, ConfirmedWaitList)) {
dataInscription.inscription = await eventInscriptionService._createInscription(
dataInscription.event.id,
dataUser.userResult.user.id,
@ -421,7 +405,7 @@ const extraControllers = {
} else {
console.log("No se ha podido actualizar el aforo de la lista de espera del evento");
return handleResultResponse(
"o se ha podido actualizar el aforo de la lista de espera del evento",
"No se ha podido actualizar el aforo de la lista de espera del evento",
null,
params,
res,
@ -429,28 +413,35 @@ const extraControllers = {
);
}
} //FIN APUNTARSE A la lista de espera si se puede
};
}
dataInscription.inscription = await dataInscription.inscription.toJSON();
//Incluimos correo en sendinblue
try {
marketingListService.addMarketingList(dataUser, dataInscription);
} catch (error) { console.log('Se ha producido un error al añadir a SenINBlue>>>>>>>>>>>>>>>>><<', error); }
} catch (error) {
console.log("Se ha producido un error al añadir a Hubspot >>>>>>>>>>>>>>>>>", error);
}
//Mandamos correo con entrada o lista de espera
try {
mailService.sendEmailConfirm(dataUser, dataInscription);
} catch (error) { console.log('Se ha producido un error al enviar mail>>>>>>>>>>>>>>>>><<', error); }
} catch (error) {
console.log("Se ha producido un error al enviar mail>>>>>>>>>>>>>>>>><<", error);
}
return handleResultResponse(await dataInscription.inscription, null, params, res, httpStatus.CREATED);
} catch (Error) {
return handleResultResponse("Error al crear la incripción createInscription", null, params, res, httpStatus.NOT_FOUND);
return handleResultResponse(
"Error al crear la incripción createInscription",
null,
params,
res,
httpStatus.NOT_FOUND
);
}
},
deleteInscription: async (req, res, next) => {
const params = extractParamsFromRequest(req, res, {});
const user = req.user;
@ -469,9 +460,15 @@ const extraControllers = {
if (!inscription || inscription.userId !== user.id)
return handleResultResponse("Inscription no encontrada", null, params, res, httpStatus.NOT_FOUND);
//En el caso de ser una inscripción grupal y el tutor se quiere quitar, se podrá hacer solo en el caso de que en la reserva no haya ya confirmados
//En el caso de ser una inscripción grupal y el tutor se quiere quitar, se podrá hacer solo en el caso de que en la reserva no haya ya confirmados
if (inscription.user.profile === "tutor" && inscription.reservation && inscription.reservation.confirmed > 1)
return handleResultResponse("No se pudo eliminar inscripción por ser tutor de grupo y tener alumnos apuntados, pongase en contacto con nosotros", null, params, res, httpStatus.NOT_FOUND)
return handleResultResponse(
"No se pudo eliminar inscripción por ser tutor de grupo y tener alumnos apuntados, pongase en contacto con nosotros",
null,
params,
res,
httpStatus.NOT_FOUND
);
//Borramos inscripción
if ((await eventInscriptionService._deleteInscription(inscription.id)) > 0) {
@ -479,41 +476,56 @@ const extraControllers = {
//En todos los casos en el que se elimine una inscripción hay que refrescar los confirmados de la reserva o del evento
//en el caso de ser un tutor que ha realizado una reserva y solo está el confirmado, se borra y punto no se actualiza nada
if (inscription.user.profile === "tutor" && inscription.reservation && inscription.reservation.confirmed === 1) {
if (
inscription.user.profile === "tutor" &&
inscription.reservation &&
inscription.reservation.confirmed === 1
) {
//Eliminamos la reserva hecha del centro aliado
if (!((await eventReservationService._deleteReservation(inscription.reservation.id)) > 0))
return handleResultResponse("No se pudo eliminar inscripción por ser tutor de grupo online y tener alumnos apuntados, pongase en contacto con nosotros", null, params, res, httpStatus.NOT_FOUND);
return handleResultResponse(
"No se pudo eliminar inscripción por ser tutor de grupo online y tener alumnos apuntados, pongase en contacto con nosotros",
null,
params,
res,
httpStatus.NOT_FOUND
);
if (inscription.reservation.state === 'publish' && lodash.words(inscription.type).includes("onsite")) {
if (inscription.reservation.state === "publish" && lodash.words(inscription.type).includes("onsite")) {
const eventOfReservation = await eventService._getEvent(inscription.reservation.eventId);
//Modificamos los asistentes de evento (AFORO) para añadir las plazas de la reserva eliminada
const newAforo = eventOfReservation.assistants + inscription.reservation.assistants;
if (!(await eventService._updateAssistantsEvent(eventOfReservation.id, newAforo)))
return handleResultResponse("No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas", null, params, res, httpStatus.NOT_FOUND);
return handleResultResponse(
"No se ha podido actualizar el aforo del evento, para reservar las plazas solicitadas",
null,
params,
res,
httpStatus.NOT_FOUND
);
}
}
else
//En el caso de ser cualquier usuario o un tutor inscrito de forma libre o a una reserva de la que no es titular
//Actualizamos confirmados asistentes
refreshConfirmed(inscription);
}
else
return handleResultResponse("No se pudo eliminar inscripción", null, params, res, httpStatus.NOT_FOUND);
else refreshConfirmed(inscription);
} else return handleResultResponse("No se pudo eliminar inscripción", null, params, res, httpStatus.NOT_FOUND);
//Quitamos correo en sendinblue
try {
await marketingListService._deleteMember(marketingListId, inscription.user.email);
} catch (error) { console.log('Se ha producido un error al eliminar de SenINBlue>>>>>>>>>>>>>>>>><<', error); }
await marketingListService._deleteMember(marketingListId, inscription.user.email, inscription);
} catch (error) {
console.log("Se ha producido un error al eliminar de SenINBlue>>>>>>>>>>>>>>>>><<", error);
}
//Mandamos correo de confirmación de eliminación
try {
mailService.sendEmailCancelate(inscription);
} catch (error) { console.log('Se ha producido un error al enviar mail>>>>>>>>>>>>>>>>><<', error); }
} catch (error) {
console.log("Se ha producido un error al enviar mail>>>>>>>>>>>>>>>>><<", error);
}
console.log(">>>>>>>>>>>>>>Inscripcion eliminada con todos los pasos");
return handleResultResponse("Inscripción eliminada", null, params, res, httpStatus.DELETEOK);
} catch (error) {
console.log("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeerrrrrrrrrrrrrrrrrrorrrr", error);
return handleResultResponse("Error al eliminar inscripción", null, params, res, httpStatus.NOT_FOUND);
@ -521,7 +533,6 @@ const extraControllers = {
},
deleteInscriptionsByUser: async (req, res, next) => {
try {
//const context = buildContext(req, config);
//const user = context.user ? context.user : null;
@ -538,10 +549,7 @@ const extraControllers = {
} catch (error) {
console.error(error);
}
}
},
};
module.exports = generateControllers(eventInscriptionService, extraControllers, controllerOptions);

View File

@ -5,7 +5,6 @@ const _ = require("lodash");
const moment = require("moment");
const { generateService, parseParamsToFindOptions } = require("../../helpers/service.helper");
const models = require("../../core/models");
const marketing = require("../../helpers/sendinblue.helper");
const Sequelize = require("sequelize");
const xlsx = require("node-xlsx");
const fs = require("fs");
@ -37,9 +36,9 @@ const extraMethods = {
_fillInscriptionColor: (inscription) => {
if (inscription && inscription.type) {
const isVirtual = inscription.type === "online" || inscription.type === "online group";
if ((inscription.reservationId === null) && (!isVirtual)) {
if (inscription.reservationId === null && !isVirtual) {
// Inscripción normal
inscription.color = 'green';
inscription.color = "green";
}
}
@ -229,7 +228,6 @@ const extraMethods = {
},
_deleteInscriptionByUser: (userId) => {
return models.EventInscription.destroy({
where: {
userId: userId,
@ -239,7 +237,6 @@ const extraMethods = {
//Elimina todas las inscripciones de una determinada reserva/invitacion
_deleteInscriptionsByReservation: (reservationId) => {
return models.EventInscription.destroy({
where: {
reservationId: reservationId,
@ -280,23 +277,19 @@ const extraMethods = {
);
},
_getInscriptionsWithoutMemberId: (eventId) => {
return models.EventInscription.scope(["includeEventAndVenue", "includeReservation", "defaultScope"]).findAll({
where: {
eventId: eventId,
marketing_memberId: null
marketing_memberId: null,
},
});
},
_getInscriptionsExcel: (user, eventId, callback) => {
console.log("DESCARGA EXCEL INSCRIPCIONES TOTALES>>>>>>>> ");
console.log(">>>>>>>>>>>>>>>>>>>><consulta con eventId:", eventId);
models.EventInscription.findAll({
where: {
eventId: eventId,
@ -397,10 +390,6 @@ const extraMethods = {
);
});
},
};
module.exports = generateService(models.EventInscription, extraMethods);

View File

@ -1,7 +1,7 @@
"use strict";
const eventInscriptionService = require("./events_inscriptions.service");
const marketing = require("../../helpers/sendinblue.helper");
const marketing = require("../../helpers/hubspot.helper"); // <--- HUBSPOT
////////////////////////////////////////////////////////////////////
// dataInscription {incription:{...}, event:{...}, reservation:{...}, user:{...}}
@ -16,24 +16,22 @@ const marketing = require("../../helpers/sendinblue.helper");
marketingListOfInscription = dataInscription.event.marketingList;
*/
function _generateMarketingDTO(dataInscription) {
console.log('entro _generateMarketingDTO >>> ', dataInscription);
console.log("entro _generateMarketingDTO >>> ", dataInscription);
let { event, inscription, user, reservation } = dataInscription;
let inscriptionDTO = {};
//En el caso de generar el MarketingDTO para el ticket de la APP, fallaba porque el propio dataInscription, es la inscription y de el cuelgan user, event y reservation
//Sin embargo cuando se llama desde addMarketingList la inscription cualga de dataInscripcion como el resto de elementos
if (dataInscription)
if (!inscription)
inscription = dataInscription;
if (dataInscription) if (!inscription) inscription = dataInscription;
if (!event) {
throw new Error('Falta datos del evento en la inscripción (_generateMarketingDTO)');
throw new Error("Falta datos del evento en la inscripción (_generateMarketingDTO)");
}
if (!event.marketing_list) {
console.warn('Falta rellenar la lista de Sendinblue en el evento (_generateMarketingDTO)', event.name);
}
/*if (!event.marketing_list) { <-- YA NO HACE FALTA CON HUBSPOT
console.warn("Falta rellenar la lista de Sendinblue en el evento (_generateMarketingDTO)", event.name);
}*/
if (inscription) {
inscriptionDTO.id = inscription.id;
@ -41,6 +39,8 @@ function _generateMarketingDTO(dataInscription) {
inscriptionDTO.event_name = event.name ? event.name : "N/A";
inscriptionDTO.event_date = event.init_date ? event.init_date : "N/A";
inscriptionDTO.event_marketing_list = event ? event.marketing_list : null;
inscriptionDTO.event_country = event ? event.location.country : null;
inscriptionDTO.event_city = event ? event.location.city : null;
inscriptionDTO.date_inscription = inscription.date;
inscriptionDTO.code_ticket = inscription.code_ticket;
inscriptionDTO.validated = inscription.validated;
@ -51,18 +51,24 @@ function _generateMarketingDTO(dataInscription) {
inscriptionDTO.qrConfig = null;
inscriptionDTO.qrCode = null;
/** HUBSPOT */
// inscriptionDTO.event_city = event.venue ? event.venue.city : null;
// inscriptionDTO.event_country = event.venue ? event.venue.country : null;
if (user) {
//Era para mailchimp
//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.phone = user.phone; // <-- HUBSPOT
inscriptionDTO.profile = user.profile; // <-- HUBSPOT
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;
}
@ -70,64 +76,53 @@ function sleep(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
async function _addMember(inscriptionDTO) {
console.debug('>>>> _addMember', inscriptionDTO.email);
console.debug('>>>> event_marketing_list', inscriptionDTO.event_marketing_list);
console.debug(">>>> _addMember", inscriptionDTO.email);
console.debug(">>>> event_marketing_list", inscriptionDTO.event_marketing_list);
// console.debug(member);
return new Promise(function (resolve, reject) {
if (!inscriptionDTO.event_marketing_list) {
// || !member.validated) {
resolve(inscriptionDTO);
} else {
marketing
.addMemberToList(inscriptionDTO.event_marketing_list, inscriptionDTO)
.then(function (result) {
resolve(result.ID);
})
.catch(function (error) {
reject(error);
});
}
//if (!inscriptionDTO.event_marketing_list) {
// || !member.validated) {
//resolve(inscriptionDTO);
//} else {
/**
* HUBSPOT
*/
marketing
.addMemberToList(inscriptionDTO.event_marketing_list, inscriptionDTO)
.then(function (result) {
resolve(result.ID);
})
.catch(function (error) {
reject(error);
});
//}
});
}
async function _deleteMember(idLista, email) {
console.debug(
"Elimino miembro de la lista de marketing>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<",
email,
idLista,
);
async function _deleteMember(idLista, email, inscription = undefined) {
console.debug("Elimino miembro de la lista de marketing>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<", email, idLista);
return new Promise(function (resolve, reject) {
if (!idLista || !email) {
resolve();
} else {
resolve(marketing.deleteMemberFromList(idLista, email));
}
resolve(marketing.deleteMemberFromList(idLista, email, inscription));
});
}
async function addMarketingList(dataUser, dataInscription) {
dataInscription.user = dataUser.userResult.user;
return _addMember(_generateMarketingDTO(dataInscription));
}
async function syncronizeEventWithMarketingList(eventId) {
let result = false;
try {
let inscriptionsToSync = await eventInscriptionService._getInscriptionsWithoutMemberId(eventId);
for (var i = 0; i < inscriptionsToSync.length; i++) {
const item = inscriptionsToSync[i].get({
plain: true
plain: true,
});
//Adaptamos el objeto a lo que espera _generateMarketingDTO
// dataInscription {incription:{...}, event:{...}, reservation:{...}, user:{...}}
@ -139,8 +134,7 @@ async function syncronizeEventWithMarketingList(eventId) {
// console.log(marketingDTO)
// _deleteMember(marketingDTO.event_marketing_list, marketingDTO.email)
});
};
}
result = true;
return result;
@ -149,24 +143,23 @@ async function syncronizeEventWithMarketingList(eventId) {
}
}
function userToMarketingDTO(user) {
const result = {};
result.email = user.email ? user.email : '';
result.name = user.name ? user.name : '';
result.surname = user.surname ? user.surname : '';
result.userId = user.id ? user.id : '';
result.entity = user.Entity ? user.Entity.name : '';
result.email = user.email ? user.email : "";
result.name = user.name ? user.name : "";
result.surname = user.surname ? user.surname : "";
result.phone = user.phone ? user.phone : "";
result.userId = user.id ? user.id : "";
result.profile = user.profile ? user.profile : "";
result.entity = user.Entity ? user.Entity.name : "";
return result;
}
module.exports = {
syncronizeEventWithMarketingList,
addMarketingList,
_deleteMember,
_generateMarketingDTO,
userToMarketingDTO,
};

View File

@ -6,7 +6,7 @@
"license": "ISC",
"main": "server.js",
"scripts": {
"start": "NODE_ENV=development nodemon server.js",
"start": "NODE_ENV=development nodemon --inspect=0.0.0.0 server.js",
"start:prod": "NODE_ENV=production pm2 start server.js -n 'api3' -i 4 --node-args='--max_old_space_size=4096'",
"lint": "eslint **/*.js --quiet",
"test": "echo \"Error: no test specified\" && exit 1"
@ -20,6 +20,7 @@
"nodemon": "^1.18.9"
},
"dependencies": {
"@hubspot/api-client": "^11.1.0",
"apicache": "^1.4.0",
"args-list": "^0.3.3",
"async": "^2.6.2",