287 lines
12 KiB
Python
287 lines
12 KiB
Python
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
|