chore: initial snapshot of tubco people portal
This commit is contained in:
53
backend/workflows/migrations/0001_initial.py
Normal file
53
backend/workflows/migrations/0001_initial.py
Normal file
@@ -0,0 +1,53 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EmployeeProfile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('full_name', models.CharField(max_length=255)),
|
||||
('first_name', models.CharField(max_length=100)),
|
||||
('last_name', models.CharField(max_length=155)),
|
||||
('department', models.CharField(blank=True, max_length=255)),
|
||||
('job_title', models.CharField(blank=True, max_length=255)),
|
||||
('work_email', models.EmailField(max_length=254, unique=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OnboardingRequest',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('full_name', models.CharField(max_length=255, verbose_name='Vorname und Nachname')),
|
||||
('job_title', models.CharField(blank=True, max_length=255, verbose_name='Berufsbezeichnung')),
|
||||
('department', models.CharField(blank=True, max_length=255, verbose_name='Abteilung')),
|
||||
('work_email', models.EmailField(max_length=254, verbose_name='Gewünschte dienstliche E-Mail-Adresse')),
|
||||
('contract_start', models.DateField(verbose_name='Vertragsbeginn')),
|
||||
('handover_date', models.DateField(blank=True, null=True, verbose_name='Gewünschtes Übergabedatum der Geräte')),
|
||||
('group_mailboxes_required', models.BooleanField(default=False, verbose_name='Gruppenpostfächer erforderlich?')),
|
||||
('group_mailboxes', models.TextField(blank=True, verbose_name='Gruppenpostfächer')),
|
||||
('needed_devices', models.TextField(blank=True, verbose_name='Benötigte Geräte und Gegenstände')),
|
||||
('needed_software', models.TextField(blank=True, verbose_name='Benötigte Software')),
|
||||
('needed_accesses', models.TextField(blank=True, verbose_name='Benötigte Zugänge')),
|
||||
('needed_workspace_groups', models.TextField(blank=True, verbose_name='Benötigte Gruppen im Workspace')),
|
||||
('additional_software_needed', models.BooleanField(default=False, verbose_name='Wird zusätzliche Software benötigt?')),
|
||||
('additional_software', models.TextField(blank=True, verbose_name='Zusätzlich gewünschte Software (ohne Garantie)')),
|
||||
('needed_resources', models.TextField(blank=True, verbose_name='Benötigte Ressourcen')),
|
||||
('phone_number', models.CharField(blank=True, max_length=100, verbose_name='TUBS-Telefon-Direktwahl-Nr. 030 447202 (10-89)')),
|
||||
('additional_notes', models.TextField(blank=True, verbose_name='Raum für zusätzliche Anmerkungen und Wünsche')),
|
||||
('agreement', models.TextField(blank=True, verbose_name='Vereinbarung')),
|
||||
('signature_url', models.URLField(blank=True, verbose_name='Unterschrift')),
|
||||
('personalized_text', models.TextField(blank=True, help_text='Optionaler individueller Textblock im Onboarding PDF.', verbose_name='Personalisierter Text für PDF')),
|
||||
('generated_pdf_path', models.CharField(blank=True, max_length=500)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
91
backend/workflows/migrations/0002_form_updates.py
Normal file
91
backend/workflows/migrations/0002_form_updates.py
Normal file
@@ -0,0 +1,91 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='additional_access_needed',
|
||||
field=models.BooleanField(default=False, verbose_name='Werden weitere Zugänge benötigt?'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='additional_access_text',
|
||||
field=models.TextField(blank=True, verbose_name='Weitere Zugänge (Freitext)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='additional_hardware',
|
||||
field=models.TextField(blank=True, verbose_name='Zusätzliche Hardware'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='additional_hardware_needed',
|
||||
field=models.BooleanField(default=False, verbose_name='Wird zusätzliche Hardware benötigt?'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='additional_hardware_other',
|
||||
field=models.TextField(blank=True, verbose_name='Weitere Hardware (Freitext)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='business_card_email',
|
||||
field=models.EmailField(blank=True, max_length=254, verbose_name='E-Mailadresse (Visitenkarte)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='business_card_name',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Name (Visitenkarte)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='business_card_phone',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='Telefonnummer (Visitenkarte)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='business_card_title',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Titel (Visitenkarte)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='employment_end_date',
|
||||
field=models.DateField(blank=True, null=True, verbose_name='Enddatum (nur bei befristet)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='employment_type',
|
||||
field=models.CharField(blank=True, choices=[('befristet', 'befristet'), ('unbefristet', 'unbefristet')], max_length=20, verbose_name='Beschäftigungsverhältnis'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='inherit_phone_number',
|
||||
field=models.BooleanField(default=False, verbose_name='Telefonnummer von Vorgängerperson übernehmen'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='order_business_cards',
|
||||
field=models.BooleanField(default=False, verbose_name='Bestellung Visitenkarten'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='successor_name',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Name der Vorgängerperson'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='successor_required',
|
||||
field=models.BooleanField(default=False, verbose_name='Neue Mitarbeitende ist Nachfolge von?'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='onboardingrequest',
|
||||
name='phone_number',
|
||||
field=models.CharField(blank=True, max_length=100, verbose_name='TUB/CO-Telefon-Direktwahl-Nr. 030 447202 (10-89)'),
|
||||
),
|
||||
]
|
||||
21
backend/workflows/migrations/0003_gender_onboarded_by.py
Normal file
21
backend/workflows/migrations/0003_gender_onboarded_by.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0002_form_updates'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='gender',
|
||||
field=models.CharField(blank=True, choices=[('frau', 'Frau'), ('herr', 'Herr'), ('divers', 'Divers')], max_length=20, verbose_name='Geschlecht'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='onboarded_by_email',
|
||||
field=models.EmailField(blank=True, max_length=254, verbose_name='E-Mail der anfordernden Person'),
|
||||
),
|
||||
]
|
||||
43
backend/workflows/migrations/0004_backend_config_models.py
Normal file
43
backend/workflows/migrations/0004_backend_config_models.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0003_gender_onboarded_by'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='WorkflowConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='Default', max_length=120, unique=True)),
|
||||
('it_onboarding_email', models.EmailField(blank=True, max_length=254)),
|
||||
('general_info_email', models.EmailField(blank=True, max_length=254)),
|
||||
('business_card_email', models.EmailField(blank=True, max_length=254)),
|
||||
('hr_works_email', models.EmailField(blank=True, max_length=254)),
|
||||
('legal_text', models.TextField(blank=True, default='Eine Ausrüstungsvereinbarung erlaubt es einem Mitarbeitenden, die Ausrüstung des Unternehmens im Außendienst oder zu Hause zu nutzen und mitzunehmen.')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FormOption',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('category', models.CharField(choices=[('department', 'Abteilung'), ('device', 'Geräte'), ('software', 'Software'), ('access', 'Zugänge'), ('workspace_group', 'Workspace-Gruppen'), ('resource', 'Ressourcen'), ('phone', 'Telefonnummern')], max_length=40)),
|
||||
('label', models.CharField(max_length=255)),
|
||||
('value', models.CharField(blank=True, max_length=255)),
|
||||
('sort_order', models.PositiveIntegerField(default=0)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['category', 'sort_order', 'label'],
|
||||
'unique_together': {('category', 'label')},
|
||||
},
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='onboardingrequest',
|
||||
name='gender',
|
||||
field=models.CharField(blank=True, choices=[('herr', 'Herr'), ('frau', 'Frau'), ('divers', 'Divers')], max_length=20, verbose_name='Anrede'),
|
||||
),
|
||||
]
|
||||
68
backend/workflows/migrations/0005_seed_backend_config.py
Normal file
68
backend/workflows/migrations/0005_seed_backend_config.py
Normal file
@@ -0,0 +1,68 @@
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def seed_defaults(apps, schema_editor):
|
||||
FormOption = apps.get_model('workflows', 'FormOption')
|
||||
WorkflowConfig = apps.get_model('workflows', 'WorkflowConfig')
|
||||
|
||||
option_map = {
|
||||
'department': [
|
||||
'Buchhaltung/Personalverwaltung', 'IT-Service', 'Azubi', 'Marketing/Kommunikation', 'Messe',
|
||||
'Kongresse', 'TNB/Studiengänge', 'TUB-Academy', 'Projekte TUB', 'TU Berlin Summer + Winter School',
|
||||
],
|
||||
'device': [
|
||||
'Laptop', 'Docking-Station', 'Tastatur und Maus', 'Kopfhörer', 'Tragetasche', 'Monitor', 'Schlüssel', 'Tischtelefon',
|
||||
],
|
||||
'software': [
|
||||
'eM Client', 'KeepassXC', 'Nextcloud', '7-Zip', 'PDF Reader', 'PDF-Editor (Flexi PDF)',
|
||||
'Firefox', 'Chrome', 'Backup Client', 'MS Office', 'Zoom', 'Cisco VPN Client',
|
||||
],
|
||||
'access': ['TU Konto', 'HR Works', 'Datev', 'Odoo'],
|
||||
'workspace_group': [
|
||||
'Group-Academy', 'Group-BuSu', 'Group-EIT-Urban-Mobility', 'Group-EL', 'Group-EM', 'Group-IT-Services',
|
||||
'Group-Kongresse-Events', 'Group-MaCo', 'Group-Messe', 'Group-Messe-Kongresse', 'Group-MSE', 'Group-SuMo',
|
||||
'Group-TNB', 'Group-TUBS', 'Group-Wima', 'Group-Leitungsrunde', 'Campus-Euref', 'Group-Lohnbuchhaltung',
|
||||
'Group-SU-WU', 'NWM',
|
||||
],
|
||||
'resource': ['Drucker HBS 5./6. OG', 'Drucker Euref'],
|
||||
'phone': [
|
||||
'030 4472021 (0-9)', '030 4472022 (0-9)', '030 4472023 (0-9)', '030 4472024 (0-9)',
|
||||
'030 4472025 (0-9)', '030 4472026 (0-9)', '030 4472027 (0-9)', '030 4472028 (0-9)',
|
||||
],
|
||||
}
|
||||
|
||||
for category, labels in option_map.items():
|
||||
for idx, label in enumerate(labels, start=1):
|
||||
FormOption.objects.get_or_create(
|
||||
category=category,
|
||||
label=label,
|
||||
defaults={'value': label, 'sort_order': idx, 'is_active': True},
|
||||
)
|
||||
|
||||
WorkflowConfig.objects.get_or_create(
|
||||
name='Default',
|
||||
defaults={
|
||||
'it_onboarding_email': 'it@tub.co',
|
||||
'general_info_email': 'ingo.einacker@tub.co',
|
||||
'business_card_email': 'kommunikation@tub.co',
|
||||
'hr_works_email': 'dittrich@tub.co',
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def rollback_seed(apps, schema_editor):
|
||||
FormOption = apps.get_model('workflows', 'FormOption')
|
||||
WorkflowConfig = apps.get_model('workflows', 'WorkflowConfig')
|
||||
FormOption.objects.all().delete()
|
||||
WorkflowConfig.objects.filter(name='Default').delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0004_backend_config_models'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_defaults, rollback_seed),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0005_seed_backend_config'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='key_notification_email',
|
||||
field=models.EmailField(blank=True, max_length=254),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='OffboardingRequest',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('full_name', models.CharField(max_length=255, verbose_name='Vorname und Nachname')),
|
||||
('work_email', models.EmailField(max_length=254, verbose_name='Dienstliche E-Mail-Adresse')),
|
||||
('department', models.CharField(blank=True, max_length=255, verbose_name='Abteilung')),
|
||||
('job_title', models.CharField(blank=True, max_length=255, verbose_name='Berufsbezeichnung')),
|
||||
('last_working_day', models.DateField(verbose_name='Letzter Arbeitstag')),
|
||||
('offboarding_reason', models.TextField(blank=True, verbose_name='Grund')),
|
||||
('notes', models.TextField(blank=True, verbose_name='Notizen')),
|
||||
('requested_by_email', models.EmailField(max_length=254, verbose_name='E-Mail der anfordernden Person')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('employee_profile', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='workflows.employeeprofile')),
|
||||
],
|
||||
),
|
||||
]
|
||||
20
backend/workflows/migrations/0007_seed_key_email.py
Normal file
20
backend/workflows/migrations/0007_seed_key_email.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def seed_key_email(apps, schema_editor):
|
||||
WorkflowConfig = apps.get_model('workflows', 'WorkflowConfig')
|
||||
for cfg in WorkflowConfig.objects.all():
|
||||
if not cfg.key_notification_email:
|
||||
cfg.key_notification_email = 'minuth@tub.co'
|
||||
cfg.save(update_fields=['key_notification_email'])
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0006_offboarding_and_key_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_key_email, migrations.RunPython.noop),
|
||||
]
|
||||
16
backend/workflows/migrations/0008_offboarding_pdf_path.py
Normal file
16
backend/workflows/migrations/0008_offboarding_pdf_path.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0007_seed_key_email'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='offboardingrequest',
|
||||
name='generated_pdf_path',
|
||||
field=models.CharField(blank=True, max_length=500),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 12:03
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0008_offboarding_pdf_path'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='offboardingrequest',
|
||||
name='signature',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Unterschrift (Name)'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 13:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0009_offboardingrequest_signature'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='signature_image',
|
||||
field=models.ImageField(blank=True, null=True, upload_to='signatures/', verbose_name='Unterschrift (Bilddatei)'),
|
||||
),
|
||||
]
|
||||
27
backend/workflows/migrations/0011_notificationtemplate.py
Normal file
27
backend/workflows/migrations/0011_notificationtemplate.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 14:37
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0010_onboardingrequest_signature_image'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NotificationTemplate',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('key', models.CharField(choices=[('onboarding_it', 'Onboarding: IT'), ('onboarding_general_info', 'Onboarding: Allgemeine Info'), ('onboarding_business_card', 'Onboarding: Visitenkarte'), ('onboarding_hr_works', 'Onboarding: HR Works'), ('onboarding_key', 'Onboarding: Schlüssel'), ('onboarding_reference', 'Onboarding: Referenz Anfordernde Person'), ('offboarding_it', 'Offboarding: IT'), ('offboarding_general_info', 'Offboarding: Allgemeine Info'), ('offboarding_hr_works_disable', 'Offboarding: HR Works Deaktivierung'), ('offboarding_reference', 'Offboarding: Referenz Anfordernde Person')], max_length=60, unique=True)),
|
||||
('subject_template', models.CharField(max_length=255)),
|
||||
('body_template', models.TextField()),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['key'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,72 @@
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def seed_notification_templates(apps, schema_editor):
|
||||
NotificationTemplate = apps.get_model('workflows', 'NotificationTemplate')
|
||||
templates = {
|
||||
'onboarding_it': {
|
||||
'subject_template': '[Onboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Neue Onboarding-Anfrage für {{ FULL_NAME }}.\nAbteilung: {{ DEPARTMENT }}\nVertragsbeginn: {{ CONTRACT_START }}\nAngefordert von: {{ REQUESTED_BY }}\nBitte IT-Setup vorbereiten.',
|
||||
},
|
||||
'onboarding_general_info': {
|
||||
'subject_template': '[Info Onboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Hallo,\n\n{{ FULL_NAME }} wird onboarded.\nAbteilung: {{ DEPARTMENT }}\nVertragsbeginn: {{ CONTRACT_START }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'onboarding_business_card': {
|
||||
'subject_template': '[Visitenkarte] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Hallo,\n\nbitte Visitenkarten erstellen:\nName: {{ BUSINESS_CARD_NAME }}\nTitel: {{ BUSINESS_CARD_TITLE }}\nE-Mail: {{ BUSINESS_CARD_EMAIL }}\nTelefon: {{ BUSINESS_CARD_PHONE }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'onboarding_hr_works': {
|
||||
'subject_template': '[HR Works] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Hello Stefanie,\n\nEs ist wieder soweit. Zuwachs!\n\nKönntest du deshalb bitte ein HR Works Konto mit den folgenden Daten erstellen:\n\nName: {{ VORNAME }} {{ NACHNAME }}\nAbteilung: {{ DEPARTMENT }}\nVertragsbeginn: {{ CONTRACT_START }}\nE-Mail-Adresse: {{ EMAIL }}\n\n{% if PDF_LINK %}In 2 Minuten findest du alle Infos über den Mitarbeiter als PDF unter diesem Link: {{ PDF_LINK }}\n\n{% endif %}Falls du noch irgendwelche anderen Informationen benötigen solltest, kannst du dich bei der it@tub.co melden!\n\nVielen Dank und schöne Grüße,\nDie IT.',
|
||||
},
|
||||
'onboarding_key': {
|
||||
'subject_template': '[Schlüssel] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Hallo,\n\nbitte Schlüssel vorbereiten für:\nName: {{ FULL_NAME }}\nAbteilung: {{ DEPARTMENT }}\nVertragsbeginn: {{ CONTRACT_START }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'onboarding_reference': {
|
||||
'subject_template': '[Referenz Onboarding] {{ FULL_NAME }} | Ihre Anfrage',
|
||||
'body_template': 'Diese E-Mail dient als Referenz für Ihre Onboarding-Anfrage.\nName: {{ FULL_NAME }}\nAbteilung: {{ DEPARTMENT }}\nVertragsbeginn: {{ CONTRACT_START }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'offboarding_it': {
|
||||
'subject_template': '[Offboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Neue Offboarding-Anfrage für {{ FULL_NAME }}.\nAbteilung: {{ DEPARTMENT }}\nLetzter Arbeitstag: {{ LAST_WORKING_DAY }}\nAngefordert von: {{ REQUESTED_BY }}\nBitte IT-Offboarding durchführen.',
|
||||
},
|
||||
'offboarding_general_info': {
|
||||
'subject_template': '[Info Offboarding] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Neue Offboarding-Anfrage für {{ FULL_NAME }}.\nAbteilung: {{ DEPARTMENT }}\nLetzter Arbeitstag: {{ LAST_WORKING_DAY }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'offboarding_hr_works_disable': {
|
||||
'subject_template': '[HR Works Deaktivierung] {{ FULL_NAME }} | Anfrage von {{ REQUESTED_BY }}',
|
||||
'body_template': 'Bitte HR Works Zugriff deaktivieren für {{ FULL_NAME }} ({{ EMAIL }}) zum {{ LAST_WORKING_DAY }}.\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
'offboarding_reference': {
|
||||
'subject_template': '[Referenz Offboarding] {{ FULL_NAME }} | Ihre Anfrage',
|
||||
'body_template': 'Diese E-Mail dient als Referenz für Ihre Offboarding-Anfrage.\nName: {{ FULL_NAME }}\nAbteilung: {{ DEPARTMENT }}\nLetzter Arbeitstag: {{ LAST_WORKING_DAY }}\nAngefordert von: {{ REQUESTED_BY }}\n',
|
||||
},
|
||||
}
|
||||
|
||||
for key, payload in templates.items():
|
||||
NotificationTemplate.objects.get_or_create(
|
||||
key=key,
|
||||
defaults={
|
||||
'subject_template': payload['subject_template'],
|
||||
'body_template': payload['body_template'],
|
||||
'is_active': True,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def noop_reverse(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0011_notificationtemplate'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_notification_templates, noop_reverse),
|
||||
]
|
||||
33
backend/workflows/migrations/0013_systememailconfig.py
Normal file
33
backend/workflows/migrations/0013_systememailconfig.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 14:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0012_seed_notification_templates'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='SystemEmailConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(default='Default SMTP', max_length=120, unique=True)),
|
||||
('is_active', models.BooleanField(default=False)),
|
||||
('host', models.CharField(blank=True, max_length=255)),
|
||||
('port', models.PositiveIntegerField(default=587)),
|
||||
('username', models.CharField(blank=True, max_length=255)),
|
||||
('password', models.CharField(blank=True, max_length=255)),
|
||||
('use_tls', models.BooleanField(default=True)),
|
||||
('use_ssl', models.BooleanField(default=False)),
|
||||
('from_email', models.EmailField(blank=True, max_length=254)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'System SMTP Konfiguration',
|
||||
'verbose_name_plural': 'System SMTP Konfigurationen',
|
||||
},
|
||||
),
|
||||
]
|
||||
32
backend/workflows/migrations/0014_formfieldconfig.py
Normal file
32
backend/workflows/migrations/0014_formfieldconfig.py
Normal file
@@ -0,0 +1,32 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 15:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0013_systememailconfig'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='FormFieldConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('form_type', models.CharField(choices=[('onboarding', 'Onboarding'), ('offboarding', 'Offboarding')], max_length=20)),
|
||||
('field_name', models.CharField(max_length=80)),
|
||||
('sort_order', models.PositiveIntegerField(default=0)),
|
||||
('is_visible', models.BooleanField(default=True)),
|
||||
('is_required', models.BooleanField(blank=True, default=None, null=True)),
|
||||
('label_override', models.CharField(blank=True, max_length=255)),
|
||||
('help_text_override', models.TextField(blank=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Formularfeld-Konfiguration',
|
||||
'verbose_name_plural': 'Formularfeld-Konfigurationen',
|
||||
'ordering': ['form_type', 'sort_order', 'field_name'],
|
||||
'unique_together': {('form_type', 'field_name')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,86 @@
|
||||
# Generated by Codex on 2026-03-09
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
ONBOARDING_FIELDS = [
|
||||
'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_FIELDS = [
|
||||
'full_name',
|
||||
'work_email',
|
||||
'department',
|
||||
'job_title',
|
||||
'last_working_day',
|
||||
'notes',
|
||||
'requested_by_email',
|
||||
]
|
||||
|
||||
|
||||
def seed_defaults(apps, schema_editor):
|
||||
FormFieldConfig = apps.get_model('workflows', 'FormFieldConfig')
|
||||
for idx, name in enumerate(ONBOARDING_FIELDS):
|
||||
FormFieldConfig.objects.get_or_create(
|
||||
form_type='onboarding',
|
||||
field_name=name,
|
||||
defaults={'sort_order': idx, 'is_visible': True},
|
||||
)
|
||||
for idx, name in enumerate(OFFBOARDING_FIELDS):
|
||||
FormFieldConfig.objects.get_or_create(
|
||||
form_type='offboarding',
|
||||
field_name=name,
|
||||
defaults={'sort_order': idx, 'is_visible': True},
|
||||
)
|
||||
|
||||
|
||||
def noop_reverse(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('workflows', '0014_formfieldconfig'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_defaults, noop_reverse),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-09 19:55
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0015_seed_formfieldconfig_defaults'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='formfieldconfig',
|
||||
name='page_key',
|
||||
field=models.CharField(blank=True, choices=[('', 'Automatisch'), ('stammdaten', 'Stammdaten'), ('vertrag', 'Vertrag'), ('itsetup', 'IT-Setup'), ('abschluss', 'Abschluss')], default='', max_length=20),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,69 @@
|
||||
# Generated by Codex on 2026-03-09
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
ONBOARDING_DEFAULT_PAGE = {
|
||||
'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 seed_page_keys(apps, schema_editor):
|
||||
FormFieldConfig = apps.get_model('workflows', 'FormFieldConfig')
|
||||
for cfg in FormFieldConfig.objects.filter(form_type='onboarding'):
|
||||
if cfg.page_key:
|
||||
continue
|
||||
cfg.page_key = ONBOARDING_DEFAULT_PAGE.get(cfg.field_name, 'abschluss')
|
||||
cfg.save(update_fields=['page_key'])
|
||||
|
||||
|
||||
def noop_reverse(apps, schema_editor):
|
||||
pass
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('workflows', '0016_formfieldconfig_page_key'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RunPython(seed_page_keys, noop_reverse),
|
||||
]
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 09:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0017_seed_formfieldconfig_page_keys'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='nextcloud_enabled_override',
|
||||
field=models.BooleanField(blank=True, default=None, help_text='Leer = ENV-Wert nutzen, Ja = erzwingen aktiv, Nein = erzwingen inaktiv', null=True, verbose_name='Nextcloud Upload aktiviert (Override)'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 10:11
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0018_workflowconfig_nextcloud_enabled_override'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='offboardingrequest',
|
||||
name='requested_by_name',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Name der anfordernden Person'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='onboardingrequest',
|
||||
name='onboarded_by_name',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Name der anfordernden Person'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 12:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0019_offboardingrequest_requested_by_name_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='email_test_mode_override',
|
||||
field=models.BooleanField(blank=True, default=None, help_text='Leer = ENV-Wert nutzen, Ja = Testmodus erzwingen, Nein = Produktionsmodus erzwingen', null=True, verbose_name='E-Mail Testmodus aktiv (Override)'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,78 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 12:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0020_workflowconfig_email_test_mode_override'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='email_account',
|
||||
field=models.EmailField(blank=True, max_length=254, verbose_name='E-Mail Konto'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='email_password',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='E-Mail Passwort'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='imap_server',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='IMAP Server'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='mailbox',
|
||||
field=models.CharField(blank=True, default='INBOX', max_length=120, verbose_name='Mailbox'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='nextcloud_base_url_override',
|
||||
field=models.CharField(blank=True, max_length=500, verbose_name='Nextcloud Base URL (Override)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='nextcloud_directory_override',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Nextcloud Verzeichnis (Override)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='nextcloud_password_override',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Nextcloud Passwort (Override)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='nextcloud_username_override',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='Nextcloud Benutzername (Override)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='smtp_port',
|
||||
field=models.PositiveIntegerField(default=465, verbose_name='SMTP Port'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='smtp_server',
|
||||
field=models.CharField(blank=True, max_length=255, verbose_name='SMTP Server'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='smtp_use_ssl',
|
||||
field=models.BooleanField(default=True, verbose_name='SMTP SSL nutzen'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='smtp_use_tls',
|
||||
field=models.BooleanField(default=False, verbose_name='SMTP TLS nutzen'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='sync_interval_seconds',
|
||||
field=models.PositiveIntegerField(default=60, verbose_name='Sync-Intervall (Sekunden)'),
|
||||
),
|
||||
]
|
||||
34
backend/workflows/migrations/0022_notificationrule.py
Normal file
34
backend/workflows/migrations/0022_notificationrule.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 12:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0021_workflowconfig_email_account_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NotificationRule',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=120)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
('event_type', models.CharField(choices=[('onboarding', 'Onboarding'), ('offboarding', 'Offboarding')], max_length=20)),
|
||||
('field_name', models.CharField(blank=True, max_length=80)),
|
||||
('operator', models.CharField(choices=[('always', 'Immer'), ('contains', 'Enthält'), ('equals', 'Ist gleich'), ('is_true', 'Ist aktiv/Ja'), ('is_false', 'Ist inaktiv/Nein')], default='always', max_length=20)),
|
||||
('expected_value', models.CharField(blank=True, max_length=255)),
|
||||
('recipients', models.TextField(help_text='Mehrere E-Mail-Adressen mit Komma, Semikolon oder Zeilenumbruch trennen.')),
|
||||
('template_key', models.CharField(blank=True, max_length=60)),
|
||||
('custom_subject', models.CharField(blank=True, max_length=255)),
|
||||
('custom_body', models.TextField(blank=True)),
|
||||
('include_pdf_attachment', models.BooleanField(default=False)),
|
||||
('sort_order', models.PositiveIntegerField(default=0)),
|
||||
],
|
||||
options={
|
||||
'ordering': ['event_type', 'sort_order', 'id'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,37 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 12:56
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0022_notificationrule'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='notificationtemplate',
|
||||
name='key',
|
||||
field=models.CharField(choices=[('onboarding_it', 'Onboarding: IT'), ('onboarding_general_info', 'Onboarding: Allgemeine Info'), ('onboarding_business_card', 'Onboarding: Visitenkarte'), ('onboarding_hr_works', 'Onboarding: HR Works'), ('onboarding_key', 'Onboarding: Schlüssel'), ('onboarding_reference', 'Onboarding: Referenz Anfordernde Person'), ('onboarding_welcome', 'Onboarding: Welcome E-Mail'), ('offboarding_it', 'Offboarding: IT'), ('offboarding_general_info', 'Offboarding: Allgemeine Info'), ('offboarding_hr_works_disable', 'Offboarding: HR Works Deaktivierung'), ('offboarding_reference', 'Offboarding: Referenz Anfordernde Person')], max_length=60, unique=True),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ScheduledWelcomeEmail',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('recipient_email', models.EmailField(max_length=254)),
|
||||
('send_at', models.DateTimeField()),
|
||||
('status', models.CharField(choices=[('scheduled', 'Geplant'), ('sent', 'Gesendet'), ('failed', 'Fehlgeschlagen')], default='scheduled', max_length=20)),
|
||||
('celery_task_id', models.CharField(blank=True, max_length=100)),
|
||||
('sent_at', models.DateTimeField(blank=True, null=True)),
|
||||
('last_error', models.TextField(blank=True)),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('updated_at', models.DateTimeField(auto_now=True)),
|
||||
('onboarding_request', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='workflows.onboardingrequest')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['-send_at', '-id'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,33 @@
|
||||
# Generated by Django 5.1.5 on 2026-03-10 13:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('workflows', '0023_alter_notificationtemplate_key_scheduledwelcomeemail'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='welcome_email_delay_days',
|
||||
field=models.PositiveIntegerField(default=5, verbose_name='Welcome E-Mail Verzögerung (Tage)'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='welcome_include_pdf',
|
||||
field=models.BooleanField(default=True, verbose_name='Welcome E-Mail mit PDF-Anhang'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='workflowconfig',
|
||||
name='welcome_sender_email',
|
||||
field=models.EmailField(blank=True, max_length=254, verbose_name='Welcome E-Mail Absender'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='scheduledwelcomeemail',
|
||||
name='status',
|
||||
field=models.CharField(choices=[('scheduled', 'Geplant'), ('paused', 'Pausiert'), ('cancelled', 'Abgebrochen'), ('sent', 'Gesendet'), ('failed', 'Fehlgeschlagen')], default='scheduled', max_length=20),
|
||||
),
|
||||
]
|
||||
0
backend/workflows/migrations/__init__.py
Normal file
0
backend/workflows/migrations/__init__.py
Normal file
Reference in New Issue
Block a user