from django.core.validators import FileExtensionValidator from django.db import models from django.utils.translation import get_language, gettext_lazy as _ class PortalBranding(models.Model): name = models.CharField(max_length=80, default='Default', unique=True) portal_title = models.CharField(max_length=255, default='Workdock') company_name = models.CharField(max_length=255, default='Workdock') company_domain = models.CharField(max_length=120, blank=True, default='workdock.de') support_email = models.EmailField(blank=True, default='info@workdock.de') sender_display_name = models.CharField(max_length=255, blank=True, default='Workdock') login_subtitle = models.CharField(max_length=255, blank=True, default='Bitte melden Sie sich mit Ihrem Benutzerkonto an.') footer_text = models.CharField(max_length=255, blank=True, default='Workdock') footer_text_en = models.CharField(max_length=255, blank=True, default='Workdock') legal_notice = models.TextField(blank=True, default='') legal_notice_en = models.TextField(blank=True, default='') default_language = models.CharField(max_length=10, choices=[('de', 'Deutsch'), ('en', 'English')], default='de') logo_image = models.FileField(upload_to='branding/', blank=True, null=True, validators=[FileExtensionValidator(allowed_extensions=['svg', 'png', 'jpg', 'jpeg', 'webp'])]) pdf_letterhead = models.FileField(upload_to='branding/', blank=True, null=True, validators=[FileExtensionValidator(allowed_extensions=['pdf'])]) favicon_image = models.FileField(upload_to='branding/', blank=True, null=True, validators=[FileExtensionValidator(allowed_extensions=['ico', 'png', 'svg', 'webp'])]) primary_color = models.CharField(max_length=20, blank=True, default='#000078') secondary_color = models.CharField(max_length=20, blank=True, default='#c0002b') updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = 'Portal Branding' verbose_name_plural = 'Portal Branding' def __str__(self) -> str: return self.portal_title or self.company_name or self.name class PortalCompanyConfig(models.Model): name = models.CharField(max_length=80, default='Default', unique=True) legal_company_name = models.CharField(max_length=255, blank=True, default='') street_address = models.CharField(max_length=255, blank=True, default='') postal_code = models.CharField(max_length=50, blank=True, default='') city = models.CharField(max_length=120, blank=True, default='') country = models.CharField(max_length=120, blank=True, default='Deutschland') website_url = models.URLField(blank=True, default='') imprint_url = models.URLField(blank=True, default='') privacy_url = models.URLField(blank=True, default='') hr_contact_email = models.EmailField(blank=True, default='') it_contact_email = models.EmailField(blank=True, default='') operations_contact_email = models.EmailField(blank=True, default='') phone_number = models.CharField(max_length=80, blank=True, default='') vat_id = models.CharField(max_length=80, blank=True, default='') registration_number = models.CharField(max_length=120, blank=True, default='') updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = 'Portal Company Config' verbose_name_plural = 'Portal Company Config' def __str__(self) -> str: return self.legal_company_name or self.name class PortalTrialConfig(models.Model): name = models.CharField(max_length=80, default='Default', unique=True) is_trial_mode = models.BooleanField(default=False) trial_started_at = models.DateTimeField(null=True, blank=True) trial_expires_at = models.DateTimeField(null=True, blank=True) restrict_production_integrations = models.BooleanField(default=True) auto_cleanup_enabled = models.BooleanField(default=True) trial_banner_text = models.CharField(max_length=255, blank=True, default='') trial_banner_text_en = models.CharField(max_length=255, blank=True, default='') last_cleanup_at = models.DateTimeField(null=True, blank=True) updated_at = models.DateTimeField(auto_now=True) class Meta: verbose_name = 'Portal Trial Config' verbose_name_plural = 'Portal Trial Config' def __str__(self) -> str: return self.name class PortalAppConfig(models.Model): SECTION_APP = 'app' SECTION_PLATFORM = 'platform' SECTION_ADMIN = 'admin' SECTION_CHOICES = [ (SECTION_APP, _('Apps')), (SECTION_PLATFORM, _('Platform Apps')), (SECTION_ADMIN, _('Admin Apps')), ] key = models.CharField(max_length=80, unique=True) section = models.CharField(max_length=20, choices=SECTION_CHOICES, default=SECTION_APP) sort_order = models.PositiveIntegerField(default=0) is_enabled = models.BooleanField(default=True) visible_to_super_admin = models.BooleanField(default=True) visible_to_admin = models.BooleanField(default=True) visible_to_it_staff = models.BooleanField(default=False) visible_to_staff = models.BooleanField(default=False) title_override = models.CharField(max_length=255, blank=True) title_override_en = models.CharField(max_length=255, blank=True) description_override = models.TextField(blank=True) description_override_en = models.TextField(blank=True) action_label_override = models.CharField(max_length=255, blank=True) action_label_override_en = models.CharField(max_length=255, blank=True) updated_at = models.DateTimeField(auto_now=True) class Meta: ordering = ['section', 'sort_order', 'key'] verbose_name = 'Portal App' verbose_name_plural = 'Portal Apps' def __str__(self) -> str: return self.key def _translated_value(self, field_name: str, language_code: str | None = None) -> str: lang = (language_code or get_language() or 'de').split('-')[0] if lang == 'en': english_value = (getattr(self, f'{field_name}_en', '') or '').strip() if english_value: return english_value return (getattr(self, field_name, '') or '').strip() def translated_title_override(self, language_code: str | None = None) -> str: return self._translated_value('title_override', language_code) def translated_description_override(self, language_code: str | None = None) -> str: return self._translated_value('description_override', language_code) def translated_action_label_override(self, language_code: str | None = None) -> str: return self._translated_value('action_label_override', language_code)