From b7bbef80353d3a365daa4b69184d3959e447aa9c Mon Sep 17 00:00:00 2001 From: Horacio Daniel Ros Date: Fri, 14 Aug 2026 19:34:00 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20agregar=20soporte=20para=20cancelaci?= =?UTF-8?q?=C3=B3n=20de=20citas=20por=20parte=20del=20cliente=20en=20notif?= =?UTF-8?q?icaciones?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Appointments/Appointments.Interface.ts | 1 + .../src/Models/Appointments/Appointments.ts | 28 +++++++++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/server/src/Models/Appointments/Appointments.Interface.ts b/server/src/Models/Appointments/Appointments.Interface.ts index 2a4ef36..b888010 100644 --- a/server/src/Models/Appointments/Appointments.Interface.ts +++ b/server/src/Models/Appointments/Appointments.Interface.ts @@ -46,6 +46,7 @@ export type SendAppointmentNotificationParams = { systemToken?: string; type: APPOINTMENT_NOTIFICATION_TYPE; channel?: "whatsapp" | "email"; + allowClientCancellation?: boolean; }; export type CreateImmediateAppointmentNotificationJobsParams = { diff --git a/server/src/Models/Appointments/Appointments.ts b/server/src/Models/Appointments/Appointments.ts index f347b2d..e080e08 100644 --- a/server/src/Models/Appointments/Appointments.ts +++ b/server/src/Models/Appointments/Appointments.ts @@ -2491,12 +2491,14 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise { sessionUser: data.sessionUser, type: APPOINTMENT_NOTIFICATION_TYPE.CANCELLATION, channel: "email", + allowClientCancellation: true, }); const wapContent = await this.tryToSendNotification({ appointmentId: String(checkAppointment._id), sessionUser: data.sessionUser, type: APPOINTMENT_NOTIFICATION_TYPE.CANCELLATION, channel: "whatsapp", + allowClientCancellation: true, }); await this.createCancellationNotificationJobs({ @@ -2650,6 +2652,14 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise { throw new Error("La compañia no existe"); } + const checkClient = await ClientsManager.clients.findOne({ + _id: String(checkAppointment.clientId), + }); + + if (!checkClient) { + throw new Error("El cliente no existe"); + } + const hasSystemToken = this.hasValidSystemToken(data.systemToken); if (!hasSystemToken) { @@ -2657,19 +2667,19 @@ public async updateAppointment(data: UpdateAppointmentParams): Promise { throw new Error("No se ha encontrado el usuario o no tiene permisos para realizar esta acción"); } - if (!(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN))) { + const isAuthorizedClientCancellation = + data.allowClientCancellation === true && + data.type === APPOINTMENT_NOTIFICATION_TYPE.CANCELLATION && + String(checkClient.userId) === data.sessionUser; + + if ( + !isAuthorizedClientCancellation && + !(await EmployeesList.checkPermission(companyCheck, data.sessionUser, EmployeeRoles.ADMIN)) + ) { throw new Error(NoPermissionMessage()); } } - const checkClient = await ClientsManager.clients.findOne({ - _id: String(checkAppointment.clientId), - }); - - if (!checkClient) { - throw new Error("El cliente no existe"); - } - const checkEmployee = await EmployeesList.employees.findOne({ _id: String(checkAppointment.employeeId), });