snapshot: preserve handbook, bilingual phase 2, and logo updates

This commit is contained in:
Md Bayazid Bostame
2026-03-24 12:25:43 +01:00
parent 0f285aa2cf
commit 4d3c7bdf6e
26 changed files with 625 additions and 66 deletions

View File

@@ -8,6 +8,7 @@ from celery import shared_task
from django.contrib.auth import get_user_model
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext as _, get_language
from jinja2 import Template
from pypdf import PageObject, PdfReader, PdfWriter
from xhtml2pdf import pisa
@@ -294,7 +295,7 @@ def _matches_intro_condition(request_obj: OnboardingRequest, item: IntroChecklis
return True
def _build_intro_sections_from_admin(request_obj: OnboardingRequest) -> dict[str, list[str]]:
def _build_intro_sections_from_admin(request_obj: OnboardingRequest, language_code: str | None = None) -> dict[str, list[str]]:
items = list(IntroChecklistItem.objects.filter(is_active=True).order_by('section', 'sort_order', 'label'))
if not items:
return {}
@@ -304,11 +305,26 @@ def _build_intro_sections_from_admin(request_obj: OnboardingRequest) -> dict[str
if item.section not in section_map:
continue
if _matches_intro_condition(request_obj, item):
section_map[item.section].append(item.label)
section_map[item.section].append(item.translated_label(language_code))
return {key: values for key, values in section_map.items() if values}
def build_intro_sections_for_request(request_obj: OnboardingRequest) -> list[dict]:
def build_intro_sections_for_request(request_obj: OnboardingRequest, language_code: str | None = None) -> list[dict]:
lang = (language_code or get_language() or 'de').split('-')[0]
section_titles = {
'de': {
'workplace': 'Geräte und Arbeitsplatz',
'accounts': 'Konten und Berechtigungen',
'software': 'Software und Tools',
'process': 'Prozesse und Hinweise',
},
'en': {
'workplace': 'Devices and workplace',
'accounts': 'Accounts and permissions',
'software': 'Software and tools',
'process': 'Processes and notes',
},
}
devices = _split_multiline(request_obj.needed_devices)
software = _split_multiline(request_obj.needed_software)
accesses = _split_multiline(request_obj.needed_accesses)
@@ -354,12 +370,12 @@ def build_intro_sections_for_request(request_obj: OnboardingRequest) -> list[dic
if request_obj.successor_name:
process_items.append(f'Übergabe-/Nachfolgekontext besprochen: {request_obj.successor_name}')
custom_intro_items = _build_intro_sections_from_admin(request_obj)
custom_intro_items = _build_intro_sections_from_admin(request_obj, lang)
intro_sections_raw = [
('workplace', 'Geräte und Arbeitsplatz', workplace_items),
('accounts', 'Konten und Berechtigungen', account_items),
('software', 'Software und Tools', software_items),
('process', 'Prozesse und Hinweise', process_items),
('workplace', section_titles.get(lang, section_titles['de'])['workplace'], workplace_items),
('accounts', section_titles.get(lang, section_titles['de'])['accounts'], account_items),
('software', section_titles.get(lang, section_titles['de'])['software'], software_items),
('process', section_titles.get(lang, section_titles['de'])['process'], process_items),
]
sections = []
@@ -714,7 +730,7 @@ def _generate_onboarding_pdf(request_obj: OnboardingRequest) -> Path:
return output_pdf
def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest) -> Path:
def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest, language_code: str | None = None) -> Path:
safe_name = _safe_filename_fragment(request_obj.full_name, fallback=f'onboarding_intro_{request_obj.id}')
output_pdf = settings.PDF_OUTPUT_DIR / f'onboarding_intro_{safe_name}.pdf'
temp_pdf = settings.PDF_OUTPUT_DIR / f'_temp_onboarding_intro_{safe_name}.pdf'
@@ -729,7 +745,7 @@ def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest) -> Path:
'title': section['title'],
'rows': _chunk_list([item['label'] for item in section['items']], chunk_size=2),
}
for section in build_intro_sections_for_request(request_obj)
for section in build_intro_sections_for_request(request_obj, language_code=language_code)
]
requester_email = request_obj.onboarded_by_email or '-'
@@ -755,7 +771,11 @@ def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest) -> Path:
return output_pdf
def _generate_onboarding_intro_session_pdf(session: OnboardingIntroductionSession, admin_signature_name: str = '-') -> Path:
def _generate_onboarding_intro_session_pdf(
session: OnboardingIntroductionSession,
admin_signature_name: str = '-',
language_code: str | None = None,
) -> Path:
request_obj = session.onboarding_request
safe_name = _safe_filename_fragment(request_obj.full_name, fallback=f'onboarding_intro_session_{request_obj.id}')
version = timezone.now().strftime('%Y%m%d%H%M%S')
@@ -768,7 +788,7 @@ def _generate_onboarding_intro_session_pdf(session: OnboardingIntroductionSessio
salutation = (request_obj.get_gender_display() or '').strip()
display_name = f"{salutation} {request_obj.full_name}".strip() if salutation else request_obj.full_name
raw_sections = build_intro_sections_for_request(request_obj)
raw_sections = build_intro_sections_for_request(request_obj, language_code=language_code)
checked_map = session.checklist_state or {}
exported_sections = []
checked_count = 0