from collections import OrderedDict from .models import FormFieldConfig DEFAULT_FIELD_ORDER = { 'onboarding': [ 'first_name', 'last_name', 'full_name', 'gender', 'job_title', 'department', 'work_email', 'order_business_cards', 'business_card_name', 'business_card_title', 'business_card_email', 'business_card_phone', 'contract_start', 'employment_type', 'employment_end_date', 'handover_date', 'group_mailboxes_required_choice', 'group_mailboxes', 'needed_devices_multi', 'additional_hardware_needed_choice', 'additional_hardware_multi', 'additional_hardware_other', 'needed_software_multi', 'additional_software_needed_choice', 'additional_software_multi', 'additional_software', 'needed_accesses_multi', 'additional_access_needed_choice', 'additional_access_text', 'needed_workspace_groups_multi', 'needed_resources_multi', 'successor_required_choice', 'successor_name', 'inherit_phone_number_choice', 'phone_number_choice', 'additional_notes', 'signature_url', 'signature_image', 'onboarded_by_email', 'agreement_confirm', ], 'offboarding': [ 'full_name', 'work_email', 'department', 'job_title', 'last_working_day', 'notes', ], } ONBOARDING_PAGE_ORDER = ['stammdaten', 'vertrag', 'itsetup', 'abschluss'] ONBOARDING_PAGE_LABELS = { 'stammdaten': '1. Stammdaten', 'vertrag': '2. Vertrag', 'itsetup': '3. IT-Setup', 'abschluss': '4. Abschluss', } LOCKED_FIELD_RULES = { 'onboarding': {'full_name', 'work_email', 'contract_start', 'agreement_confirm'}, 'offboarding': {'full_name', 'work_email', 'last_working_day'}, } ONBOARDING_DEFAULT_PAGE = { 'first_name': 'stammdaten', 'last_name': 'stammdaten', 'full_name': 'stammdaten', 'gender': 'stammdaten', 'job_title': 'stammdaten', 'department': 'stammdaten', 'work_email': 'stammdaten', 'order_business_cards': 'stammdaten', 'business_card_name': 'stammdaten', 'business_card_title': 'stammdaten', 'business_card_email': 'stammdaten', 'business_card_phone': 'stammdaten', 'contract_start': 'vertrag', 'employment_type': 'vertrag', 'employment_end_date': 'vertrag', 'handover_date': 'vertrag', 'group_mailboxes_required_choice': 'vertrag', 'group_mailboxes': 'vertrag', 'needed_devices_multi': 'itsetup', 'additional_hardware_needed_choice': 'itsetup', 'additional_hardware_multi': 'itsetup', 'additional_hardware_other': 'itsetup', 'needed_software_multi': 'itsetup', 'additional_software_needed_choice': 'itsetup', 'additional_software_multi': 'itsetup', 'additional_software': 'itsetup', 'needed_accesses_multi': 'itsetup', 'additional_access_needed_choice': 'itsetup', 'additional_access_text': 'itsetup', 'needed_workspace_groups_multi': 'itsetup', 'needed_resources_multi': 'itsetup', 'successor_required_choice': 'itsetup', 'successor_name': 'itsetup', 'inherit_phone_number_choice': 'itsetup', 'phone_number_choice': 'itsetup', 'additional_notes': 'abschluss', 'signature_url': 'abschluss', 'signature_image': 'abschluss', 'onboarded_by_email': 'abschluss', 'agreement_confirm': 'abschluss', } def _default_sort(form_type: str, field_name: str) -> int: ordered = DEFAULT_FIELD_ORDER.get(form_type, []) if field_name in ordered: return ordered.index(field_name) return len(ordered) + 500 def _ensure_configs(form_type: str, field_names: list[str]) -> dict[str, FormFieldConfig]: existing = { cfg.field_name: cfg for cfg in FormFieldConfig.objects.filter(form_type=form_type, field_name__in=field_names) } missing_names = [name for name in field_names if name not in existing] if missing_names: FormFieldConfig.objects.bulk_create( [ FormFieldConfig( form_type=form_type, field_name=name, sort_order=_default_sort(form_type, name), page_key=ONBOARDING_DEFAULT_PAGE.get(name, '') if form_type == 'onboarding' else '', ) for name in missing_names ], ignore_conflicts=True, ) existing = { cfg.field_name: cfg for cfg in FormFieldConfig.objects.filter(form_type=form_type, field_name__in=field_names) } return existing def ensure_form_field_configs(form_type: str, field_names: list[str]) -> dict[str, FormFieldConfig]: return _ensure_configs(form_type, field_names) def apply_form_field_config(form_type: str, form) -> None: field_names = list(form.fields.keys()) configs = _ensure_configs(form_type, field_names) locked = LOCKED_FIELD_RULES.get(form_type, set()) for field_name, field in list(form.fields.items()): cfg = configs.get(field_name) if not cfg: continue if cfg.label_override.strip(): field.label = cfg.label_override.strip() if cfg.help_text_override.strip(): field.help_text = cfg.help_text_override.strip() if field_name not in locked and cfg.is_required is not None: field.required = cfg.is_required if field_name not in locked and not cfg.is_visible: form.fields.pop(field_name, None) ordered_items = sorted( form.fields.items(), key=lambda item: ( configs[item[0]].sort_order if item[0] in configs else _default_sort(form_type, item[0]), item[0], ), ) form.fields = OrderedDict(ordered_items) if form_type == 'onboarding': form._field_page_keys = { name: (configs[name].page_key or ONBOARDING_DEFAULT_PAGE.get(name, 'abschluss')) for name in form.fields.keys() if name in configs }