/**
* Add appointment request email templates to system_email_templates
*
* This migration adds four email templates for the appointment request system:
* 1. appointment-request-received - Confirmation to client/requester
* 2. appointment-request-approved - Approval notification to client/requester
* 3. appointment-request-declined - Decline notification to client/requester
* 4. new-appointment-request - Notification to MSP staff for approval
*
* Templates are created for English initially. Additional languages can be added
* via subsequent migrations or seed files.
*/
exports.up = async function(knex) {
console.log('Adding appointment request email templates...');
// Ensure Appointments category exists
let appointmentsCategory = await knex('notification_categories')
.where({ name: 'Appointments' })
.first();
if (!appointmentsCategory) {
[appointmentsCategory] = await knex('notification_categories')
.insert({
name: 'Appointments',
description: 'Appointment request and scheduling notifications',
is_enabled: true,
is_default_enabled: true
})
.returning('*');
console.log('✓ Created Appointments notification category');
}
// Create notification subtypes for appointment requests
const subtypeNames = {
'appointment-request-received': 'Confirmation that appointment request was received',
'appointment-request-approved': 'Notification that appointment request was approved',
'appointment-request-declined': 'Notification that appointment request was declined',
'new-appointment-request': 'New appointment request notification for MSP staff'
};
const subtypeIds = {};
for (const [name, description] of Object.entries(subtypeNames)) {
let subtype = await knex('notification_subtypes')
.where({ name })
.first();
if (!subtype) {
[subtype] = await knex('notification_subtypes')
.insert({
category_id: appointmentsCategory.id,
name,
description,
is_enabled: true,
is_default_enabled: true
})
.returning('*');
console.log(`✓ Created notification subtype: ${name}`);
}
subtypeIds[name] = subtype.id;
}
// English (en) templates
const templates = [
// 1. Appointment Request Received - To client/requester
{
name: 'appointment-request-received',
language_code: 'en',
subject: 'Appointment Request Received - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `
Appointment Request Received
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Thank you for submitting your appointment request. We have received your request and our team will review it shortly.
Reference: {{referenceNumber}}
Request Details
Service:
{{serviceName}}
Requested Date:
{{requestedDate}}
Requested Time:
{{requestedTime}}
Duration:
{{duration}} minutes
{{#if preferredTechnician}}
Preferred Technician:
{{preferredTechnician}}
{{/if}}
What happens next?
Our team will review your request and confirm availability. You will receive an email notification once your appointment has been approved or if any changes are needed. We typically respond within {{responseTime}}.
If you have any questions or need to make changes to your request, please contact us at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}.
`,
text_content: `Appointment Request Received
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Thank you for submitting your appointment request. We have received your request and our team will review it shortly.
Reference Number: {{referenceNumber}}
REQUEST DETAILS:
Service: {{serviceName}}
Requested Date: {{requestedDate}}
Requested Time: {{requestedTime}}
Duration: {{duration}} minutes
{{#if preferredTechnician}}Preferred Technician: {{preferredTechnician}}{{/if}}
WHAT HAPPENS NEXT?
Our team will review your request and confirm availability. You will receive an email notification once your appointment has been approved or if any changes are needed. We typically respond within {{responseTime}}.
If you have any questions or need to make changes to your request, please contact us at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}.`
},
// 2. Appointment Request Approved - To client/requester
{
name: 'appointment-request-approved',
language_code: 'en',
subject: 'Appointment Confirmed - {{serviceName}} on {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `
Appointment Confirmed
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Great news! Your appointment request has been approved and confirmed. We look forward to serving you.
Your Appointment
Service
{{serviceName}}
Date
{{appointmentDate}}
Time
{{appointmentTime}}
Duration
{{duration}} minutes
{{#if technicianName}}
Assigned Technician
{{technicianName}}{{#if technicianEmail}}
Email: {{technicianEmail}}{{/if}}{{#if technicianPhone}}
Phone: {{technicianPhone}}{{/if}}
{{/if}}
{{#if calendarLink}}
{{/if}}
{{#if cancellationPolicy}}
Cancellation Policy
{{cancellationPolicy}}
{{/if}}
If you need to reschedule or cancel this appointment, please contact us at least {{minimumNoticeHours}} hours in advance at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}.
We'll send you a reminder before your appointment. See you soon!
`,
text_content: `Appointment Confirmed
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Great news! Your appointment request has been approved and confirmed. We look forward to serving you.
YOUR APPOINTMENT:
Service: {{serviceName}}
Date: {{appointmentDate}}
Time: {{appointmentTime}}
Duration: {{duration}} minutes
{{#if technicianName}}
ASSIGNED TECHNICIAN:
{{technicianName}}
{{#if technicianEmail}}Email: {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Phone: {{technicianPhone}}{{/if}}
{{/if}}
{{#if calendarLink}}
Add to Calendar: {{calendarLink}}
{{/if}}
{{#if cancellationPolicy}}
CANCELLATION POLICY:
{{cancellationPolicy}}
{{/if}}
If you need to reschedule or cancel this appointment, please contact us at least {{minimumNoticeHours}} hours in advance at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}.
We'll send you a reminder before your appointment. See you soon!`
},
// 3. Appointment Request Declined - To client/requester
{
name: 'appointment-request-declined',
language_code: 'en',
subject: 'Appointment Request Update - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `
Appointment Request Update
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Thank you for your interest in scheduling an appointment with us. Unfortunately, we are unable to accommodate your request at the requested time.
Original Request
Service:
{{serviceName}}
Requested Date:
{{requestedDate}}
Requested Time:
{{requestedTime}}
Reference:
{{referenceNumber}}
{{#if declineReason}}
{{/if}}
We'd Still Love to Help
We apologize for any inconvenience. We encourage you to submit a new request for an alternative date and time that works better with our availability.
{{#if requestNewAppointmentLink}}
Request Another Time
{{/if}}
If you have any questions or would like assistance finding an available time slot, please don't hesitate to contact us at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}. Our team is here to help you find a time that works.
`,
text_content: `Appointment Request Update
Hello{{#if requesterName}} {{requesterName}}{{/if}},
Thank you for your interest in scheduling an appointment with us. Unfortunately, we are unable to accommodate your request at the requested time.
ORIGINAL REQUEST:
Service: {{serviceName}}
Requested Date: {{requestedDate}}
Requested Time: {{requestedTime}}
Reference: {{referenceNumber}}
{{#if declineReason}}
REASON:
{{declineReason}}
{{/if}}
WE'D STILL LOVE TO HELP
We apologize for any inconvenience. We encourage you to submit a new request for an alternative date and time that works better with our availability.
{{#if requestNewAppointmentLink}}
Request Another Time: {{requestNewAppointmentLink}}
{{/if}}
If you have any questions or would like assistance finding an available time slot, please don't hesitate to contact us at {{contactEmail}}{{#if contactPhone}} or call {{contactPhone}}{{/if}}. Our team is here to help you find a time that works.`
},
// 4. New Appointment Request - To MSP staff
{
name: 'new-appointment-request',
language_code: 'en',
subject: 'New Appointment Request - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `
New Appointment Request
Team,
A new appointment request has been submitted and requires your review and approval.
Requester Information
{{requesterName}}
{{requesterEmail}}
{{#if requesterPhone}}
{{requesterPhone}}
{{/if}}
{{#if companyName}}
Company: {{companyName}}
{{/if}}
{{#if clientName}}
Client: {{clientName}}
{{/if}}
Request Details
Reference: {{referenceNumber}}
Submitted: {{submittedAt}}
{{#if linkedTicket}}
Ticket: #{{linkedTicket}}
{{/if}}
Appointment Details
Service:
{{serviceName}}
Requested Date:
{{requestedDate}}
Requested Time:
{{requestedTime}}
Duration:
{{duration}} minutes
{{#if preferredTechnician}}
Preferred Technician:
{{preferredTechnician}}
{{/if}}
{{#if description}}
Additional Notes
"{{description}}"
{{/if}}
Please review this request and take appropriate action. The requester is waiting for confirmation.
`,
text_content: `New Appointment Request - Action Required
Team,
A new appointment request has been submitted and requires your review and approval.
REQUESTER INFORMATION:
Name: {{requesterName}}
Email: {{requesterEmail}}
{{#if requesterPhone}}Phone: {{requesterPhone}}{{/if}}
{{#if companyName}}Company: {{companyName}}{{/if}}
{{#if clientName}}Client: {{clientName}}{{/if}}
REQUEST DETAILS:
Reference: {{referenceNumber}}
Submitted: {{submittedAt}}
{{#if linkedTicket}}Ticket: #{{linkedTicket}}{{/if}}
Type: {{#if isAuthenticated}}Client Portal Request{{else}}Public Request{{/if}}
APPOINTMENT DETAILS:
Service: {{serviceName}}
Requested Date: {{requestedDate}}
Requested Time: {{requestedTime}}
Duration: {{duration}} minutes
{{#if preferredTechnician}}Preferred Technician: {{preferredTechnician}}{{/if}}
{{#if description}}
ADDITIONAL NOTES:
"{{description}}"
{{/if}}
{{#if approvalLink}}
REVIEW & APPROVE:
{{approvalLink}}
{{/if}}
Please review this request and take appropriate action. The requester is waiting for confirmation.`
},
// German (de) templates
{
name: 'appointment-request-received',
language_code: 'de',
subject: 'Terminanfrage erhalten - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `
Terminanfrage erhalten
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Vielen Dank für das Einreichen Ihrer Terminanfrage. Wir haben Ihre Anfrage erhalten und unser Team wird sie in Kürze prüfen.
Referenz: {{referenceNumber}}
Anfragedetails
Service:{{serviceName}}
Gewünschtes Datum:{{requestedDate}}
Gewünschte Uhrzeit:{{requestedTime}}
Dauer:{{duration}} Minuten
{{#if preferredTechnician}}
Bevorzugter Techniker:{{preferredTechnician}}
{{/if}}
Was passiert als nächstes?
Unser Team wird Ihre Anfrage prüfen und die Verfügbarkeit bestätigen. Sie erhalten eine E-Mail-Benachrichtigung, sobald Ihr Termin genehmigt wurde oder falls Änderungen erforderlich sind. Wir antworten in der Regel innerhalb von {{responseTime}}.
Wenn Sie Fragen haben oder Änderungen an Ihrer Anfrage vornehmen möchten, kontaktieren Sie uns bitte unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.
`,
text_content: `Terminanfrage erhalten
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Vielen Dank für das Einreichen Ihrer Terminanfrage. Wir haben Ihre Anfrage erhalten und unser Team wird sie in Kürze prüfen.
Referenznummer: {{referenceNumber}}
ANFRAGEDETAILS:
Service: {{serviceName}}
Gewünschtes Datum: {{requestedDate}}
Gewünschte Uhrzeit: {{requestedTime}}
Dauer: {{duration}} Minuten
{{#if preferredTechnician}}Bevorzugter Techniker: {{preferredTechnician}}{{/if}}
WAS PASSIERT ALS NÄCHSTES?
Unser Team wird Ihre Anfrage prüfen und die Verfügbarkeit bestätigen. Sie erhalten eine E-Mail-Benachrichtigung, sobald Ihr Termin genehmigt wurde oder falls Änderungen erforderlich sind. Wir antworten in der Regel innerhalb von {{responseTime}}.
Wenn Sie Fragen haben oder Änderungen an Ihrer Anfrage vornehmen möchten, kontaktieren Sie uns bitte unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-approved',
language_code: 'de',
subject: 'Termin bestätigt - {{serviceName}} am {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `
Termin bestätigt
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Gute Nachrichten! Ihre Terminanfrage wurde genehmigt und bestätigt. Wir freuen uns darauf, Sie zu bedienen.
Ihr Termin
Service{{serviceName}}
Datum{{appointmentDate}}
Uhrzeit{{appointmentTime}}
Dauer{{duration}} Minuten
{{#if cancellationPolicy}}
Stornierungsbedingungen
{{cancellationPolicy}}
{{/if}}
Wenn Sie diesen Termin verschieben oder stornieren möchten, kontaktieren Sie uns bitte mindestens {{minimumNoticeHours}} Stunden im Voraus unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.
`,
text_content: `Termin bestätigt
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Gute Nachrichten! Ihre Terminanfrage wurde genehmigt und bestätigt. Wir freuen uns darauf, Sie zu bedienen.
IHR TERMIN:
Service: {{serviceName}}
Datum: {{appointmentDate}}
Uhrzeit: {{appointmentTime}}
Dauer: {{duration}} Minuten
{{#if technicianName}}
ZUGEWIESENER TECHNIKER:
{{technicianName}}
{{#if technicianEmail}}E-Mail: {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Telefon: {{technicianPhone}}{{/if}}
{{/if}}
{{#if cancellationPolicy}}
STORNIERUNGSBEDINGUNGEN:
{{cancellationPolicy}}
{{/if}}
Wenn Sie diesen Termin verschieben oder stornieren möchten, kontaktieren Sie uns bitte mindestens {{minimumNoticeHours}} Stunden im Voraus unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-declined',
language_code: 'de',
subject: 'Terminanfrage Aktualisierung - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `
Terminanfrage Aktualisierung
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Vielen Dank für Ihr Interesse an einem Termin bei uns. Leider können wir Ihre Anfrage zum gewünschten Zeitpunkt nicht berücksichtigen.
{{#if declineReason}}
{{/if}}
Wir helfen Ihnen gerne weiter
Wir entschuldigen uns für die Unannehmlichkeiten. Wir ermutigen Sie, eine neue Anfrage für ein alternatives Datum und eine alternative Uhrzeit einzureichen, die besser zu unserer Verfügbarkeit passen.
Wenn Sie Fragen haben oder Hilfe bei der Suche nach einem verfügbaren Zeitfenster benötigen, kontaktieren Sie uns bitte unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.
`,
text_content: `Terminanfrage Aktualisierung
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Vielen Dank für Ihr Interesse an einem Termin bei uns. Leider können wir Ihre Anfrage zum gewünschten Zeitpunkt nicht berücksichtigen.
{{#if declineReason}}
GRUND:
{{declineReason}}
{{/if}}
WIR HELFEN IHNEN GERNE WEITER
Wir entschuldigen uns für die Unannehmlichkeiten. Wir ermutigen Sie, eine neue Anfrage für ein alternatives Datum und eine alternative Uhrzeit einzureichen.
Wenn Sie Fragen haben oder Hilfe bei der Suche nach einem verfügbaren Zeitfenster benötigen, kontaktieren Sie uns bitte unter {{contactEmail}}{{#if contactPhone}} oder rufen Sie an unter {{contactPhone}}{{/if}}.`
},
{
name: 'new-appointment-request',
language_code: 'de',
subject: 'Neue Terminanfrage - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `
Neue Terminanfrage
Team,
Eine neue Terminanfrage wurde eingereicht und erfordert Ihre Prüfung und Genehmigung.
Termindetails
Service: {{serviceName}}
Gewünschtes Datum: {{requestedDate}}
Gewünschte Uhrzeit: {{requestedTime}}
Dauer: {{duration}} Minuten
Bitte prüfen Sie diese Anfrage und ergreifen Sie entsprechende Maßnahmen. Der Antragsteller wartet auf Bestätigung.
`,
text_content: `Neue Terminanfrage - Aktion erforderlich
Team,
Eine neue Terminanfrage wurde eingereicht und erfordert Ihre Prüfung und Genehmigung.
ANFORDERER INFORMATIONEN:
Name: {{requesterName}}
E-Mail: {{requesterEmail}}
{{#if requesterPhone}}Telefon: {{requesterPhone}}{{/if}}
{{#if clientName}}Kunde: {{clientName}}{{/if}}
TERMINDETAILS:
Service: {{serviceName}}
Gewünschtes Datum: {{requestedDate}}
Gewünschte Uhrzeit: {{requestedTime}}
Dauer: {{duration}} Minuten
Bitte prüfen Sie diese Anfrage und ergreifen Sie entsprechende Maßnahmen.`
},
// Spanish (es), French (fr), Italian (it), Dutch (nl) templates
// Due to length, these are condensed versions with key translations in subject and text_content
// HTML content maintains minimal styling with translated text
// Spanish (es)
{
name: 'appointment-request-received',
language_code: 'es',
subject: 'Solicitud de cita recibida - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `Solicitud recibidaSolicitud recibida
Hola{{#if requesterName}} {{requesterName}}{{/if}},
Gracias por enviar su solicitud de cita. Hemos recibido su solicitud y nuestro equipo la revisará en breve.
Referencia: {{referenceNumber}}
Detalles de la solicitud
Servicio: {{serviceName}}
Fecha solicitada: {{requestedDate}}
Hora solicitada: {{requestedTime}}
Duración: {{duration}} minutos
Si tiene preguntas, contáctenos en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.
`,
text_content: `Solicitud de cita recibida
Hola{{#if requesterName}} {{requesterName}}{{/if}},
Gracias por enviar su solicitud de cita. Hemos recibido su solicitud y nuestro equipo la revisará en breve.
Número de referencia: {{referenceNumber}}
DETALLES DE LA SOLICITUD:
Servicio: {{serviceName}}
Fecha solicitada: {{requestedDate}}
Hora solicitada: {{requestedTime}}
Duración: {{duration}} minutos
Nuestro equipo revisará su solicitud y confirmará la disponibilidad. Recibirá una notificación por correo electrónico una vez que su cita haya sido aprobada.
Si tiene preguntas, contáctenos en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-approved',
language_code: 'es',
subject: 'Cita confirmada - {{serviceName}} el {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `Cita confirmada✓ Cita confirmada
Hola{{#if requesterName}} {{requesterName}}{{/if}},
¡Buenas noticias! Su solicitud de cita ha sido aprobada y confirmada.
Su cita
Servicio: {{serviceName}}
Fecha: {{appointmentDate}}
Hora: {{appointmentTime}}
Duración: {{duration}} minutos
{{#if technicianName}}Técnico asignado: {{technicianName}}
{{/if}}Si necesita reprogramar o cancelar, contáctenos con al menos {{minimumNoticeHours}} horas de anticipación en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.
`,
text_content: `Cita confirmada
Hola{{#if requesterName}} {{requesterName}}{{/if}},
¡Buenas noticias! Su solicitud de cita ha sido aprobada y confirmada.
SU CITA:
Servicio: {{serviceName}}
Fecha: {{appointmentDate}}
Hora: {{appointmentTime}}
Duración: {{duration}} minutos
{{#if technicianName}}
TÉCNICO ASIGNADO:
{{technicianName}}
{{#if technicianEmail}}Correo: {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Teléfono: {{technicianPhone}}{{/if}}
{{/if}}
Si necesita reprogramar o cancelar, contáctenos con al menos {{minimumNoticeHours}} horas de anticipación.`
},
{
name: 'appointment-request-declined',
language_code: 'es',
subject: 'Actualización de solicitud de cita - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `Actualización de citaActualización de solicitud de cita
Hola{{#if requesterName}} {{requesterName}}{{/if}},
Gracias por su interés. Lamentablemente, no podemos acomodar su solicitud en el momento solicitado.
{{#if declineReason}}{{/if}}Le animamos a enviar una nueva solicitud para una fecha y hora alternativa.
Si tiene preguntas, contáctenos en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.
`,
text_content: `Actualización de solicitud de cita
Hola{{#if requesterName}} {{requesterName}}{{/if}},
Gracias por su interés. Lamentablemente, no podemos acomodar su solicitud en el momento solicitado.
{{#if declineReason}}
MOTIVO:
{{declineReason}}
{{/if}}
Le animamos a enviar una nueva solicitud para una fecha y hora alternativa que funcione mejor con nuestra disponibilidad.
Si tiene preguntas, contáctenos en {{contactEmail}}{{#if contactPhone}} o llame al {{contactPhone}}{{/if}}.`
},
{
name: 'new-appointment-request',
language_code: 'es',
subject: 'Nueva solicitud de cita - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `Nueva solicitudNueva solicitud de cita
Equipo,
Se ha enviado una nueva solicitud de cita que requiere su revisión y aprobación.
Detalles de la cita
Servicio: {{serviceName}}
Fecha solicitada: {{requestedDate}}
Hora solicitada: {{requestedTime}}
Duración: {{duration}} minutos
Por favor revise esta solicitud y tome las medidas apropiadas.
`,
text_content: `Nueva solicitud de cita - Acción requerida
Equipo,
Se ha enviado una nueva solicitud de cita que requiere su revisión y aprobación.
DETALLES DE LA CITA:
Servicio: {{serviceName}}
Fecha solicitada: {{requestedDate}}
Hora solicitada: {{requestedTime}}
Duración: {{duration}} minutos
Por favor revise esta solicitud y tome las medidas apropiadas.`
},
// French (fr)
{
name: 'appointment-request-received',
language_code: 'fr',
subject: 'Demande de rendez-vous reçue - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `Demande reçueDemande reçue
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Merci d'avoir soumis votre demande de rendez-vous. Nous avons reçu votre demande et notre équipe l'examinera sous peu.
Référence : {{referenceNumber}}
Détails de la demande
Service : {{serviceName}}
Date demandée : {{requestedDate}}
Heure demandée : {{requestedTime}}
Durée : {{duration}} minutes
Si vous avez des questions, contactez-nous à {{contactEmail}}{{#if contactPhone}} ou appelez au {{contactPhone}}{{/if}}.
`,
text_content: `Demande de rendez-vous reçue
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Merci d'avoir soumis votre demande de rendez-vous. Nous avons reçu votre demande et notre équipe l'examinera sous peu.
Numéro de référence : {{referenceNumber}}
DÉTAILS DE LA DEMANDE :
Service : {{serviceName}}
Date demandée : {{requestedDate}}
Heure demandée : {{requestedTime}}
Durée : {{duration}} minutes
Notre équipe examinera votre demande et confirmera la disponibilité. Vous recevrez une notification par e-mail une fois votre rendez-vous approuvé.
Si vous avez des questions, contactez-nous à {{contactEmail}}{{#if contactPhone}} ou appelez au {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-approved',
language_code: 'fr',
subject: 'Rendez-vous confirmé - {{serviceName}} le {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `Rendez-vous confirmé✓ Rendez-vous confirmé
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Bonne nouvelle ! Votre demande de rendez-vous a été approuvée et confirmée.
Votre rendez-vous
Service : {{serviceName}}
Date : {{appointmentDate}}
Heure : {{appointmentTime}}
Durée : {{duration}} minutes
{{#if technicianName}}Technicien assigné : {{technicianName}}
{{/if}}Si vous devez reporter ou annuler, contactez-nous au moins {{minimumNoticeHours}} heures à l'avance à {{contactEmail}}{{#if contactPhone}} ou appelez au {{contactPhone}}{{/if}}.
`,
text_content: `Rendez-vous confirmé
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Bonne nouvelle ! Votre demande de rendez-vous a été approuvée et confirmée.
VOTRE RENDEZ-VOUS :
Service : {{serviceName}}
Date : {{appointmentDate}}
Heure : {{appointmentTime}}
Durée : {{duration}} minutes
{{#if technicianName}}
TECHNICIEN ASSIGNÉ :
{{technicianName}}
{{#if technicianEmail}}E-mail : {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Téléphone : {{technicianPhone}}{{/if}}
{{/if}}
Si vous devez reporter ou annuler, contactez-nous au moins {{minimumNoticeHours}} heures à l'avance.`
},
{
name: 'appointment-request-declined',
language_code: 'fr',
subject: 'Mise à jour de la demande de rendez-vous - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `Mise à jourMise à jour de la demande
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Merci de votre intérêt. Malheureusement, nous ne pouvons pas accepter votre demande au moment demandé.
{{#if declineReason}}{{/if}}Nous vous encourageons à soumettre une nouvelle demande pour une date et une heure alternatives.
Si vous avez des questions, contactez-nous à {{contactEmail}}{{#if contactPhone}} ou appelez au {{contactPhone}}{{/if}}.
`,
text_content: `Mise à jour de la demande de rendez-vous
Bonjour{{#if requesterName}} {{requesterName}}{{/if}},
Merci de votre intérêt. Malheureusement, nous ne pouvons pas accepter votre demande au moment demandé.
{{#if declineReason}}
RAISON :
{{declineReason}}
{{/if}}
Nous vous encourageons à soumettre une nouvelle demande pour une date et une heure alternatives qui correspondent mieux à notre disponibilité.
Si vous avez des questions, contactez-nous à {{contactEmail}}{{#if contactPhone}} ou appelez au {{contactPhone}}{{/if}}.`
},
{
name: 'new-appointment-request',
language_code: 'fr',
subject: 'Nouvelle demande de rendez-vous - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `Nouvelle demandeNouvelle demande de rendez-vous
Équipe,
Une nouvelle demande de rendez-vous a été soumise et nécessite votre examen et approbation.
Détails du rendez-vous
Service : {{serviceName}}
Date demandée : {{requestedDate}}
Heure demandée : {{requestedTime}}
Durée : {{duration}} minutes
Veuillez examiner cette demande et prendre les mesures appropriées.
`,
text_content: `Nouvelle demande de rendez-vous - Action requise
Équipe,
Une nouvelle demande de rendez-vous a été soumise et nécessite votre examen et approbation.
DÉTAILS DU RENDEZ-VOUS :
Service : {{serviceName}}
Date demandée : {{requestedDate}}
Heure demandée : {{requestedTime}}
Durée : {{duration}} minutes
Veuillez examiner cette demande et prendre les mesures appropriées.`
},
// Italian (it)
{
name: 'appointment-request-received',
language_code: 'it',
subject: 'Richiesta di appuntamento ricevuta - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `Richiesta ricevutaRichiesta ricevuta
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Grazie per aver inviato la tua richiesta di appuntamento. Abbiamo ricevuto la tua richiesta e il nostro team la esaminerà a breve.
Riferimento: {{referenceNumber}}
Dettagli della richiesta
Servizio: {{serviceName}}
Data richiesta: {{requestedDate}}
Ora richiesta: {{requestedTime}}
Durata: {{duration}} minuti
Per domande, contattaci a {{contactEmail}}{{#if contactPhone}} o chiama {{contactPhone}}{{/if}}.
`,
text_content: `Richiesta di appuntamento ricevuta
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Grazie per aver inviato la tua richiesta di appuntamento. Abbiamo ricevuto la tua richiesta e il nostro team la esaminerà a breve.
Numero di riferimento: {{referenceNumber}}
DETTAGLI DELLA RICHIESTA:
Servizio: {{serviceName}}
Data richiesta: {{requestedDate}}
Ora richiesta: {{requestedTime}}
Durata: {{duration}} minuti
Il nostro team esaminerà la tua richiesta e confermerà la disponibilità. Riceverai una notifica via email una volta che il tuo appuntamento sarà stato approvato.
Per domande, contattaci a {{contactEmail}}{{#if contactPhone}} o chiama {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-approved',
language_code: 'it',
subject: 'Appuntamento confermato - {{serviceName}} il {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `Appuntamento confermato✓ Appuntamento confermato
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Buone notizie! La tua richiesta di appuntamento è stata approvata e confermata.
Il tuo appuntamento
Servizio: {{serviceName}}
Data: {{appointmentDate}}
Ora: {{appointmentTime}}
Durata: {{duration}} minuti
{{#if technicianName}}Tecnico assegnato: {{technicianName}}
{{/if}}Se devi riprogrammare o annullare, contattaci almeno {{minimumNoticeHours}} ore prima a {{contactEmail}}{{#if contactPhone}} o chiama {{contactPhone}}{{/if}}.
`,
text_content: `Appuntamento confermato
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Buone notizie! La tua richiesta di appuntamento è stata approvata e confermata.
IL TUO APPUNTAMENTO:
Servizio: {{serviceName}}
Data: {{appointmentDate}}
Ora: {{appointmentTime}}
Durata: {{duration}} minuti
{{#if technicianName}}
TECNICO ASSEGNATO:
{{technicianName}}
{{#if technicianEmail}}Email: {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Telefono: {{technicianPhone}}{{/if}}
{{/if}}
Se devi riprogrammare o annullare, contattaci almeno {{minimumNoticeHours}} ore prima.`
},
{
name: 'appointment-request-declined',
language_code: 'it',
subject: 'Aggiornamento richiesta di appuntamento - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `AggiornamentoAggiornamento richiesta
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Grazie per il tuo interesse. Purtroppo, non possiamo accogliere la tua richiesta al momento richiesto.
{{#if declineReason}}{{/if}}Ti incoraggiamo a inviare una nuova richiesta per una data e ora alternative.
Per domande, contattaci a {{contactEmail}}{{#if contactPhone}} o chiama {{contactPhone}}{{/if}}.
`,
text_content: `Aggiornamento richiesta di appuntamento
Ciao{{#if requesterName}} {{requesterName}}{{/if}},
Grazie per il tuo interesse. Purtroppo, non possiamo accogliere la tua richiesta al momento richiesto.
{{#if declineReason}}
MOTIVO:
{{declineReason}}
{{/if}}
Ti incoraggiamo a inviare una nuova richiesta per una data e ora alternative che si adattino meglio alla nostra disponibilità.
Per domande, contattaci a {{contactEmail}}{{#if contactPhone}} o chiama {{contactPhone}}{{/if}}.`
},
{
name: 'new-appointment-request',
language_code: 'it',
subject: 'Nuova richiesta di appuntamento - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `Nuova richiestaNuova richiesta di appuntamento
Team,
È stata inviata una nuova richiesta di appuntamento che richiede la vostra revisione e approvazione.
Dettagli dell'appuntamento
Servizio: {{serviceName}}
Data richiesta: {{requestedDate}}
Ora richiesta: {{requestedTime}}
Durata: {{duration}} minuti
Si prega di rivedere questa richiesta e prendere le misure appropriate.
`,
text_content: `Nuova richiesta di appuntamento - Azione richiesta
Team,
È stata inviata una nuova richiesta di appuntamento che richiede la vostra revisione e approvazione.
DETTAGLI DELL'APPUNTAMENTO:
Servizio: {{serviceName}}
Data richiesta: {{requestedDate}}
Ora richiesta: {{requestedTime}}
Durata: {{duration}} minuti
Si prega di rivedere questa richiesta e prendere le misure appropriate.`
},
// Dutch (nl)
{
name: 'appointment-request-received',
language_code: 'nl',
subject: 'Afspraakverzoek ontvangen - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-received'],
html_content: `Verzoek ontvangenVerzoek ontvangen
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Bedankt voor het indienen van uw afspraakverzoek. Wij hebben uw verzoek ontvangen en ons team zal deze binnenkort beoordelen.
Referentie: {{referenceNumber}}
Verzoekdetails
Service: {{serviceName}}
Gewenste datum: {{requestedDate}}
Gewenste tijd: {{requestedTime}}
Duur: {{duration}} minuten
Voor vragen, neem contact op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.
`,
text_content: `Afspraakverzoek ontvangen
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Bedankt voor het indienen van uw afspraakverzoek. Wij hebben uw verzoek ontvangen en ons team zal deze binnenkort beoordelen.
Referentienummer: {{referenceNumber}}
VERZOEKDETAILS:
Service: {{serviceName}}
Gewenste datum: {{requestedDate}}
Gewenste tijd: {{requestedTime}}
Duur: {{duration}} minuten
Ons team zal uw verzoek beoordelen en de beschikbaarheid bevestigen. U ontvangt een e-mailmelding zodra uw afspraak is goedgekeurd.
Voor vragen, neem contact op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.`
},
{
name: 'appointment-request-approved',
language_code: 'nl',
subject: 'Afspraak bevestigd - {{serviceName}} op {{appointmentDate}}',
notification_subtype_id: subtypeIds['appointment-request-approved'],
html_content: `Afspraak bevestigd✓ Afspraak bevestigd
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Goed nieuws! Uw afspraakverzoek is goedgekeurd en bevestigd.
Uw afspraak
Service: {{serviceName}}
Datum: {{appointmentDate}}
Tijd: {{appointmentTime}}
Duur: {{duration}} minuten
{{#if technicianName}}Toegewezen technicus: {{technicianName}}
{{/if}}Als u moet verzetten of annuleren, neem dan minstens {{minimumNoticeHours}} uur van tevoren contact op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.
`,
text_content: `Afspraak bevestigd
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Goed nieuws! Uw afspraakverzoek is goedgekeurd en bevestigd.
UW AFSPRAAK:
Service: {{serviceName}}
Datum: {{appointmentDate}}
Tijd: {{appointmentTime}}
Duur: {{duration}} minuten
{{#if technicianName}}
TOEGEWEZEN TECHNICUS:
{{technicianName}}
{{#if technicianEmail}}E-mail: {{technicianEmail}}{{/if}}
{{#if technicianPhone}}Telefoon: {{technicianPhone}}{{/if}}
{{/if}}
Als u moet verzetten of annuleren, neem dan minstens {{minimumNoticeHours}} uur van tevoren contact op.`
},
{
name: 'appointment-request-declined',
language_code: 'nl',
subject: 'Update afspraakverzoek - {{serviceName}}',
notification_subtype_id: subtypeIds['appointment-request-declined'],
html_content: `UpdateUpdate afspraakverzoek
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Bedankt voor uw interesse. Helaas kunnen wij uw verzoek op het gevraagde tijdstip niet accommoderen.
{{#if declineReason}}{{/if}}Wij moedigen u aan om een nieuw verzoek in te dienen voor een alternatieve datum en tijd.
Voor vragen, neem contact op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.
`,
text_content: `Update afspraakverzoek
Hallo{{#if requesterName}} {{requesterName}}{{/if}},
Bedankt voor uw interesse. Helaas kunnen wij uw verzoek op het gevraagde tijdstip niet accommoderen.
{{#if declineReason}}
REDEN:
{{declineReason}}
{{/if}}
Wij moedigen u aan om een nieuw verzoek in te dienen voor een alternatieve datum en tijd die beter past bij onze beschikbaarheid.
Voor vragen, neem contact op via {{contactEmail}}{{#if contactPhone}} of bel {{contactPhone}}{{/if}}.`
},
{
name: 'new-appointment-request',
language_code: 'nl',
subject: 'Nieuw afspraakverzoek - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}',
notification_subtype_id: subtypeIds['new-appointment-request'],
html_content: `Nieuw verzoekNieuw afspraakverzoek
Team,
Er is een nieuw afspraakverzoek ingediend dat uw beoordeling en goedkeuring vereist.
Afspraakdetails
Service: {{serviceName}}
Gewenste datum: {{requestedDate}}
Gewenste tijd: {{requestedTime}}
Duur: {{duration}} minuten
Gelieve dit verzoek te beoordelen en passende actie te ondernemen.
`,
text_content: `Nieuw afspraakverzoek - Actie vereist
Team,
Er is een nieuw afspraakverzoek ingediend dat uw beoordeling en goedkeuring vereist.
AFSPRAAKDETAILS:
Service: {{serviceName}}
Gewenste datum: {{requestedDate}}
Gewenste tijd: {{requestedTime}}
Duur: {{duration}} minuten
Gelieve dit verzoek te beoordelen en passende actie te ondernemen.`
}
];
// Insert templates
await knex('system_email_templates')
.insert(templates)
.onConflict(['name', 'language_code'])
.merge({
subject: knex.raw('excluded.subject'),
html_content: knex.raw('excluded.html_content'),
text_content: knex.raw('excluded.text_content'),
notification_subtype_id: knex.raw('excluded.notification_subtype_id')
});
console.log(`✓ Added ${templates.length} appointment request email templates (English)`);
console.log('✓ Appointment request email templates migration completed successfully');
};
exports.down = async function(knex) {
console.log('Removing appointment request email templates...');
// Remove templates
await knex('system_email_templates')
.whereIn('name', [
'appointment-request-received',
'appointment-request-approved',
'appointment-request-declined',
'new-appointment-request'
])
.del();
// Remove notification subtypes
await knex('notification_subtypes')
.whereIn('name', [
'appointment-request-received',
'appointment-request-approved',
'appointment-request-declined',
'new-appointment-request'
])
.del();
// Remove category if it has no other subtypes
const appointmentsCategory = await knex('notification_categories')
.where({ name: 'Appointments' })
.first();
if (appointmentsCategory) {
const remainingSubtypes = await knex('notification_subtypes')
.where({ category_id: appointmentsCategory.id })
.count('* as count')
.first();
if (remainingSubtypes && parseInt(remainingSubtypes.count) === 0) {
await knex('notification_categories')
.where({ id: appointmentsCategory.id })
.del();
console.log('✓ Removed Appointments notification category');
}
}
console.log('✓ Appointment request email templates rollback completed');
};