snapshot: preserve bilingual email template phase

This commit is contained in:
Md Bayazid Bostame
2026-03-24 12:37:35 +01:00
parent 4d3c7bdf6e
commit ec00ae8b2e
9 changed files with 275 additions and 18 deletions

View File

@@ -32,6 +32,7 @@ from .forms import (
DEFAULT_NOTIFICATION_TEMPLATES = {
'onboarding_it': {
'subject': '[Onboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Onboarding] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Neue Onboarding-Anfrage für {{ FULL_NAME }}.\n'
'Abteilung: {{ DEPARTMENT }}\n'
@@ -39,9 +40,17 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Angefordert von: {{ REQUESTED_BY }}\n'
'Bitte IT-Setup vorbereiten.'
),
'body_en': (
'New onboarding request for {{ FULL_NAME }}.\n'
'Department: {{ DEPARTMENT }}\n'
'Contract start: {{ CONTRACT_START }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
'Please prepare the IT setup.'
),
},
'onboarding_general_info': {
'subject': '[Info Onboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Onboarding Info] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Hallo,\n\n'
'{{ FULL_NAME }} wird onboarded.\n'
@@ -49,9 +58,17 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Vertragsbeginn: {{ CONTRACT_START }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'Hello,\n\n'
'{{ FULL_NAME }} is being onboarded.\n'
'Department: {{ DEPARTMENT }}\n'
'Contract start: {{ CONTRACT_START }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'onboarding_business_card': {
'subject': '[Visitenkarte] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Business Card] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Hallo,\n\n'
'bitte Visitenkarten erstellen:\n'
@@ -61,9 +78,19 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Telefon: {{ BUSINESS_CARD_PHONE }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'Hello,\n\n'
'please create business cards:\n'
'Name: {{ BUSINESS_CARD_NAME }}\n'
'Title: {{ BUSINESS_CARD_TITLE }}\n'
'Email: {{ BUSINESS_CARD_EMAIL }}\n'
'Phone: {{ BUSINESS_CARD_PHONE }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'onboarding_hr_works': {
'subject': '[HR Works] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[HR Works] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Hello Stefanie,\n\n'
'Es ist wieder soweit. Zuwachs!\n\n'
@@ -77,9 +104,23 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Vielen Dank und schöne Grüße,\n'
'Die IT.'
),
'body_en': (
'Hello Stefanie,\n\n'
'we have a new team member joining.\n\n'
'Could you please create an HR Works account with the following details:\n\n'
'Name: {{ VORNAME }} {{ NACHNAME }}\n'
'Department: {{ DEPARTMENT }}\n'
'Contract start: {{ CONTRACT_START }}\n'
'Email address: {{ EMAIL }}\n\n'
'{% if PDF_LINK %}You will find the employee PDF here in about 2 minutes: {{ PDF_LINK }}\n\n{% endif %}'
'If you need any other information, please contact it@tub.co.\n\n'
'Thank you and best regards,\n'
'IT'
),
},
'onboarding_key': {
'subject': '[Schlüssel] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Key] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Hallo,\n\n'
'bitte Schlüssel vorbereiten für:\n'
@@ -88,9 +129,18 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Vertragsbeginn: {{ CONTRACT_START }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'Hello,\n\n'
'please prepare keys for:\n'
'Name: {{ FULL_NAME }}\n'
'Department: {{ DEPARTMENT }}\n'
'Contract start: {{ CONTRACT_START }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'onboarding_reference': {
'subject': '[Referenz Onboarding] {{ FULL_NAME }} | Ihre Anfrage',
'subject_en': '[Onboarding Reference] {{ FULL_NAME }} | Your Request',
'body': (
'Diese E-Mail dient als Referenz für Ihre Onboarding-Anfrage.\n'
'Name: {{ FULL_NAME }}\n'
@@ -98,9 +148,17 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Vertragsbeginn: {{ CONTRACT_START }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'This email is your reference copy for the onboarding request.\n'
'Name: {{ FULL_NAME }}\n'
'Department: {{ DEPARTMENT }}\n'
'Contract start: {{ CONTRACT_START }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'onboarding_welcome': {
'subject': 'Willkommen bei TUB/CO, {{ VORNAME }}',
'subject_en': 'Welcome to TUB/CO, {{ VORNAME }}',
'body': (
'Hallo {{ FULL_NAME }},\n\n'
'herzlich willkommen bei TUB/CO.\n'
@@ -111,9 +169,20 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Viele Grüße\n'
'TUB/CO IT'
),
'body_en': (
'Hello {{ FULL_NAME }},\n\n'
'welcome to TUB/CO.\n'
'We are very happy that you will join our {{ DEPARTMENT }} team starting on {{ CONTRACT_START }}.\n\n'
'Your work email address is: {{ EMAIL }}.\n'
'You will find your onboarding documents attached as a PDF.\n\n'
'If you have any questions, feel free to contact us anytime.\n\n'
'Best regards,\n'
'TUB/CO IT'
),
},
'offboarding_it': {
'subject': '[Offboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Offboarding] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Neue Offboarding-Anfrage für {{ FULL_NAME }}.\n'
'Abteilung: {{ DEPARTMENT }}\n'
@@ -121,25 +190,45 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Angefordert von: {{ REQUESTED_BY }}\n'
'Bitte IT-Offboarding durchführen.'
),
'body_en': (
'New offboarding request for {{ FULL_NAME }}.\n'
'Department: {{ DEPARTMENT }}\n'
'Last working day: {{ LAST_WORKING_DAY }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
'Please complete the IT offboarding.'
),
},
'offboarding_general_info': {
'subject': '[Info Offboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[Offboarding Info] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Neue Offboarding-Anfrage für {{ FULL_NAME }}.\n'
'Abteilung: {{ DEPARTMENT }}\n'
'Letzter Arbeitstag: {{ LAST_WORKING_DAY }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'New offboarding request for {{ FULL_NAME }}.\n'
'Department: {{ DEPARTMENT }}\n'
'Last working day: {{ LAST_WORKING_DAY }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'offboarding_hr_works_disable': {
'subject': '[HR Works Deaktivierung] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
'subject_en': '[HR Works Disable] {{ FULL_NAME }} | Requested by {{ REQUESTED_BY }}',
'body': (
'Bitte HR Works Zugriff deaktivieren für {{ FULL_NAME }} ({{ EMAIL }}) zum {{ LAST_WORKING_DAY }}.\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'Please disable HR Works access for {{ FULL_NAME }} ({{ EMAIL }}) effective {{ LAST_WORKING_DAY }}.\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
'offboarding_reference': {
'subject': '[Referenz Offboarding] {{ FULL_NAME }} | Ihre Anfrage',
'subject_en': '[Offboarding Reference] {{ FULL_NAME }} | Your Request',
'body': (
'Diese E-Mail dient als Referenz für Ihre Offboarding-Anfrage.\n'
'Name: {{ FULL_NAME }}\n'
@@ -147,6 +236,13 @@ DEFAULT_NOTIFICATION_TEMPLATES = {
'Letzter Arbeitstag: {{ LAST_WORKING_DAY }}\n'
'Angefordert von: {{ REQUESTED_BY }}\n'
),
'body_en': (
'This email is your reference copy for the offboarding request.\n'
'Name: {{ FULL_NAME }}\n'
'Department: {{ DEPARTMENT }}\n'
'Last working day: {{ LAST_WORKING_DAY }}\n'
'Requested by: {{ REQUESTED_BY }}\n'
),
},
}
@@ -419,15 +515,16 @@ def _send_workflow_email(
)
def _render_notification_template(template_key: str, context: dict) -> tuple[str, str]:
def _render_notification_template(template_key: str, context: dict, language_code: str | None = None) -> tuple[str, str]:
lang = (language_code or 'de').split('-')[0]
db_template = NotificationTemplate.objects.filter(key=template_key, is_active=True).first()
if db_template:
subject_template = db_template.subject_template
body_template = db_template.body_template
subject_template = db_template.translated_subject_template(lang)
body_template = db_template.translated_body_template(lang)
else:
fallback = DEFAULT_NOTIFICATION_TEMPLATES[template_key]
subject_template = fallback['subject']
body_template = fallback['body']
subject_template = fallback.get(f'subject_{lang}', '') or fallback['subject']
body_template = fallback.get(f'body_{lang}', '') or fallback['body']
subject = Template(subject_template).render(context).strip()
body = Template(body_template).render(context).strip()
@@ -475,6 +572,7 @@ def _apply_notification_rules(
context: dict,
pdf_path: Path | None = None,
) -> None:
language_code = (getattr(request_obj, 'preferred_language', '') or 'de').split('-')[0]
rules = NotificationRule.objects.filter(event_type=event_type, is_active=True).order_by('sort_order', 'id')
for rule in rules:
if not _rule_matches(rule, request_obj):
@@ -494,11 +592,12 @@ def _apply_notification_rules(
context=context,
to=recipients,
attachments=attachments,
language_code=language_code,
)
continue
subject = (rule.custom_subject or '').strip()
body = (rule.custom_body or '').strip()
subject = rule.translated_custom_subject(language_code)
body = rule.translated_custom_body(language_code)
if not subject and not body:
continue
@@ -547,8 +646,9 @@ def _send_templated_email(
context: dict,
attachments: list[Path] | None = None,
from_email: str | None = None,
language_code: str | None = None,
) -> None:
subject, body = _render_notification_template(template_key, context)
subject, body = _render_notification_template(template_key, context, language_code=language_code)
_send_workflow_email(subject=subject, body=body, to=to, attachments=attachments, from_email=from_email)