chore: initial snapshot of tubco people portal
This commit is contained in:
188
backend/workflows/form_builder.py
Normal file
188
backend/workflows/form_builder.py
Normal file
@@ -0,0 +1,188 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user