PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.13
Yatra – Travel Booking & Tour Operator Software v3.0.13
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / resources / js / lib / email-templates-catalog.ts

email-templates-catalog.ts in Yatra – Travel Booking & Tour Operator Software 3.0.13, at resources/js/lib/email-templates-catalog.ts

770 lines 29.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Canonical list of system email templates (aligned with Yatra Pro seeds).
3 * When Email Automation is off, settings-backed templates stay editable in the free plugin;
4 * Pro-only catalog rows stay visible but locked until Pro + Email Automation is on.
5 * Module-gated templates (e.g. trip consent, abandoned recovery) stay listed with real
6 * on/off + content from site settings while the module is off — view-only until the module is active.
7 */
8
9 import { __, sprintf, brandName } from "./i18n";
10
11 // Pre-compute "{brand} Pro" once at module load. Used by the
12 // operator-facing template descriptions below so a white-labelled
13 // site shows the operator's brand instead of literal "Yatra Pro".
14 // brandName() reads window.yatraAdmin.brandName which is injected
15 // before any React module loads, so this value is always correct.
16 const BRAND_PRO_NAME = brandName() + " Pro";
17 import type { EmailSettingsValues } from "../components/settings/email-settings-types";
18
19 /** Rich booking merge tags (gateway, schedule, travelers, booking meta, special requests). */
20 const BOOKING_RICH_MERGE_TAGS =
21 "{{payment_gateway}}, {{payment_gateway_label}}, {{payment_schedule}}, {{payment_schedule_label}}, {{travelers_list}}, {{travelers_list_html}}, {{traveler_custom_fields_html}}, {{booking_custom_fields_html}}, {{special_requests}}, {{special_requests_html}}";
22
23 export type EmailCatalogEntry = {
24 template_key: string;
25 event_key: string;
26 name: string;
27 description: string;
28 category: string;
29 recipient_type: "customer" | "admin";
30 to_email: string;
31 /** When true, subject/body/active map to EmailSettingsValues keys. */
32 isCoreFree: boolean;
33 /** If set, subject/body cannot be edited until Pro + this module slug is active (row still listed). */
34 requiresModule?: string;
35 settingsFlag?: keyof EmailSettingsValues;
36 /** Only relevant when deposits / partial payments are enabled. */
37 requiresPartialPayments?: boolean;
38 settingsSubject?: keyof EmailSettingsValues;
39 settingsBody?: keyof EmailSettingsValues;
40 /** Shown in core editor sidebar for merge tags */
41 mergeTags?: string;
42 };
43
44 export const CORE_FREE_TEMPLATE_KEYS = [
45 "booking_confirmation",
46 "payment_received",
47 "partial_payment_received",
48 "booking_cancelled",
49 "trip_reminder",
50 "trip_consent_request",
51 "customer_email_verification",
52 "guest_email_verification",
53 "account_email_change_request",
54 "account_email_changed",
55 "booking_completed",
56 "booking_expired_customer",
57 "admin_booking_expired",
58 "scheduled_payment_reminder",
59 "scheduled_payment_succeeded",
60 "scheduled_payment_failed",
61 "admin_scheduled_payment_failed",
62 "enquiry_received",
63 "enquiry_admin",
64 "enquiry_response",
65 "review_request",
66 "abandoned_booking_recovery_first",
67 "abandoned_booking_recovery_second",
68 "abandoned_booking_recovery_final",
69 "admin_new_booking",
70 "admin_payment_received",
71 "admin_booking_cancelled",
72 ] as const;
73
74 export type CoreFreeTemplateKey = (typeof CORE_FREE_TEMPLATE_KEYS)[number];
75
76 export function isCoreTemplateSlug(
77 slug: string | null | undefined,
78 ): slug is CoreFreeTemplateKey {
79 return (
80 !!slug && (CORE_FREE_TEMPLATE_KEYS as readonly string[]).includes(slug)
81 );
82 }
83
84 export const EMAIL_TEMPLATES_CATALOG: EmailCatalogEntry[] = [
85 {
86 template_key: "booking_confirmation",
87 event_key: "booking.created",
88 name: __("Booking Confirmation", "yatra"),
89 description: __(
90 "Customer email for checkout, admin bookings, and confirmed status.",
91 "yatra",
92 ),
93 category: "booking",
94 recipient_type: "customer",
95 to_email: "{customer_email}",
96 isCoreFree: true,
97 settingsFlag: "email_template_booking",
98 settingsSubject: "email_tpl_booking_subject",
99 settingsBody: "email_tpl_booking_body",
100 mergeTags:
101 "{{site_name}}, {{customer_name}}, {{customer_first_name}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{travel_date}}, {{travelers_count}}, {{total_amount_formatted}}, {{amount_due_formatted}}, {{currency}}, {{intro_paragraph}}, {{details_html}}, {{footer_note}}, " +
102 BOOKING_RICH_MERGE_TAGS,
103 },
104 {
105 template_key: "payment_received",
106 event_key: "payment.received",
107 name: __("Payment Received", "yatra"),
108 description: __("Sent when a payment is recorded for a booking.", "yatra"),
109 category: "payment",
110 recipient_type: "customer",
111 to_email: "{customer_email}",
112 isCoreFree: true,
113 settingsFlag: "email_template_confirmation",
114 settingsSubject: "email_tpl_payment_subject",
115 settingsBody: "email_tpl_payment_body",
116 mergeTags:
117 "{{site_name}}, {{customer_name}}, {{customer_first_name}}, {{booking_reference}}, {{trip_name}}, {{travel_date}}, {{payment_amount_formatted}}, {{payment_method}}, {{transaction_id}}, {{total_amount_formatted}}, {{currency}}, " +
118 BOOKING_RICH_MERGE_TAGS,
119 },
120 {
121 template_key: "partial_payment_received",
122 event_key: "payment.partial_received",
123 name: __("Partial Payment Received", "yatra"),
124 description: __(
125 "Sent when a payment is recorded but a balance is still outstanding. Only used when deposits or partial payments are enabled and this template is switched on — otherwise the standard Payment Received email is sent for every payment.",
126 "yatra",
127 ),
128 category: "payment",
129 recipient_type: "customer",
130 to_email: "{customer_email}",
131 isCoreFree: true,
132 // Shown only when the site actually takes deposits / partial payments.
133 requiresPartialPayments: true,
134 settingsFlag: "email_template_partial_payment",
135 settingsSubject: "email_tpl_partial_payment_subject",
136 settingsBody: "email_tpl_partial_payment_body",
137 mergeTags:
138 "{{site_name}}, {{customer_name}}, {{customer_first_name}}, {{booking_reference}}, {{trip_name}}, {{travel_date}}, {{payment_amount_formatted}}, {{amount_paid_formatted}}, {{amount_due_formatted}}, {{total_amount_formatted}}, {{payment_method}}, {{transaction_id}}, {{currency}}, " +
139 BOOKING_RICH_MERGE_TAGS,
140 },
141 {
142 template_key: "booking_cancelled",
143 event_key: "booking.cancelled",
144 name: __("Booking Cancellation", "yatra"),
145 description: __("Sent when a booking is marked cancelled.", "yatra"),
146 category: "booking",
147 recipient_type: "customer",
148 to_email: "{customer_email}",
149 isCoreFree: true,
150 settingsFlag: "email_template_cancellation",
151 settingsSubject: "email_tpl_cancellation_subject",
152 settingsBody: "email_tpl_cancellation_body",
153 mergeTags:
154 "{{site_name}}, {{customer_name}}, {{customer_first_name}}, {{booking_reference}}, {{trip_name}}, {{travel_date}}, {{travelers_count}}, " +
155 BOOKING_RICH_MERGE_TAGS,
156 },
157 {
158 template_key: "trip_reminder",
159 event_key: "reminder.trip",
160 name: __("Trip Reminder", "yatra"),
161 description: __(
162 "Scheduled reminder before departure (see Booking settings).",
163 "yatra",
164 ),
165 category: "reminder",
166 recipient_type: "customer",
167 to_email: "{customer_email}",
168 isCoreFree: true,
169 settingsFlag: "email_template_reminder",
170 settingsSubject: "email_tpl_reminder_subject",
171 settingsBody: "email_tpl_reminder_body",
172 mergeTags:
173 "{{site_name}}, {{customer_name}}, {{booking_reference}}, {{trip_name}}, {{travel_date}}, {{travelers_count}}, {{reminder_days}}, {{days_until_trip}}, {{amount_due_formatted}}, {{reminder_extra_html}}, " +
174 BOOKING_RICH_MERGE_TAGS,
175 },
176 {
177 template_key: "trip_consent_request",
178 event_key: "consent.requested",
179 name: __("Trip consent request", "yatra"),
180 description: __(
181 "Sent when a traveler must sign a trip consent form (Trip Consent module).",
182 "yatra",
183 ),
184 category: "booking",
185 recipient_type: "customer",
186 to_email: "{customer_email}",
187 isCoreFree: true,
188 requiresModule: "trip_consent",
189 settingsFlag: "email_template_trip_consent",
190 settingsSubject: "email_tpl_trip_consent_subject",
191 settingsBody: "email_tpl_trip_consent_body",
192 mergeTags:
193 "{{site_name}}, {{recipient_name}}, {{form_name}}, {{consent_link}}, {{trip_name}}, {{travel_date}}, {{booking_reference}}, {{expiry_notice_html}}, {{consent_test_notice_html}}",
194 },
195 {
196 template_key: "customer_email_verification",
197 event_key: "account.email_verification",
198 name: __("Customer email verification", "yatra"),
199 description: __(
200 "Sent when a customer registers (e.g. from checkout) and must verify their email before logging in.",
201 "yatra",
202 ),
203 category: "account",
204 recipient_type: "customer",
205 to_email: "{customer_email}",
206 isCoreFree: true,
207 settingsFlag: "email_template_customer_verification",
208 settingsSubject: "email_tpl_customer_verification_subject",
209 settingsBody: "email_tpl_customer_verification_body",
210 mergeTags:
211 "{{site_name}}, {{site_url}}, {{customer_first_name}}, {{customer_name}}, {{verification_link}}, {{intro_paragraph}}, {{expiry_notice_html}}, {{footer_note}}",
212 },
213 {
214 template_key: "guest_email_verification",
215 event_key: "account.email_verification",
216 name: __("Guest email verification (checkout)", "yatra"),
217 description: __(
218 "Sent to a guest at checkout who must verify their email before the booking is finalized (when 'Require guest email verification' is enabled). Distinct from the account-registration verification above.",
219 "yatra",
220 ),
221 category: "account",
222 recipient_type: "customer",
223 to_email: "{customer_email}",
224 isCoreFree: true,
225 settingsFlag: "email_template_guest_verification",
226 settingsSubject: "email_tpl_guest_verification_subject",
227 settingsBody: "email_tpl_guest_verification_body",
228 mergeTags:
229 "{{site_name}}, {{site_url}}, {{customer_first_name}}, {{customer_name}}, {{verification_link}}, {{intro_paragraph}}, {{expiry_notice_html}}, {{footer_note}}",
230 },
231 {
232 template_key: "account_email_change_request",
233 event_key: "account.email_change_request",
234 name: __("Account email change request", "yatra"),
235 description: __(
236 "Sent to the NEW address when a customer changes their account email. Contains the confirmation link; the change only applies once they click it.",
237 "yatra",
238 ),
239 category: "account",
240 recipient_type: "customer",
241 to_email: "{new_email}",
242 isCoreFree: true,
243 settingsFlag: "email_template_account_email_change",
244 settingsSubject: "email_tpl_account_email_change_subject",
245 settingsBody: "email_tpl_account_email_change_body",
246 mergeTags:
247 "{{site_name}}, {{site_url}}, {{customer_first_name}}, {{customer_name}}, {{new_email}}, {{verification_link}}, {{intro_paragraph}}, {{footer_note}}",
248 },
249 {
250 template_key: "account_email_changed",
251 event_key: "account.email_changed",
252 name: __("Account email changed", "yatra"),
253 description: __(
254 "Security notice sent to the OLD address once a customer's account email change is confirmed.",
255 "yatra",
256 ),
257 category: "account",
258 recipient_type: "customer",
259 to_email: "{customer_email}",
260 isCoreFree: true,
261 settingsFlag: "email_template_account_email_changed",
262 settingsSubject: "email_tpl_account_email_changed_subject",
263 settingsBody: "email_tpl_account_email_changed_body",
264 mergeTags:
265 "{{site_name}}, {{site_url}}, {{customer_first_name}}, {{customer_name}}, {{new_email}}, {{intro_paragraph}}, {{footer_note}}",
266 },
267 {
268 template_key: "admin_new_booking",
269 event_key: "booking.created",
270 name: __("Admin: New Booking", "yatra"),
271 description: __(
272 "Sent to your admin email when a booking is created. Turn off here to stop this email.",
273 "yatra",
274 ),
275 category: "booking",
276 recipient_type: "admin",
277 to_email: "{{admin_email}}",
278 isCoreFree: true,
279 settingsFlag: "email_template_admin_new_booking",
280 settingsSubject: "email_tpl_admin_booking_subject",
281 settingsBody: "email_tpl_admin_booking_body",
282 mergeTags:
283 "{{site_name}}, {{site_url}}, {{admin_url}}, {{booking_reference}}, {{booking_id}}, {{customer_name}}, {{customer_email}}, {{customer_phone}}, {{trip_name}}, {{travel_date}}, {{travelers_count}}, {{total_amount_formatted}}, {{currency}}, {{booking_status}}, {{payment_status}}, " +
284 BOOKING_RICH_MERGE_TAGS,
285 },
286 {
287 template_key: "admin_payment_received",
288 event_key: "payment.received",
289 name: __("Admin: Payment received", "yatra"),
290 description: __(
291 "Sent to your admin email when a payment is recorded. Customer receipt uses the Payment Received template.",
292 "yatra",
293 ),
294 category: "payment",
295 recipient_type: "admin",
296 to_email: "{{admin_email}}",
297 isCoreFree: true,
298 settingsFlag: "email_template_admin_payment",
299 settingsSubject: "email_tpl_admin_payment_subject",
300 settingsBody: "email_tpl_admin_payment_body",
301 mergeTags:
302 "{{site_name}}, {{admin_url}}, {{booking_reference}}, {{booking_id}}, {{customer_name}}, {{payment_amount_formatted}}, {{payment_method}}, {{transaction_id}}, " +
303 BOOKING_RICH_MERGE_TAGS,
304 },
305 {
306 template_key: "admin_booking_cancelled",
307 event_key: "booking.cancelled",
308 name: __("Admin: Booking cancelled", "yatra"),
309 description: __(
310 "Sent to your admin email when a booking is cancelled. Customer notice uses the Booking Cancellation template.",
311 "yatra",
312 ),
313 category: "booking",
314 recipient_type: "admin",
315 to_email: "{{admin_email}}",
316 isCoreFree: true,
317 settingsFlag: "email_template_admin_cancellation",
318 settingsSubject: "email_tpl_admin_cancellation_subject",
319 settingsBody: "email_tpl_admin_cancellation_body",
320 mergeTags:
321 "{{site_name}}, {{admin_url}}, {{booking_reference}}, {{booking_id}}, {{customer_name}}, {{trip_name}}, {{travel_date}}, " +
322 BOOKING_RICH_MERGE_TAGS,
323 },
324 {
325 template_key: "new_booking",
326 event_key: "booking.created",
327 name: __("New Booking Confirmation", "yatra"),
328 description: __(
329 "Pro automation alternative for the free Booking Confirmation template. Enable Email Automation to edit and send.",
330 "yatra",
331 ),
332 category: "booking",
333 recipient_type: "customer",
334 to_email: "{customer_email}",
335 isCoreFree: false,
336 // Gate behind Email Automation so the free / Pro versions don't appear as
337 // a confusing duplicate in the customer's view (e.g. two "Payment Received"
338 // rows). isModuleGatedLocked() reads this and locks the row when the
339 // module isn't active.
340 requiresModule: "email_automation",
341 },
342 {
343 template_key: "booking_payment",
344 event_key: "payment.received",
345 name: __("Booking payment notice", "yatra"),
346 description: __(
347 "Pro automation alternative for the free Payment Received template. Enable Email Automation to edit and send.",
348 "yatra",
349 ),
350 category: "payment",
351 recipient_type: "customer",
352 to_email: "{customer_email}",
353 isCoreFree: false,
354 requiresModule: "email_automation",
355 },
356 {
357 template_key: "booking_confirmed",
358 event_key: "booking.confirmed",
359 name: __("Booking Confirmed", "yatra"),
360 description: __(
361 "Pro automation template fired on booking confirmation. Enable Email Automation to edit and send.",
362 "yatra",
363 ),
364 category: "booking",
365 recipient_type: "customer",
366 to_email: "{customer_email}",
367 isCoreFree: false,
368 requiresModule: "email_automation",
369 },
370 {
371 template_key: "booking_completed",
372 event_key: "booking.completed",
373 name: __("Trip completed", "yatra"),
374 description: __(
375 "Sent when a booking is marked completed (after travel).",
376 "yatra",
377 ),
378 category: "booking",
379 recipient_type: "customer",
380 to_email: "{customer_email}",
381 isCoreFree: true,
382 settingsFlag: "email_template_booking_completed",
383 settingsSubject: "email_tpl_booking_completed_subject",
384 settingsBody: "email_tpl_booking_completed_body",
385 mergeTags:
386 "{{site_name}}, {{customer_name}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{travel_date}}, {{trip_url}}, " +
387 BOOKING_RICH_MERGE_TAGS,
388 },
389 {
390 template_key: "booking_expired_customer",
391 event_key: "booking.expired",
392 name: __("Booking expired (customer)", "yatra"),
393 description: __(
394 "Sent when a pending booking is auto-cancelled for non-payment.",
395 "yatra",
396 ),
397 category: "booking",
398 recipient_type: "customer",
399 to_email: "{customer_email}",
400 isCoreFree: true,
401 settingsFlag: "email_template_booking_expired_customer",
402 settingsSubject: "email_tpl_booking_expired_customer_subject",
403 settingsBody: "email_tpl_booking_expired_customer_body",
404 mergeTags:
405 "{{site_name}}, {{customer_name}}, {{booking_reference}}, {{trip_name}}, {{travel_date}}, {{trip_url}}, {{expiry_policy_note}}, " +
406 BOOKING_RICH_MERGE_TAGS,
407 },
408 {
409 template_key: "admin_booking_expired",
410 event_key: "booking.expired",
411 name: __("Admin: Booking expired", "yatra"),
412 description: __(
413 "Admin notice when a booking is auto-cancelled for non-payment.",
414 "yatra",
415 ),
416 category: "booking",
417 recipient_type: "admin",
418 to_email: "{{admin_email}}",
419 isCoreFree: true,
420 settingsFlag: "email_template_admin_booking_expired",
421 settingsSubject: "email_tpl_admin_booking_expired_subject",
422 settingsBody: "email_tpl_admin_booking_expired_body",
423 mergeTags:
424 "{{site_name}}, {{admin_url}}, {{booking_reference}}, {{booking_id}}, {{customer_name}}, {{customer_email}}, {{trip_name}}, " +
425 BOOKING_RICH_MERGE_TAGS,
426 },
427 {
428 template_key: "scheduled_payment_reminder",
429 event_key: "scheduled.payment.reminder",
430 name: __("Scheduled payment reminder", "yatra"),
431 description: __(
432 "Sent before an installment or gateway-scheduled charge when Scheduled payments is enabled in settings.",
433 "yatra",
434 ),
435 category: "payment",
436 recipient_type: "customer",
437 to_email: "{customer_email}",
438 isCoreFree: true,
439 requiresModule: "scheduled_payments",
440 settingsFlag: "email_template_scheduled_payment_reminder",
441 settingsSubject: "email_tpl_scheduled_payment_reminder_subject",
442 settingsBody: "email_tpl_scheduled_payment_reminder_body",
443 mergeTags:
444 "{{site_name}}, {{customer_first_name}}, {{customer_name}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{trip_url}}, {{scheduled_amount_formatted}}, {{scheduled_date_formatted}}, {{payment_type_label}}, {{scheduled_payment_id}}, {{currency}}, " +
445 BOOKING_RICH_MERGE_TAGS,
446 },
447 {
448 template_key: "scheduled_payment_succeeded",
449 event_key: "scheduled.payment.succeeded",
450 name: __("Scheduled payment succeeded", "yatra"),
451 description: __(
452 "Sent after a scheduled / installment charge succeeds.",
453 "yatra",
454 ),
455 category: "payment",
456 recipient_type: "customer",
457 to_email: "{customer_email}",
458 isCoreFree: true,
459 requiresModule: "scheduled_payments",
460 settingsFlag: "email_template_scheduled_payment_succeeded",
461 settingsSubject: "email_tpl_scheduled_payment_succeeded_subject",
462 settingsBody: "email_tpl_scheduled_payment_succeeded_body",
463 mergeTags:
464 "{{site_name}}, {{customer_first_name}}, {{customer_name}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{scheduled_amount_formatted}}, {{payment_type_label}}, {{balance_after_formatted}}, {{scheduled_payment_id}}, {{currency}}, " +
465 BOOKING_RICH_MERGE_TAGS,
466 },
467 {
468 template_key: "scheduled_payment_failed",
469 event_key: "scheduled.payment.failed",
470 name: __("Scheduled payment failed", "yatra"),
471 description: __(
472 "Sent when a scheduled charge fails (temporary or final).",
473 "yatra",
474 ),
475 category: "payment",
476 recipient_type: "customer",
477 to_email: "{customer_email}",
478 isCoreFree: true,
479 requiresModule: "scheduled_payments",
480 settingsFlag: "email_template_scheduled_payment_failed",
481 settingsSubject: "email_tpl_scheduled_payment_failed_subject",
482 settingsBody: "email_tpl_scheduled_payment_failed_body",
483 mergeTags:
484 "{{site_name}}, {{customer_first_name}}, {{customer_name}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{scheduled_amount_formatted}}, {{scheduled_payment_id}}, {{failure_reason}}, {{failure_intro_html}}, {{failure_followup_html}}, " +
485 BOOKING_RICH_MERGE_TAGS,
486 },
487 {
488 template_key: "admin_scheduled_payment_failed",
489 event_key: "scheduled.payment.failed",
490 name: __("Admin: Scheduled payment failed", "yatra"),
491 description: __(
492 "Admin notice when a scheduled payment permanently fails.",
493 "yatra",
494 ),
495 category: "payment",
496 recipient_type: "admin",
497 to_email: "{{admin_email}}",
498 isCoreFree: true,
499 requiresModule: "scheduled_payments",
500 settingsFlag: "email_template_admin_scheduled_payment_failed",
501 settingsSubject: "email_tpl_admin_scheduled_payment_failed_subject",
502 settingsBody: "email_tpl_admin_scheduled_payment_failed_body",
503 mergeTags:
504 "{{site_name}}, {{admin_url}}, {{booking_reference}}, {{booking_id}}, {{trip_name}}, {{customer_name}}, {{customer_email}}, {{scheduled_amount_formatted}}, {{scheduled_payment_id}}, {{failure_reason}}, " +
505 BOOKING_RICH_MERGE_TAGS,
506 },
507 {
508 template_key: "payment_reminder",
509 event_key: "payment.reminder",
510 name: __("Payment Reminder", "yatra"),
511 description: __(
512 "Pro automation template. Enable Email Automation to edit and send.",
513 "yatra",
514 ),
515 category: "payment",
516 recipient_type: "customer",
517 to_email: "{customer_email}",
518 isCoreFree: false,
519 },
520 {
521 template_key: "enquiry_received",
522 event_key: "enquiry.created",
523 name: __("Enquiry Received", "yatra"),
524 description: __(
525 "Confirmation sent to the customer after they submit an enquiry.",
526 "yatra",
527 ),
528 category: "enquiry",
529 recipient_type: "customer",
530 to_email: "{customer_email}",
531 isCoreFree: true,
532 settingsFlag: "email_template_enquiry_received",
533 settingsSubject: "email_tpl_enquiry_received_subject",
534 settingsBody: "email_tpl_enquiry_received_body",
535 mergeTags:
536 "{{site_name}}, {{customer_name}}, {{customer_email}}, {{customer_phone}}, {{trip_name}}, {{trip_url}}, {{message}}",
537 },
538 {
539 template_key: "enquiry_admin",
540 event_key: "enquiry.created",
541 name: __("Admin: New Enquiry", "yatra"),
542 description: __(
543 "Sent to your admin email when a new enquiry is submitted.",
544 "yatra",
545 ),
546 category: "enquiry",
547 recipient_type: "admin",
548 to_email: "{{admin_email}}",
549 isCoreFree: true,
550 settingsFlag: "email_template_enquiry_admin",
551 settingsSubject: "email_tpl_enquiry_admin_subject",
552 settingsBody: "email_tpl_enquiry_admin_body",
553 mergeTags:
554 "{{site_name}}, {{admin_url}}, {{customer_name}}, {{customer_email}}, {{customer_phone}}, {{trip_name}}, {{message}}",
555 },
556 {
557 template_key: "enquiry_response",
558 event_key: "enquiry.responded",
559 name: __("Enquiry Response", "yatra"),
560 description: __(
561 "Sent to the customer when you reply to their enquiry.",
562 "yatra",
563 ),
564 category: "enquiry",
565 recipient_type: "customer",
566 to_email: "{customer_email}",
567 isCoreFree: true,
568 settingsFlag: "email_template_enquiry_response",
569 settingsSubject: "email_tpl_enquiry_response_subject",
570 settingsBody: "email_tpl_enquiry_response_body",
571 mergeTags:
572 "{{site_name}}, {{customer_name}}, {{customer_email}}, {{trip_name}}, {{trip_url}}, {{response}}, {{response_message}}, {{original_message}}",
573 },
574 {
575 template_key: "review_request",
576 event_key: "marketing.review_request",
577 name: __("Review Request", "yatra"),
578 description: __(
579 "Queued when a booking is marked completed, then sent after the delay in Review settings (if reviews are enabled).",
580 "yatra",
581 ),
582 category: "marketing",
583 recipient_type: "customer",
584 to_email: "{customer_email}",
585 isCoreFree: true,
586 settingsFlag: "email_template_review_request",
587 settingsSubject: "email_tpl_review_request_subject",
588 settingsBody: "email_tpl_review_request_body",
589 mergeTags:
590 "{{site_name}}, {{customer_name}}, {{trip_name}}, {{review_url}}, {{booking_reference}}, " +
591 BOOKING_RICH_MERGE_TAGS,
592 },
593 {
594 template_key: "abandoned_booking_recovery_first",
595 event_key: "booking.abandoned_recovery",
596 name: __("Abandoned booking recovery (First)", "yatra"),
597 description: sprintf(
598 /* translators: %s: brand name (e.g. "Yatra Pro" or operator's white-labeled brand) */
599 __(
600 "First reminder sent by %s abandoned checkout recovery (module copy in {{recovery_intro_html}}).",
601 "yatra",
602 ),
603 BRAND_PRO_NAME,
604 ),
605 category: "booking",
606 recipient_type: "customer",
607 to_email: "{customer_email}",
608 isCoreFree: true,
609 requiresModule: "abandoned_booking_recovery",
610 settingsFlag: "email_template_abandoned_booking_recovery_first",
611 settingsSubject: "email_tpl_abandoned_booking_recovery_first_subject",
612 settingsBody: "email_tpl_abandoned_booking_recovery_first_body",
613 mergeTags:
614 "{{site_name}}, {{customer_name}}, {{trip_name}}, {{recovery_link}}, {{booking_reference}}, {{recovery_reminder_label}}, {{recovery_intro_html}}, " +
615 BOOKING_RICH_MERGE_TAGS,
616 },
617 {
618 template_key: "abandoned_booking_recovery_second",
619 event_key: "booking.abandoned_recovery",
620 name: __("Abandoned booking recovery (Second)", "yatra"),
621 description: sprintf(
622 /* translators: %s: brand name */
623 __(
624 "Second reminder sent by %s abandoned checkout recovery (module copy in {{recovery_intro_html}}).",
625 "yatra",
626 ),
627 BRAND_PRO_NAME,
628 ),
629 category: "booking",
630 recipient_type: "customer",
631 to_email: "{customer_email}",
632 isCoreFree: true,
633 requiresModule: "abandoned_booking_recovery",
634 settingsFlag: "email_template_abandoned_booking_recovery_second",
635 settingsSubject: "email_tpl_abandoned_booking_recovery_second_subject",
636 settingsBody: "email_tpl_abandoned_booking_recovery_second_body",
637 mergeTags:
638 "{{site_name}}, {{customer_name}}, {{trip_name}}, {{recovery_link}}, {{booking_reference}}, {{recovery_reminder_label}}, {{recovery_intro_html}}, " +
639 BOOKING_RICH_MERGE_TAGS,
640 },
641 {
642 template_key: "abandoned_booking_recovery_final",
643 event_key: "booking.abandoned_recovery",
644 name: __("Abandoned booking recovery (Final)", "yatra"),
645 description: sprintf(
646 /* translators: %s: brand name */
647 __(
648 "Final reminder sent by %s abandoned checkout recovery (module copy in {{recovery_intro_html}}).",
649 "yatra",
650 ),
651 BRAND_PRO_NAME,
652 ),
653 category: "booking",
654 recipient_type: "customer",
655 to_email: "{customer_email}",
656 isCoreFree: true,
657 requiresModule: "abandoned_booking_recovery",
658 settingsFlag: "email_template_abandoned_booking_recovery_final",
659 settingsSubject: "email_tpl_abandoned_booking_recovery_final_subject",
660 settingsBody: "email_tpl_abandoned_booking_recovery_final_body",
661 mergeTags:
662 "{{site_name}}, {{customer_name}}, {{trip_name}}, {{recovery_link}}, {{booking_reference}}, {{recovery_reminder_label}}, {{recovery_intro_html}}, " +
663 BOOKING_RICH_MERGE_TAGS,
664 },
665 ];
666
667 export function getCatalogEntryByTemplateKey(
668 key: string,
669 ): EmailCatalogEntry | undefined {
670 return EMAIL_TEMPLATES_CATALOG.find((e) => e.template_key === key);
671 }
672
673 export function getCoreTemplateDefinition(
674 slug: string,
675 ): EmailCatalogEntry | undefined {
676 const e = getCatalogEntryByTemplateKey(slug);
677 return e?.isCoreFree ? e : undefined;
678 }
679
680 /** UI row shape for the shared templates table (API or settings-backed). */
681 export type UnifiedEmailTemplate = {
682 id: string | number;
683 template_key: string;
684 event_key: string;
685 name: string;
686 description: string;
687 subject: string;
688 body: string;
689 category: string;
690 recipient_type: "customer" | "admin";
691 to_email?: string;
692 from_email?: string;
693 from_name?: string;
694 reply_to?: string;
695 is_active: boolean;
696 is_system: boolean;
697 is_locked: boolean;
698 variables: string[];
699 created_at?: string;
700 updated_at?: string;
701 };
702
703 export type BuildLocalTemplateRowsOptions = {
704 isProPluginActive: boolean;
705 isModuleActive: (slug: string) => boolean;
706 };
707
708 export function buildLocalTemplateRows(
709 values: EmailSettingsValues,
710 options?: BuildLocalTemplateRowsOptions,
711 ): UnifiedEmailTemplate[] {
712 const pro = options?.isProPluginActive ?? false;
713 const moduleOk = (slug: string) =>
714 options?.isModuleActive ? options.isModuleActive(slug) : false;
715
716 // Sites that never take a deposit or part payment have no use for the
717 // part-payment template, so it is hidden rather than shown inert.
718 const partialPaymentsOn = Boolean(
719 values.partial_payment || values.enable_deposit || values.deposit_required,
720 );
721
722 return EMAIL_TEMPLATES_CATALOG.filter(
723 (entry) => !entry.requiresPartialPayments || partialPaymentsOn,
724 ).map((entry) => {
725 const moduleGateOk =
726 !entry.requiresModule || (pro && moduleOk(entry.requiresModule));
727
728 const proCatalogLocked = !entry.isCoreFree;
729 const moduleContentLocked = Boolean(entry.requiresModule) && !moduleGateOk;
730
731 const is_locked = proCatalogLocked || moduleContentLocked;
732
733 const hasSettingsKeys = Boolean(
734 entry.settingsFlag && entry.settingsSubject && entry.settingsBody,
735 );
736
737 const subject = entry.settingsSubject
738 ? String(values[entry.settingsSubject] ?? "")
739 : "";
740 const body = entry.settingsBody
741 ? String(values[entry.settingsBody] ?? "")
742 : "";
743 const isActive = entry.settingsFlag
744 ? Boolean(values[entry.settingsFlag])
745 : false;
746
747 const id =
748 entry.isCoreFree || hasSettingsKeys
749 ? `core:${entry.template_key}`
750 : `locked:${entry.template_key}`;
751
752 return {
753 id,
754 template_key: entry.template_key,
755 event_key: entry.event_key,
756 name: entry.name,
757 description: entry.description,
758 subject,
759 body,
760 category: entry.category,
761 recipient_type: entry.recipient_type,
762 to_email: entry.to_email,
763 is_active: hasSettingsKeys ? isActive : false,
764 is_system: true,
765 is_locked,
766 variables: [],
767 };
768 });
769 }
770