/** * Add Polish translations for client-facing email templates * * Translates authentication, ticketing, billing, and appointment email templates to Polish * for client portal users. */ exports.up = async function(knex) { console.log('Adding Polish email templates...'); // Get notification subtypes const subtypes = await knex('notification_subtypes') .select('id', 'name') .whereIn('name', [ 'email-verification', 'password-reset', 'portal-invitation', 'tenant-recovery', 'no-account-found', 'Ticket Assigned', 'Ticket Created', 'Ticket Updated', 'Ticket Closed', 'Ticket Comment Added', 'Invoice Generated', 'Payment Received', 'Payment Overdue', 'appointment-request-received', 'appointment-request-approved', 'appointment-request-declined', 'new-appointment-request', 'survey-ticket-closed' ]); const getSubtypeId = (name) => { const subtype = subtypes.find(s => s.name === name); if (!subtype) { console.warn(`Notification subtype '${name}' not found, skipping template`); return null; } return subtype.id; }; // Build Polish templates array const allTemplates = [ // Authentication templates // NOTE: email-verification template is managed in migration 20251029100000 { name: 'password-reset', language_code: 'pl', subject: 'Prośba o zresetowanie hasła', notification_subtype_id: getSubtypeId('password-reset'), html_content: ` Prośba o zresetowanie hasła

Prośba o zresetowanie hasła

Bezpieczne odzyskiwanie hasła do Twojego konta

Cześć {{userName}},

Otrzymaliśmy prośbę o zresetowanie hasła dla konta powiązanego z {{email}}.

🔐 Weryfikacja bezpieczeństwa konta

Zgłoszone: Przed chwilą

E-mail konta: {{email}}

Ważne przez: {{expirationTime}}

Aby ustawić nowe hasło, kliknij przycisk poniżej:

Zresetuj hasło

Lub skopiuj i wklej ten link w przeglądarce:

⚠️ Ważne informacje dotyczące bezpieczeństwa

Co dalej?

  1. Kliknij przycisk resetowania powyżej lub użyj podanego linku
  2. Utwórz silne i unikalne hasło do swojego konta
  3. Po resecie zostaniesz automatycznie zalogowany(a)
  4. Wszystkie bieżące sesje zostaną wylogowane ze względów bezpieczeństwa
  5. Rozważ włączenie uwierzytelniania dwuskładnikowego dla większej ochrony

Potrzebujesz pomocy?

Jeśli masz trudności z resetowaniem hasła, nasz zespół wsparcia jest do Twojej dyspozycji.

Skontaktuj się ze wsparciem: {{supportEmail}}

`, text_content: `Prośba o zresetowanie hasła Cześć {{userName}}, Otrzymaliśmy prośbę o zresetowanie hasła dla konta powiązanego z {{email}}. WERYFIKACJA BEZPIECZEŃSTWA KONTA - Zgłoszone: Przed chwilą - E-mail konta: {{email}} - Ważne przez: {{expirationTime}} Aby utworzyć nowe hasło, otwórz poniższy link: {{resetLink}} WAŻNE INFORMACJE DOTYCZĄCE BEZPIECZEŃSTWA: - Link wygaśnie za {{expirationTime}} - Może zostać użyty tylko raz - Jeśli nie prosiłeś(aś) o reset, zignoruj tę wiadomość - Twoje hasło nie zmieni się, dopóki nie ustawisz nowego CO DALEJ: 1. Użyj powyższego linku 2. Utwórz silne i unikalne hasło 3. Zostaniesz automatycznie zalogowany(a) 4. Wszystkie istniejące sesje zostaną wylogowane 5. Rozważ włączenie uwierzytelniania dwuskładnikowego Potrzebujesz pomocy? Skontaktuj się ze wsparciem: {{supportEmail}} --- To automatyczna wiadomość bezpieczeństwa wysłana na {{email}}. © {{currentYear}} {{clientName}}. Wszelkie prawa zastrzeżone.` }, // NOTE: portal-invitation template is managed in migration 20251029100000 { name: 'tenant-recovery', language_code: 'pl', subject: '{{platformName}} - Twoje linki do logowania', notification_subtype_id: getSubtypeId('tenant-recovery'), html_content: `

{{platformName}}

Cześć,

Poprosiłeś(aś) o dostęp do portalu{{#if isMultiple}}i{{/if}} klienta{{#if isMultiple}}ów{{/if}}. {{#if isMultiple}}Znaleźliśmy {{tenantCount}} organizacji powiązanych z Twoim adresem e-mail.{{else}}Oto Twój link do logowania:{{/if}}

{{tenantLinksHtml}}

Uwaga dotycząca bezpieczeństwa: Jeśli nie prosiłeś(aś) o te linki do logowania, możesz bezpiecznie zignorować tę wiadomość. Twoje konto pozostaje bezpieczne.

Jeśli masz pytania lub potrzebujesz pomocy, skontaktuj się z zespołem wsparcia swojej organizacji.

© {{currentYear}} {{platformName}}. Wszelkie prawa zastrzeżone.

To automatyczna wiadomość. Nie odpowiadaj na ten e-mail.

`, text_content: `{{platformName}} - Twoje linki do logowania Cześć, Poprosiłeś(aś) o dostęp do portalu{{#if isMultiple}}i{{/if}} klienta{{#if isMultiple}}ów{{/if}}. {{#if isMultiple}}Znaleźliśmy {{tenantCount}} organizacji powiązanych z Twoim adresem e-mail.{{else}}Oto Twój link do logowania:{{/if}} Twoje linki do logowania: {{tenantLinksText}} Uwaga dotycząca bezpieczeństwa: Jeśli nie prosiłeś(aś) o te linki do logowania, możesz bezpiecznie zignorować tę wiadomość. Jeśli masz pytania lub potrzebujesz pomocy, skontaktuj się z zespołem wsparcia swojej organizacji. --- © {{currentYear}} {{platformName}}. Wszelkie prawa zastrzeżone. To automatyczna wiadomość. Nie odpowiadaj na ten e-mail.` }, { name: 'no-account-found', language_code: 'pl', subject: '{{platformName}} - Prośba o dostęp', notification_subtype_id: getSubtypeId('no-account-found'), html_content: `

{{platformName}}

Cześć,

Otrzymaliśmy prośbę o dostęp do portalu klienta z użyciem tego adresu e-mail.

Jeśli masz u nas konto, powinieneś/powinnaś otrzymać osobny e-mail z linkami do logowania.

Jeśli nie otrzymałeś(aś) e-maila z logowaniem, może to oznaczać:

Potrzebujesz pomocy?

Jeśli uważasz, że powinieneś/powinnaś mieć dostęp do portalu klienta, skontaktuj się z zespołem wsparcia swojego dostawcy usług.

Uwaga dotycząca bezpieczeństwa: Jeśli nie prosiłeś(aś) o dostęp, możesz bezpiecznie zignorować tę wiadomość.

© {{currentYear}} {{platformName}}. Wszelkie prawa zastrzeżone.

To automatyczna wiadomość. Nie odpowiadaj na ten e-mail.

`, text_content: `{{platformName}} - Prośba o dostęp Cześć, Otrzymaliśmy prośbę o dostęp do portalu klienta z użyciem tego adresu e-mail. Jeśli masz u nas konto, powinieneś/powinnaś otrzymać osobny e-mail z linkami do logowania. Jeśli nie otrzymałeś(aś) e-maila z logowaniem, może to oznaczać: - Ten adres e-mail nie jest powiązany z żadnym kontem portalu klienta - Twoje konto może być nieaktywne - Wiadomość mogła trafić do folderu spam Potrzebujesz pomocy? Jeśli uważasz, że powinieneś/powinnaś mieć dostęp do portalu klienta, skontaktuj się z zespołem wsparcia swojego dostawcy usług. Uwaga dotycząca bezpieczeństwa: Jeśli nie prosiłeś(aś) o dostęp, możesz bezpiecznie zignorować tę wiadomość. --- © {{currentYear}} {{platformName}}. Wszelkie prawa zastrzeżone. To automatyczna wiadomość. Nie odpowiadaj na ten e-mail.` }, // Ticketing templates { name: 'ticket-assigned', language_code: 'pl', subject: 'Zgłoszenie przypisane • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Assigned'), html_content: `
Zgłoszenie przypisane
{{ticket.title}}
{{ticket.metaLine}}

To zgłoszenie zostało do Ciebie przypisane dla {{ticket.clientName}}. Sprawdź szczegóły poniżej i podejmij odpowiednie działania.

Zgłoszenie #{{ticket.id}}
Priorytet {{ticket.priority}}
Status {{ticket.status}}
Przypisał(a) {{ticket.assignedBy}}
Przypisane do
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Zgłaszający
{{ticket.requesterName}}
{{ticket.requesterContact}}
Tablica {{ticket.board}}
Kategoria {{ticket.categoryDetails}}
Lokalizacja {{ticket.locationSummary}}
Podsumowanie zgłoszenia
{{ticket.summary}}
Zobacz zgłoszenie
Powered by Alga PSA
`, text_content: ` Zgłoszenie przypisane To zgłoszenie zostało do Ciebie przypisane dla {{ticket.clientName}}. Zgłoszenie #{{ticket.id}} • {{ticket.title}} Priorytet: {{ticket.priority}} Status: {{ticket.status}} Przypisał(a): {{ticket.assignedBy}} Przypisane do: {{ticket.assignedToName}} ({{ticket.assignedToEmail}}) Zgłaszający: {{ticket.requesterName}} ({{ticket.requesterContact}}) Tablica: {{ticket.board}} Kategoria: {{ticket.categoryDetails}} Lokalizacja: {{ticket.locationSummary}} Podsumowanie: {{ticket.summary}} Zobacz zgłoszenie: {{ticket.url}} ` }, { name: 'ticket-created', language_code: 'pl', subject: 'Nowe zgłoszenie • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Created'), html_content: `
Nowe zgłoszenie
{{ticket.title}}
{{ticket.metaLine}}

Utworzono nowe zgłoszenie dla {{ticket.clientName}}. Zapoznaj się z podsumowaniem i przejdź do zgłoszenia.

Zgłoszenie #{{ticket.id}}
Priorytet {{ticket.priority}}
Status {{ticket.status}}
Utworzono {{ticket.createdAt}} · {{ticket.createdBy}}
Przypisane do
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Zgłaszający
{{ticket.requesterName}}
{{ticket.requesterContact}}
Tablica {{ticket.board}}
Kategoria {{ticket.categoryDetails}}
Lokalizacja {{ticket.locationSummary}}
Podsumowanie zgłoszenia
{{ticket.summary}}
Zobacz zgłoszenie
Powered by Alga PSA
`, text_content: ` Nowe zgłoszenie Utworzono nowe zgłoszenie dla {{ticket.clientName}}. Zgłoszenie #{{ticket.id}} • {{ticket.title}} Priorytet: {{ticket.priority}} Status: {{ticket.status}} Utworzono: {{ticket.createdAt}} · {{ticket.createdBy}} Przypisane do: {{ticket.assignedToName}} ({{ticket.assignedToEmail}}) Zgłaszający: {{ticket.requesterName}} ({{ticket.requesterContact}}) Tablica: {{ticket.board}} Kategoria: {{ticket.categoryDetails}} Lokalizacja: {{ticket.locationSummary}} Podsumowanie: {{ticket.summary}} Zobacz zgłoszenie: {{ticket.url}} ` }, { name: 'ticket-updated', language_code: 'pl', subject: 'Zgłoszenie zaktualizowane • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Updated'), html_content: `
Zgłoszenie zaktualizowane
{{ticket.title}}
{{ticket.metaLine}}

Zgłoszenie dla {{ticket.clientName}} zostało zaktualizowane. Sprawdź szczegóły i podejmij działania.

Zgłoszenie #{{ticket.id}}
Priorytet {{ticket.priority}}
Status {{ticket.status}}
Zaktualizowano {{ticket.updatedAt}} · {{ticket.updatedBy}}
Przypisane do
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Zgłaszający
{{ticket.requesterName}}
{{ticket.requesterContact}}
Tablica {{ticket.board}}
Kategoria {{ticket.categoryDetails}}
Lokalizacja {{ticket.locationSummary}}
Podsumowanie zgłoszenia
{{ticket.summary}}
Zobacz zgłoszenie
Powered by Alga PSA
`, text_content: ` Zgłoszenie zaktualizowane Zgłoszenie dla {{ticket.clientName}} zostało zaktualizowane. Zgłoszenie #{{ticket.id}} • {{ticket.title}} Priorytet: {{ticket.priority}} Status: {{ticket.status}} Zaktualizowano: {{ticket.updatedAt}} · {{ticket.updatedBy}} Przypisane do: {{ticket.assignedToName}} ({{ticket.assignedToEmail}}) Zgłaszający: {{ticket.requesterName}} ({{ticket.requesterContact}}) Tablica: {{ticket.board}} Kategoria: {{ticket.categoryDetails}} Lokalizacja: {{ticket.locationSummary}} Podsumowanie: {{ticket.summary}} Zobacz zgłoszenie: {{ticket.url}} ` }, { name: 'ticket-closed', language_code: 'pl', subject: 'Zgłoszenie zamknięte • {{ticket.title}} ({{ticket.priority}})', notification_subtype_id: getSubtypeId('Ticket Closed'), html_content: `
Zgłoszenie zamknięte
{{ticket.title}}
{{ticket.metaLine}}

Zgłoszenie dla {{ticket.clientName}} zostało zamknięte. Poniżej znajdziesz podsumowanie.

Zamknięte
Priorytet {{ticket.priority}}
Status {{ticket.status}}
Zamknięto {{ticket.closedAt}} · {{ticket.closedBy}}
Przypisane do
{{ticket.assignedToName}}
{{ticket.assignedToEmail}}
Zgłaszający
{{ticket.requesterName}}
{{ticket.requesterContact}}
Tablica {{ticket.board}}
Kategoria {{ticket.categoryDetails}}
Lokalizacja {{ticket.locationSummary}}
Rozwiązanie
{{ticket.resolution}}
Zobacz zgłoszenie
Powered by Alga PSA
`, text_content: ` Zgłoszenie zamknięte Zgłoszenie dla {{ticket.clientName}} zostało zamknięte. Zgłoszenie #{{ticket.id}} • {{ticket.title}} Priorytet: {{ticket.priority}} Status: {{ticket.status}} Zamknięto: {{ticket.closedAt}} · {{ticket.closedBy}} Przypisane do: {{ticket.assignedToName}} ({{ticket.assignedToEmail}}) Zgłaszający: {{ticket.requesterName}} ({{ticket.requesterContact}}) Tablica: {{ticket.board}} Kategoria: {{ticket.categoryDetails}} Lokalizacja: {{ticket.locationSummary}} Rozwiązanie: {{ticket.resolution}} Zobacz zgłoszenie: {{ticket.url}} ` }, { name: 'ticket-comment-added', language_code: 'pl', subject: 'Nowy komentarz • {{ticket.title}}', notification_subtype_id: getSubtypeId('Ticket Comment Added'), html_content: `
Nowy komentarz
{{ticket.title}}
{{ticket.metaLine}}

{{comment.authorName}} dodał(a) komentarz do zgłoszenia {{ticket.clientName}}.

Zgłoszenie #{{ticket.id}}
Priorytet {{ticket.priority}}
Status {{ticket.status}}
Zgłaszający
{{ticket.requesterName}}
{{ticket.requesterContact}}
Treść komentarza
{{comment.body}}
Zobacz zgłoszenie
Powered by Alga PSA
`, text_content: ` Nowy komentarz {{comment.authorName}} dodał(a) komentarz do zgłoszenia {{ticket.clientName}}. Zgłoszenie #{{ticket.id}} • {{ticket.title}} Priorytet: {{ticket.priority}} Status: {{ticket.status}} Zgłaszający: {{ticket.requesterName}} ({{ticket.requesterContact}}) Komentarz: {{comment.body}} Zobacz zgłoszenie: {{ticket.url}} ` }, // Billing templates { name: 'invoice-generated', language_code: 'pl', subject: 'Nowa faktura • {{invoice.number}}', notification_subtype_id: getSubtypeId('Invoice Generated'), html_content: `
Nowa faktura
Faktura #{{invoice.number}}
{{invoice.clientName}}

Nowa faktura została wystawiona. Sprawdź szczegóły poniżej.

Numer faktury {{invoice.number}}
Kwota {{invoice.amount}}
Data wystawienia {{invoice.date}}
Termin płatności {{invoice.dueDate}}
Zobacz fakturę
Powered by Alga PSA
`, text_content: ` Nowa faktura Numer faktury: {{invoice.number}} Kwota: {{invoice.amount}} Data wystawienia: {{invoice.date}} Termin płatności: {{invoice.dueDate}} Zobacz fakturę: {{invoice.url}} ` }, { name: 'payment-received', language_code: 'pl', subject: 'Płatność otrzymana • {{invoice.number}}', notification_subtype_id: getSubtypeId('Payment Received'), html_content: `
Płatność otrzymana
Faktura #{{invoice.number}}
{{invoice.clientName}}

Otrzymaliśmy płatność za fakturę. Dziękujemy!

Numer faktury {{invoice.number}}
Kwota {{invoice.amount}}
Data płatności {{invoice.paymentDate}}
Metoda płatności {{invoice.paymentMethod}}
Zobacz fakturę
Powered by Alga PSA
`, text_content: ` Płatność otrzymana Numer faktury: {{invoice.number}} Kwota: {{invoice.amount}} Data płatności: {{invoice.paymentDate}} Metoda płatności: {{invoice.paymentMethod}} Zobacz fakturę: {{invoice.url}} ` }, { name: 'payment-overdue', language_code: 'pl', subject: 'Płatność po terminie • {{invoice.number}}', notification_subtype_id: getSubtypeId('Payment Overdue'), html_content: `
Płatność po terminie
Faktura #{{invoice.number}}
{{invoice.clientName}}

Płatność za poniższą fakturę jest po terminie. Prosimy o uregulowanie należności.

Numer faktury {{invoice.number}}
Kwota do zapłaty {{invoice.amountDue}}
Termin płatności {{invoice.dueDate}}
Dni po terminie {{invoice.daysOverdue}}
Zobacz fakturę
Powered by Alga PSA
`, text_content: ` Płatność po terminie Numer faktury: {{invoice.number}} Kwota do zapłaty: {{invoice.amountDue}} Termin płatności: {{invoice.dueDate}} Dni po terminie: {{invoice.daysOverdue}} Zobacz fakturę: {{invoice.url}} ` }, // Portal Invitation { name: 'portal-invitation', language_code: 'pl', subject: 'Zaproszenie do portalu klienta{{#if clientName}} - {{clientName}}{{/if}}', notification_subtype_id: getSubtypeId('portal-invitation'), html_content: ` Zaproszenie do portalu

Witamy w portalu klienta

Twój dostęp do zarządzania usługami jest gotowy

Witaj {{contactName}},

Zostałeś(aś) zaproszony(a) do portalu klienta {{clientName}}. Ten bezpieczny portal daje Ci natychmiastowy dostęp do:

Twój dostęp obejmuje:

✓ Przeglądanie i śledzenie Twoich zgłoszeń serwisowych

✓ Przegląd aktualizacji projektów i dokumentacji

✓ Bezpośrednia komunikacja z zespołem wsparcia

Skonfiguruj dostęp do portalu

Lub skopiuj i wklej ten link do przeglądarki:

⏰ Zaproszenie ograniczone czasowo

Ten link zaproszeniowy wygaśnie za {{expirationTime}}. Dokończ konfigurację konta przed tym terminem, aby zapewnić nieprzerwany dostęp.

Potrzebujesz pomocy?

Email: {{clientLocationEmail}}

Telefon: {{clientLocationPhone}}

Nasz zespół wsparcia jest gotowy, aby pomóc Ci rozpocząć.

`, text_content: `Witamy w portalu klienta Witaj {{contactName}}, Zostałeś(aś) zaproszony(a) do portalu klienta {{clientName}}. Ten bezpieczny portal daje Ci natychmiastowy dostęp do: ✓ Przeglądanie i śledzenie Twoich zgłoszeń serwisowych ✓ Przegląd aktualizacji projektów i dokumentacji ✓ Bezpośrednia komunikacja z zespołem wsparcia Skonfiguruj dostęp do portalu: {{portalLink}} ⏰ Zaproszenie ograniczone czasowo Ten link zaproszeniowy wygaśnie za {{expirationTime}}. Dokończ konfigurację konta przed tym terminem, aby zapewnić nieprzerwany dostęp. Potrzebujesz pomocy? Email: {{clientLocationEmail}} Telefon: {{clientLocationPhone}} Nasz zespół wsparcia jest gotowy, aby pomóc Ci rozpocząć. --- Ta wiadomość została wysłana do {{contactName}} w ramach konfiguracji dostępu do portalu. Jeśli nie spodziewałeś(aś) się tego zaproszenia, skontaktuj się z nami pod adresem {{clientLocationEmail}}. © {{currentYear}} {{clientName}}. Wszelkie prawa zastrzeżone.` }, // Email Verification { name: 'email-verification', language_code: 'pl', subject: 'Zweryfikuj swój adres email{{#if registrationClientName}} dla {{registrationClientName}}{{/if}}', notification_subtype_id: getSubtypeId('email-verification'), html_content: ` Weryfikacja adresu email

Zweryfikuj swój adres email

Jeszcze jeden krok do ukończenia rejestracji

Witaj{{#if contactName}} {{contactName}}{{/if}},

Dziękujemy za rejestrację! Proszę zweryfikować swój adres email, klikając poniższy przycisk:

Zweryfikuj adres email

Lub skopiuj i wklej ten link do przeglądarki:

⏰ Link ograniczony czasowo

Ten link weryfikacyjny wygaśnie za {{expirationTime}}. Jeśli link wygaśnie, możesz poprosić o nowy na stronie logowania.

Jeśli nie zakładałeś(aś) konta, możesz bezpiecznie zignorować tę wiadomość.

`, text_content: `Zweryfikuj swój adres email Witaj{{#if contactName}} {{contactName}}{{/if}}, Dziękujemy za rejestrację! Proszę zweryfikować swój adres email, klikając poniższy link: {{verificationLink}} ⏰ Link ograniczony czasowo Ten link weryfikacyjny wygaśnie za {{expirationTime}}. Jeśli link wygaśnie, możesz poprosić o nowy na stronie logowania. Jeśli nie zakładałeś(aś) konta, możesz bezpiecznie zignorować tę wiadomość.` }, // Appointment Request Received { name: 'appointment-request-received', language_code: 'pl', subject: 'Wniosek o wizytę otrzymany - {{serviceName}}', notification_subtype_id: getSubtypeId('appointment-request-received'), html_content: ` Wniosek otrzymany

Wniosek otrzymany

Otrzymaliśmy Twój wniosek o wizytę

Witaj{{#if requesterName}} {{requesterName}}{{/if}},

Dziękujemy za złożenie wniosku o wizytę. Otrzymaliśmy Twój wniosek i nasz zespół wkrótce go rozpatrzy.

Numer referencyjny: {{referenceNumber}}

Szczegóły wniosku

Usługa: {{serviceName}}

Żądana data: {{requestedDate}}

Żądana godzina: {{requestedTime}}

Czas trwania: {{duration}} minut

{{#if preferredTechnician}}

Preferowany technik: {{preferredTechnician}}

{{/if}}

Co dalej?

Nasz zespół rozpatrzy Twój wniosek i potwierdzi dostępność. Otrzymasz powiadomienie email, gdy wizyta zostanie zatwierdzona lub jeśli będą potrzebne zmiany. Zazwyczaj odpowiadamy w ciągu {{responseTime}}.

Jeśli masz pytania lub chcesz wprowadzić zmiany do wniosku, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.

`, text_content: `Wniosek o wizytę otrzymany Witaj{{#if requesterName}} {{requesterName}}{{/if}}, Dziękujemy za złożenie wniosku o wizytę. Otrzymaliśmy Twój wniosek i nasz zespół wkrótce go rozpatrzy. Numer referencyjny: {{referenceNumber}} SZCZEGÓŁY WNIOSKU: Usługa: {{serviceName}} Żądana data: {{requestedDate}} Żądana godzina: {{requestedTime}} Czas trwania: {{duration}} minut {{#if preferredTechnician}}Preferowany technik: {{preferredTechnician}}{{/if}} CO DALEJ? Nasz zespół rozpatrzy Twój wniosek i potwierdzi dostępność. Otrzymasz powiadomienie email, gdy wizyta zostanie zatwierdzona lub jeśli będą potrzebne zmiany. Zazwyczaj odpowiadamy w ciągu {{responseTime}}. Jeśli masz pytania lub chcesz wprowadzić zmiany do wniosku, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.` }, // Appointment Request Approved { name: 'appointment-request-approved', language_code: 'pl', subject: 'Wizyta potwierdzona - {{serviceName}} dnia {{appointmentDate}}', notification_subtype_id: getSubtypeId('appointment-request-approved'), html_content: ` Wizyta potwierdzona

✓ Wizyta potwierdzona

Twój wniosek o wizytę został zatwierdzony

Witaj{{#if requesterName}} {{requesterName}}{{/if}},

Świetna wiadomość! Twój wniosek o wizytę został zatwierdzony i zaplanowany.

Szczegóły wizyty

Usługa: {{serviceName}}

Data: {{appointmentDate}}

Godzina: {{appointmentTime}}

Czas trwania: {{duration}} minut

{{#if location}}

Lokalizacja: {{location}}

{{/if}}
{{#if technicianName}}

Twój przypisany technik

{{technicianName}}

{{#if technicianEmail}}

{{technicianEmail}}

{{/if}} {{#if technicianPhone}}

{{technicianPhone}}

{{/if}}
{{/if}}

Jeśli potrzebujesz przełożyć lub anulować wizytę, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.

`, text_content: `Wizyta potwierdzona Witaj{{#if requesterName}} {{requesterName}}{{/if}}, Świetna wiadomość! Twój wniosek o wizytę został zatwierdzony i zaplanowany. SZCZEGÓŁY WIZYTY: Usługa: {{serviceName}} Data: {{appointmentDate}} Godzina: {{appointmentTime}} Czas trwania: {{duration}} minut {{#if location}}Lokalizacja: {{location}}{{/if}} {{#if technicianName}} TWÓJ PRZYPISANY TECHNIK: {{technicianName}} {{#if technicianEmail}}{{technicianEmail}}{{/if}} {{#if technicianPhone}}{{technicianPhone}}{{/if}} {{/if}} Jeśli potrzebujesz przełożyć lub anulować wizytę, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.` }, // Appointment Request Declined { name: 'appointment-request-declined', language_code: 'pl', subject: 'Aktualizacja wniosku o wizytę - {{serviceName}}', notification_subtype_id: getSubtypeId('appointment-request-declined'), html_content: ` Aktualizacja wniosku

Aktualizacja wniosku o wizytę

Ważne informacje o Twoim wniosku

Witaj{{#if requesterName}} {{requesterName}}{{/if}},

Dziękujemy za zainteresowanie umówieniem wizyty u nas. Niestety, nie możemy zrealizować Twojego wniosku w żądanym terminie.

{{#if declineReason}}

Powód:

{{declineReason}}

{{/if}}

Chętnie pomożemy

Przepraszamy za niedogodności. Zachęcamy do złożenia nowego wniosku na inny termin.

Jeśli masz pytania lub potrzebujesz pomocy w znalezieniu dostępnego terminu, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.

`, text_content: `Aktualizacja wniosku o wizytę Witaj{{#if requesterName}} {{requesterName}}{{/if}}, Dziękujemy za zainteresowanie umówieniem wizyty u nas. Niestety, nie możemy zrealizować Twojego wniosku w żądanym terminie. {{#if declineReason}} POWÓD: {{declineReason}} {{/if}} CHĘTNIE POMOŻEMY Przepraszamy za niedogodności. Zachęcamy do złożenia nowego wniosku na inny termin. Jeśli masz pytania lub potrzebujesz pomocy w znalezieniu dostępnego terminu, skontaktuj się z nami pod adresem {{contactEmail}}{{#if contactPhone}} lub zadzwoń pod {{contactPhone}}{{/if}}.` }, // New Appointment Request (for MSP staff) { name: 'new-appointment-request', language_code: 'pl', subject: 'Nowy wniosek o wizytę - {{clientName}}{{#if serviceName}} - {{serviceName}}{{/if}}', notification_subtype_id: getSubtypeId('new-appointment-request'), html_content: ` Nowy wniosek o wizytę

Nowy wniosek o wizytę

Wymagana akcja

Zespole,

Wpłynął nowy wniosek o wizytę wymagający przeglądu i zatwierdzenia.

Szczegóły wizyty

Usługa: {{serviceName}}

Żądana data: {{requestedDate}}

Żądana godzina: {{requestedTime}}

Czas trwania: {{duration}} minut

Proszę przejrzeć ten wniosek i podjąć odpowiednie działania. Wnioskodawca czeka na potwierdzenie.

`, text_content: `Nowy wniosek o wizytę - Wymagana akcja Zespole, Wpłynął nowy wniosek o wizytę wymagający przeglądu i zatwierdzenia. INFORMACJE O WNIOSKODAWCY: Imię: {{requesterName}} Email: {{requesterEmail}} {{#if requesterPhone}}Telefon: {{requesterPhone}}{{/if}} {{#if clientName}}Klient: {{clientName}}{{/if}} SZCZEGÓŁY WIZYTY: Usługa: {{serviceName}} Żądana data: {{requestedDate}} Żądana godzina: {{requestedTime}} Czas trwania: {{duration}} minut Proszę przejrzeć ten wniosek i podjąć odpowiednie działania.` }, // Survey - Ticket Closed { name: 'SURVEY_TICKET_CLOSED', language_code: 'pl', subject: 'Chętnie poznamy Twoją opinię o zgłoszeniu {{ticket_number}}', notification_subtype_id: getSubtypeId('survey-ticket-closed'), html_content: ` Chętnie poznamy Twoją opinię o zgłoszeniu {{ticket_number}}

Chętnie poznamy Twoją opinię o zgłoszeniu {{ticket_number}}

Zgłoszenie #{{ticket_number}} · {{ticket_subject}}

Technik: {{technician_name}}

Cześć {{contact_name}},

{{prompt_text}}

Wybierz ocenę poniżej, aby dać nam znać, jak nam poszło:

{{rating_buttons_html}}

Jeśli przyciski się nie załadują, otwórz ten bezpieczny link do ankiety:

{{survey_url}}

{{rating_links_text}}

{{thank_you_text}}

{{tenant_name}} · Zgłoszenie #{{ticket_number}} · {{ticket_closed_at}}

`, text_content: `Chętnie poznamy Twoją opinię o zgłoszeniu {{ticket_number}} Cześć {{contact_name}}, Zgłoszenie #{{ticket_number}} · {{ticket_subject}} Technik: {{technician_name}} {{prompt_text}} Wybierz ocenę poniżej, aby dać nam znać, jak nam poszło: Jeśli przyciski się nie załadują, otwórz ten bezpieczny link do ankiety: {{rating_links_text}} {{thank_you_text}} {{tenant_name}} · Zgłoszenie #{{ticket_number}} · {{ticket_closed_at}}` } ]; // Filter out templates with null subtype_ids (those whose subtypes don't exist yet) const validTemplates = allTemplates.filter(t => t.notification_subtype_id !== null); if (validTemplates.length === 0) { console.warn('No valid Polish email templates to insert (all subtypes missing)'); return; } await knex('system_email_templates').insert(validTemplates).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(`✓ Polish email templates added (${validTemplates.length} of ${allTemplates.length} templates)`); }; exports.down = async function(knex) { // Remove Polish email templates await knex('system_email_templates') .where({ language_code: 'pl' }) .whereIn('name', [ 'password-reset', 'tenant-recovery', 'no-account-found', 'ticket-assigned', 'ticket-created', 'ticket-updated', 'ticket-closed', 'ticket-comment-added', 'invoice-generated', 'payment-received', 'payment-overdue', 'portal-invitation', 'email-verification', 'appointment-request-received', 'appointment-request-approved', 'appointment-request-declined', 'new-appointment-request', 'SURVEY_TICKET_CLOSED' ]) .del(); console.log('Polish email templates removed'); };