snapshot: preserve company config integration and pdf cleanup

This commit is contained in:
Md Bayazid Bostame
2026-03-26 14:13:03 +01:00
parent 7bd03fc86e
commit 8821a7943b
5 changed files with 77 additions and 4 deletions

View File

@@ -151,6 +151,7 @@
.manual-grid td {
width: 50%;
}
</style>
</head>
<body>

View File

@@ -134,6 +134,7 @@
vertical-align: bottom;
margin: 0 6px;
}
</style>
</head>
<body>

View File

@@ -125,6 +125,7 @@
.muted-cell {
color: #64748b;
}
</style>
</head>
<body>

View File

@@ -149,6 +149,43 @@ def get_branding_email_copy() -> dict[str, str]:
}
def get_company_contact_copy() -> dict[str, str]:
branding = get_portal_branding()
company_config = get_portal_company_config()
company_name = (branding.company_name or 'TUBCO').strip()
legal_name = (company_config.legal_company_name or company_name).strip()
domain = get_company_email_domain()
support_email = (branding.support_email or '').strip()
it_contact_email = (company_config.it_contact_email or support_email or f'it@{domain}').strip()
hr_contact_email = (company_config.hr_contact_email or support_email or f'hr@{domain}').strip()
operations_contact_email = (company_config.operations_contact_email or support_email or f'info@{domain}').strip()
address_parts = [
(company_config.street_address or '').strip(),
' '.join(part for part in [(company_config.postal_code or '').strip(), (company_config.city or '').strip()] if part).strip(),
(company_config.country or '').strip(),
]
address = ', '.join(part for part in address_parts if part)
return {
'company_name': company_name,
'legal_company_name': legal_name,
'support_email': support_email,
'it_contact_email': it_contact_email,
'hr_contact_email': hr_contact_email,
'operations_contact_email': operations_contact_email,
'phone_number': (company_config.phone_number or '').strip(),
'website_url': (company_config.website_url or '').strip(),
'imprint_url': (company_config.imprint_url or '').strip(),
'privacy_url': (company_config.privacy_url or '').strip(),
'address': address,
'street_address': (company_config.street_address or '').strip(),
'postal_code': (company_config.postal_code or '').strip(),
'city': (company_config.city or '').strip(),
'country': (company_config.country or '').strip(),
'registration_number': (company_config.registration_number or '').strip(),
'vat_id': (company_config.vat_id or '').strip(),
}
def get_branded_from_email(email_address: str | None) -> str | None:
address = (email_address or '').strip()
if not address:
@@ -166,8 +203,9 @@ def get_default_notification_templates() -> dict[str, dict[str, str]]:
templates = deepcopy(DEFAULT_NOTIFICATION_TEMPLATES)
branding_copy = get_branding_email_copy()
company_contact = get_company_contact_copy()
company_name = branding_copy['company_name']
support_email = branding_copy['support_email'] or f"it@{branding_copy['company_domain']}"
support_email = company_contact['it_contact_email'] or branding_copy['support_email'] or f"it@{branding_copy['company_domain']}"
welcome = templates.get('onboarding_welcome')
if welcome:
welcome['subject'] = f'Willkommen bei {company_name}, {{ VORNAME }}'

View File

@@ -13,7 +13,7 @@ from jinja2 import Template
from pypdf import PageObject, PdfReader, PdfWriter
from xhtml2pdf import pisa
from .branding import get_default_notification_templates, get_portal_letterhead_path
from .branding import get_company_contact_copy, get_default_notification_templates, get_portal_letterhead_path
from .models import EmployeeProfile, IntroChecklistItem, NotificationRule, NotificationTemplate, OffboardingRequest, OnboardingIntroductionSession, OnboardingRequest, ScheduledWelcomeEmail, WorkflowConfig
from .emailing import send_system_email
from .services import upload_to_nextcloud
@@ -867,6 +867,7 @@ def _generate_onboarding_pdf(request_obj: OnboardingRequest) -> Path:
template_path = settings.PDF_TEMPLATES_DIR / 'onboarding_template.html'
letterhead_path = get_portal_letterhead_path()
company_contact = get_company_contact_copy()
devices = _split_multiline(request_obj.needed_devices)
software = _split_multiline(request_obj.needed_software)
@@ -980,6 +981,11 @@ def _generate_onboarding_pdf(request_obj: OnboardingRequest) -> Path:
'UNTERSCHRIFT_HINWEIS': signature_note,
'REQUESTED_BY_NAME': requester_name,
'REQUESTED_BY_EMAIL': requester_email,
'COMPANY_LEGAL_NAME': company_contact['legal_company_name'] or company_contact['company_name'],
'COMPANY_ADDRESS': company_contact['address'] or t['not_available_short'],
'COMPANY_IT_CONTACT': company_contact['it_contact_email'] or t['not_available_short'],
'COMPANY_HR_CONTACT': company_contact['hr_contact_email'] or t['not_available_short'],
'COMPANY_PHONE': company_contact['phone_number'] or t['not_available_short'],
}
html = _render_html(template_path, context)
@@ -1000,6 +1006,7 @@ def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest, language_code
template_path = settings.PDF_TEMPLATES_DIR / 'onboarding_intro_template.html'
letterhead_path = get_portal_letterhead_path()
company_contact = get_company_contact_copy()
salutation = (request_obj.get_gender_display() or '').strip()
display_name = f"{salutation} {request_obj.full_name}".strip() if salutation else request_obj.full_name
@@ -1024,6 +1031,11 @@ def _generate_onboarding_intro_pdf(request_obj: OnboardingRequest, language_code
'REQUESTED_BY_NAME': requester_name,
'REQUESTED_BY_EMAIL': requester_email,
'INTRO_SECTIONS': intro_sections,
'COMPANY_LEGAL_NAME': company_contact['legal_company_name'] or company_contact['company_name'],
'COMPANY_ADDRESS': company_contact['address'] or t['not_available_short'],
'COMPANY_IT_CONTACT': company_contact['it_contact_email'] or t['not_available_short'],
'COMPANY_HR_CONTACT': company_contact['hr_contact_email'] or t['not_available_short'],
'COMPANY_PHONE': company_contact['phone_number'] or t['not_available_short'],
}
html = _render_html(template_path, context)
@@ -1050,6 +1062,7 @@ def _generate_onboarding_intro_session_pdf(
template_path = settings.PDF_TEMPLATES_DIR / 'onboarding_intro_session_pdf.html'
letterhead_path = get_portal_letterhead_path()
company_contact = get_company_contact_copy()
salutation = (request_obj.get_gender_display() or '').strip()
display_name = f"{salutation} {request_obj.full_name}".strip() if salutation else request_obj.full_name
@@ -1091,6 +1104,11 @@ def _generate_onboarding_intro_session_pdf(
'SESSION_UPDATED_AT': session.updated_at,
'SESSION_NOTES': session.notes or t['not_available_short'],
'INTRO_SECTIONS': exported_sections,
'COMPANY_LEGAL_NAME': company_contact['legal_company_name'] or company_contact['company_name'],
'COMPANY_ADDRESS': company_contact['address'] or t['not_available_short'],
'COMPANY_IT_CONTACT': company_contact['it_contact_email'] or t['not_available_short'],
'COMPANY_HR_CONTACT': company_contact['hr_contact_email'] or t['not_available_short'],
'COMPANY_PHONE': company_contact['phone_number'] or t['not_available_short'],
}
html = _render_html(template_path, context)
@@ -1111,6 +1129,7 @@ def _generate_offboarding_pdf(request_obj: OffboardingRequest) -> Path:
template_path = settings.PDF_TEMPLATES_DIR / 'offboarding_template.html'
letterhead_path = get_portal_letterhead_path()
company_contact = get_company_contact_copy()
latest_onboarding = (
OnboardingRequest.objects.filter(work_email=request_obj.work_email)
.order_by('-created_at')
@@ -1158,6 +1177,11 @@ def _generate_offboarding_pdf(request_obj: OffboardingRequest) -> Path:
'MANUAL_RESOURCES': _chunk_choice_labels(RESOURCE_CHOICES),
'MANUAL_EXTRA_HARDWARE': _chunk_choice_labels(HARDWARE_EXTRA_CHOICES),
'MANUAL_EXTRA_SOFTWARE': _chunk_choice_labels(SOFTWARE_EXTRA_CHOICES),
'COMPANY_LEGAL_NAME': company_contact['legal_company_name'] or company_contact['company_name'],
'COMPANY_ADDRESS': company_contact['address'] or t['not_available_short'],
'COMPANY_IT_CONTACT': company_contact['it_contact_email'] or t['not_available_short'],
'COMPANY_HR_CONTACT': company_contact['hr_contact_email'] or t['not_available_short'],
'COMPANY_PHONE': company_contact['phone_number'] or t['not_available_short'],
}
html = _render_html(template_path, context)
@@ -1177,6 +1201,7 @@ def process_onboarding_request(onboarding_request_id: int) -> None:
request_obj.save(update_fields=['processing_status', 'last_error'])
try:
branding_copy = get_branding_email_copy()
company_contact = get_company_contact_copy()
it_email, general_info_email, business_card_email, hr_works_email, key_email = _resolve_workflow_emails()
salutation = (request_obj.get_gender_display() or '').strip()
display_name = f"{salutation} {request_obj.full_name}".strip()
@@ -1205,7 +1230,10 @@ def process_onboarding_request(onboarding_request_id: int) -> None:
'CONTRACT_START': request_obj.contract_start,
'EMAIL': request_obj.work_email,
'REQUESTED_BY': request_obj.onboarded_by_email or '-',
'SUPPORT_EMAIL': branding_copy['support_email'] or f"it@{branding_copy['company_domain']}",
'SUPPORT_EMAIL': company_contact['it_contact_email'] or branding_copy['support_email'] or f"it@{branding_copy['company_domain']}",
'IT_CONTACT_EMAIL': company_contact['it_contact_email'],
'HR_CONTACT_EMAIL': company_contact['hr_contact_email'],
'OPERATIONS_CONTACT_EMAIL': company_contact['operations_contact_email'],
'BUSINESS_CARD_NAME': request_obj.business_card_name or display_name,
'BUSINESS_CARD_TITLE': request_obj.business_card_title or '-',
'BUSINESS_CARD_EMAIL': request_obj.business_card_email or request_obj.work_email,
@@ -1288,6 +1316,7 @@ def process_offboarding_request(offboarding_request_id: int) -> None:
request_obj.save(update_fields=['processing_status', 'last_error'])
try:
branding_copy = get_branding_email_copy()
company_contact = get_company_contact_copy()
it_email, general_info_email, _, hr_works_email, _ = _resolve_workflow_emails()
pdf_path = _generate_offboarding_pdf(request_obj)
@@ -1300,7 +1329,10 @@ def process_offboarding_request(offboarding_request_id: int) -> None:
'LAST_WORKING_DAY': request_obj.last_working_day,
'REQUESTED_BY': request_obj.requested_by_email,
'EMAIL': request_obj.work_email,
'SUPPORT_EMAIL': branding_copy['support_email'] or f"it@{branding_copy['company_domain']}",
'SUPPORT_EMAIL': company_contact['it_contact_email'] or branding_copy['support_email'] or f"it@{branding_copy['company_domain']}",
'IT_CONTACT_EMAIL': company_contact['it_contact_email'],
'HR_CONTACT_EMAIL': company_contact['hr_contact_email'],
'OPERATIONS_CONTACT_EMAIL': company_contact['operations_contact_email'],
}
_send_templated_email(