from __future__ import annotations from pathlib import Path from email.utils import formataddr from django.conf import settings from django.templatetags.static import static from django.utils import timezone from django.utils.translation import get_language from .models import PortalBranding, PortalCompanyConfig, PortalTrialConfig def get_portal_branding() -> PortalBranding: branding, _ = PortalBranding.objects.get_or_create( name='Default', defaults={ 'portal_title': 'Workdock', 'company_name': 'Workdock', 'company_domain': 'workdock.de', 'support_email': 'info@workdock.de', 'sender_display_name': 'Workdock', 'login_subtitle': 'Bitte melden Sie sich mit Ihrem Benutzerkonto an.', 'footer_text': 'Workdock', 'footer_text_en': 'Workdock', 'legal_notice': '', 'legal_notice_en': '', 'default_language': 'de', 'primary_color': '#000078', 'secondary_color': '#c0002b', }, ) return branding def get_portal_company_config() -> PortalCompanyConfig: company_config, _ = PortalCompanyConfig.objects.get_or_create( name='Default', defaults={ 'legal_company_name': 'Workdock', 'country': 'Deutschland', 'website_url': '', 'imprint_url': '', 'privacy_url': '', 'hr_contact_email': '', 'it_contact_email': '', 'operations_contact_email': '', 'phone_number': '', 'vat_id': '', 'registration_number': '', }, ) return company_config def get_portal_trial_config() -> PortalTrialConfig: trial_config, _ = PortalTrialConfig.objects.get_or_create( name='Default', defaults={ 'is_trial_mode': False, 'restrict_production_integrations': True, 'auto_cleanup_enabled': True, 'trial_banner_text': '', 'trial_banner_text_en': '', }, ) return trial_config def is_trial_mode_enabled() -> bool: return bool(get_portal_trial_config().is_trial_mode) def is_trial_expired() -> bool: trial_config = get_portal_trial_config() if not trial_config.is_trial_mode or not trial_config.trial_expires_at: return False return timezone.now() >= trial_config.trial_expires_at def should_restrict_trial_integrations() -> bool: trial_config = get_portal_trial_config() return bool(trial_config.is_trial_mode and trial_config.restrict_production_integrations) def get_trial_context() -> dict[str, object]: trial_config = get_portal_trial_config() lang = (get_language() or 'de').split('-')[0] banner_text = ((trial_config.trial_banner_text_en or '').strip() if lang == 'en' else '') or (trial_config.trial_banner_text or '').strip() expired = is_trial_expired() days_remaining = None if trial_config.is_trial_mode and trial_config.trial_expires_at: delta = timezone.localtime(trial_config.trial_expires_at) - timezone.localtime(timezone.now()) days_remaining = max(0, delta.days + (1 if delta.seconds > 0 else 0)) return { 'portal_trial_config': trial_config, 'portal_trial_enabled': bool(trial_config.is_trial_mode), 'portal_trial_expired': expired, 'portal_trial_started_at': trial_config.trial_started_at, 'portal_trial_expires_at': trial_config.trial_expires_at, 'portal_trial_days_remaining': days_remaining, 'portal_trial_banner_text': banner_text, 'portal_trial_restrict_integrations': bool(trial_config.is_trial_mode and trial_config.restrict_production_integrations), 'portal_trial_cleanup_enabled': bool(trial_config.auto_cleanup_enabled), } def get_company_email_domain() -> str: branding = get_portal_branding() domain = (branding.company_domain or '').strip().lower().lstrip('@') return domain or 'workdock.de' def get_portal_logo_url() -> str: branding = get_portal_branding() if branding.logo_image: try: return branding.logo_image.url except ValueError: pass return static('workflows/img/tubco-logo.svg') def get_portal_favicon_url() -> str: branding = get_portal_branding() if branding.favicon_image: try: return branding.favicon_image.url except ValueError: pass return static('workflows/img/tubco-logo.svg') def get_portal_letterhead_path() -> Path: branding = get_portal_branding() if branding.pdf_letterhead: try: candidate = Path(branding.pdf_letterhead.path) if candidate.exists(): return candidate except (ValueError, NotImplementedError): pass return settings.PDF_TEMPLATES_DIR / 'templates.pdf' def get_branding_context() -> dict[str, object]: branding = get_portal_branding() company_config = get_portal_company_config() lang = (get_language() or branding.default_language or 'de').split('-')[0] footer_text = (branding.footer_text_en or '').strip() if lang == 'en' else '' legal_notice = (branding.legal_notice_en or '').strip() if lang == 'en' else '' if not footer_text: footer_text = (branding.footer_text or branding.portal_title).strip() if not legal_notice: legal_notice = (branding.legal_notice or '').strip() return { 'portal_branding': branding, 'portal_title': branding.portal_title, 'portal_company_name': branding.company_name, 'portal_email_domain': get_company_email_domain(), 'portal_support_email': branding.support_email, 'portal_sender_display_name': branding.sender_display_name or branding.company_name, 'portal_login_subtitle': branding.login_subtitle, 'portal_footer_text': footer_text, 'portal_legal_notice': legal_notice, 'portal_default_language': branding.default_language, 'portal_primary_color': branding.primary_color, 'portal_secondary_color': branding.secondary_color, 'portal_logo_url': get_portal_logo_url(), 'portal_favicon_url': get_portal_favicon_url(), 'portal_has_custom_logo': bool(branding.logo_image), 'portal_has_custom_letterhead': bool(branding.pdf_letterhead), 'portal_has_custom_favicon': bool(branding.favicon_image), 'portal_company_config': company_config, 'portal_company_legal_name': company_config.legal_company_name or branding.company_name, 'portal_company_street': company_config.street_address, 'portal_company_postal_code': company_config.postal_code, 'portal_company_city': company_config.city, 'portal_company_country': company_config.country, 'portal_company_website_url': company_config.website_url, 'portal_company_imprint_url': company_config.imprint_url, 'portal_company_privacy_url': company_config.privacy_url, 'portal_company_hr_contact_email': company_config.hr_contact_email, 'portal_company_it_contact_email': company_config.it_contact_email, 'portal_company_operations_contact_email': company_config.operations_contact_email, 'portal_company_phone_number': company_config.phone_number, 'portal_company_vat_id': company_config.vat_id, 'portal_company_registration_number': company_config.registration_number, } def get_branding_email_copy() -> dict[str, str]: branding = get_portal_branding() company_name = (branding.company_name or 'Workdock').strip() portal_title = (branding.portal_title or f'{company_name} Portal').strip() return { 'company_name': company_name, 'company_domain': get_company_email_domain(), 'portal_title': portal_title, 'support_email': (branding.support_email or '').strip(), 'sender_display_name': (branding.sender_display_name or company_name).strip(), } def get_company_contact_copy() -> dict[str, str]: branding = get_portal_branding() company_config = get_portal_company_config() company_name = (branding.company_name or 'Workdock').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: return None display_name = (get_branding_email_copy()['sender_display_name'] or '').strip() if not display_name: return address return formataddr((display_name, address)) def get_default_notification_templates() -> dict[str, dict[str, str]]: from copy import deepcopy from .tasks import DEFAULT_NOTIFICATION_TEMPLATES 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 = 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 }}' welcome['subject_en'] = f'Welcome to {company_name}, {{ VORNAME }}' welcome['body'] = ( 'Hallo {{ FULL_NAME }},\n\n' f'herzlich willkommen bei {company_name}.\n' 'Wir freuen uns sehr, dass du ab dem {{ CONTRACT_START }} unser Team in der Abteilung {{ DEPARTMENT }} verstärkst.\n\n' 'Deine dienstliche E-Mail-Adresse lautet: {{ EMAIL }}.\n' 'Im Anhang findest du deine Onboarding-Unterlagen als PDF.\n\n' f'Wenn du Fragen hast, melde dich gerne jederzeit unter {support_email}.\n\n' 'Viele Grüße\n' f'{company_name} IT' ) welcome['body_en'] = ( 'Hello {{ FULL_NAME }},\n\n' f'welcome to {company_name}.\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' f'If you have any questions, feel free to contact {support_email}.\n\n' 'Best regards,\n' f'{company_name} IT' ) return templates