feat: add comprehensive GitHub workflow and development tools

This commit is contained in:
Stiftung Development
2025-09-06 18:31:54 +02:00
commit ab23d7187e
10224 changed files with 2075210 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
# Generated by Django 5.0.6 on 2025-08-13 20:59
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='DokumentLink',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('paperless_document_id', models.IntegerField()),
('kontext', models.CharField(max_length=30)),
('titel', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Person',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('familienzweig', models.CharField(max_length=100)),
('vorname', models.CharField(max_length=100)),
('nachname', models.CharField(max_length=100)),
('geburtsdatum', models.DateField(blank=True, null=True)),
('email', models.EmailField(blank=True, max_length=254, null=True)),
('iban', models.CharField(blank=True, max_length=34, null=True)),
],
),
migrations.CreateModel(
name='Foerderung',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('jahr', models.IntegerField()),
('betrag', models.DecimalField(decimal_places=2, max_digits=12)),
('verwendungsnachweis', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.dokumentlink')),
('person', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.person')),
],
),
]

View File

@@ -0,0 +1,112 @@
# Generated by Django 5.0.6 on 2025-08-13 21:07
import django.core.validators
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='dokumentlink',
options={'ordering': ['titel'], 'verbose_name': 'Dokument', 'verbose_name_plural': 'Dokumente'},
),
migrations.AlterModelOptions(
name='foerderung',
options={'ordering': ['-jahr', '-betrag'], 'verbose_name': 'Förderung', 'verbose_name_plural': 'Förderungen'},
),
migrations.AlterModelOptions(
name='person',
options={'ordering': ['nachname', 'vorname'], 'verbose_name': 'Person', 'verbose_name_plural': 'Personen'},
),
migrations.AddField(
model_name='dokumentlink',
name='beschreibung',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='foerderung',
name='antragsdatum',
field=models.DateField(default=django.utils.timezone.now),
),
migrations.AddField(
model_name='foerderung',
name='bemerkungen',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='foerderung',
name='entscheidungsdatum',
field=models.DateField(blank=True, null=True),
),
migrations.AddField(
model_name='foerderung',
name='kategorie',
field=models.CharField(choices=[('bildung', 'Bildung'), ('forschung', 'Forschung'), ('kultur', 'Kultur'), ('soziales', 'Soziales'), ('umwelt', 'Umwelt'), ('anderes', 'Anderes')], default='anderes', max_length=20),
),
migrations.AddField(
model_name='foerderung',
name='status',
field=models.CharField(choices=[('beantragt', 'Beantragt'), ('genehmigt', 'Genehmigt'), ('ausgezahlt', 'Ausgezahlt'), ('abgelehnt', 'Abgelehnt'), ('storniert', 'Storniert')], default='beantragt', max_length=20),
),
migrations.AddField(
model_name='person',
name='adresse',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='person',
name='aktiv',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='person',
name='notizen',
field=models.TextField(blank=True, null=True),
),
migrations.AddField(
model_name='person',
name='telefon',
field=models.CharField(blank=True, max_length=20, null=True),
),
migrations.AlterField(
model_name='dokumentlink',
name='kontext',
field=models.CharField(choices=[('antrag', 'Antrag'), ('verwendungsnachweis', 'Verwendungsnachweis'), ('rechnung', 'Rechnung'), ('vertrag', 'Vertrag'), ('bericht', 'Bericht'), ('anderes', 'Anderes')], default='anderes', max_length=30),
),
migrations.AlterField(
model_name='dokumentlink',
name='paperless_document_id',
field=models.IntegerField(unique=True),
),
migrations.AlterField(
model_name='foerderung',
name='jahr',
field=models.IntegerField(validators=[django.core.validators.MinValueValidator(1900), django.core.validators.MaxValueValidator(2100)]),
),
migrations.AlterField(
model_name='foerderung',
name='person',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.person', verbose_name='Person'),
),
migrations.AlterField(
model_name='foerderung',
name='verwendungsnachweis',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.dokumentlink', verbose_name='Verwendungsnachweis'),
),
migrations.AlterField(
model_name='person',
name='familienzweig',
field=models.CharField(choices=[('hauptzweig', 'Hauptzweig'), ('nebenzweig', 'Nebenzweig'), ('verwandt', 'Verwandt'), ('anderer', 'Anderer')], default='hauptzweig', max_length=100),
),
migrations.AlterUniqueTogether(
name='foerderung',
unique_together={('person', 'jahr', 'kategorie')},
),
]

View File

@@ -0,0 +1,78 @@
# Generated by Django 5.0.6 on 2025-08-13 21:43
import django.core.validators
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0002_alter_dokumentlink_options_alter_foerderung_options_and_more'),
]
operations = [
migrations.CreateModel(
name='Land',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('lfd_nr', models.CharField(max_length=20, unique=True, verbose_name='Lfd. Nr.')),
('ew_nummer', models.CharField(blank=True, max_length=50, null=True, verbose_name='EW-Nummer')),
('amtsgericht', models.CharField(max_length=100, verbose_name='Amtsgericht')),
('gemeinde', models.CharField(max_length=100, verbose_name='Gemeinde')),
('gemarkung', models.CharField(max_length=100, verbose_name='Gemarkung')),
('flur', models.CharField(max_length=50, verbose_name='Flur')),
('flurstueck', models.CharField(max_length=50, verbose_name='Flurstück')),
('groesse_qm', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(0.01)], verbose_name='Größe in qm')),
('gruenland_qm', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Grünland (qm)')),
('acker_qm', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Acker (qm)')),
('wald_qm', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Wald (qm)')),
('sonstiges_qm', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Sonstiges (qm)')),
('verpachtete_gesamtflaeche', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Verpachtete Gesamtfläche (qm)')),
('flaeche_alte_liste', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Fläche alte Liste (qm)')),
('verp_flaeche_aktuell', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Verp. Fläche aktuell (qm)')),
('anteil_grundsteuer', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True, verbose_name='Anteil Grundsteuer (%)')),
('anteil_lwk', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True, verbose_name='Anteil LWK (%)')),
('aktiv', models.BooleanField(default=True, verbose_name='Aktiv')),
('notizen', models.TextField(blank=True, null=True, verbose_name='Ergänzende Kommentare')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Land',
'verbose_name_plural': 'Ländereien',
'ordering': ['gemeinde', 'gemarkung', 'flur', 'flurstueck'],
},
),
migrations.AlterField(
model_name='dokumentlink',
name='kontext',
field=models.CharField(choices=[('antrag', 'Antrag'), ('verwendungsnachweis', 'Verwendungsnachweis'), ('rechnung', 'Rechnung'), ('vertrag', 'Vertrag'), ('bericht', 'Bericht'), ('landkarte', 'Landkarte'), ('kataster', 'Kataster'), ('anderes', 'Anderes')], default='anderes', max_length=30),
),
migrations.CreateModel(
name='Verpachtung',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('vertragsnummer', models.CharField(max_length=50, unique=True, verbose_name='Vertragsnummer')),
('pachtbeginn', models.DateField(verbose_name='Pachtbeginn')),
('pachtende', models.DateField(verbose_name='Pachtende')),
('verlaengerung', models.DateField(blank=True, null=True, verbose_name='Verlängerung bis')),
('pachtzins_pro_qm', models.DecimalField(decimal_places=4, max_digits=8, verbose_name='Pachtzins pro qm (€)')),
('pachtzins_jaehrlich', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Jährlicher Pachtzins (€)')),
('verpachtete_flaeche', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Verpachtete Fläche (qm)')),
('status', models.CharField(choices=[('aktiv', 'Aktiv'), ('beendet', 'Beendet'), ('gekuendigt', 'Gekündigt'), ('verlängert', 'Verlängert')], default='aktiv', max_length=20)),
('bemerkungen', models.TextField(blank=True, null=True, verbose_name='Ergänzende Kommentare')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
('land', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.land', verbose_name='Land')),
('paechter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.person', verbose_name='Pächter')),
('verwendungsnachweis', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.dokumentlink', verbose_name='Verwendungsnachweis')),
],
options={
'verbose_name': 'Verpachtung',
'verbose_name_plural': 'Verpachtungen',
'ordering': ['-pachtbeginn'],
},
),
]

View File

@@ -0,0 +1,36 @@
# Generated by Django 5.0.6 on 2025-08-13 22:18
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0003_land_alter_dokumentlink_kontext_verpachtung'),
]
operations = [
migrations.CreateModel(
name='CSVImport',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('import_type', models.CharField(choices=[('personen', 'Personen'), ('laendereien', 'Ländereien'), ('verpachtungen', 'Verpachtungen')], max_length=20, verbose_name='Import-Typ')),
('filename', models.CharField(max_length=255, verbose_name='Dateiname')),
('file_size', models.IntegerField(verbose_name='Dateigröße (Bytes)')),
('status', models.CharField(choices=[('pending', 'Ausstehend'), ('processing', 'Wird verarbeitet'), ('completed', 'Abgeschlossen'), ('failed', 'Fehlgeschlagen'), ('partial', 'Teilweise erfolgreich')], default='pending', max_length=20)),
('total_rows', models.IntegerField(default=0, verbose_name='Gesamtzeilen')),
('imported_rows', models.IntegerField(default=0, verbose_name='Importierte Zeilen')),
('failed_rows', models.IntegerField(default=0, verbose_name='Fehlgeschlagene Zeilen')),
('error_log', models.TextField(blank=True, null=True, verbose_name='Fehlerprotokoll')),
('created_by', models.CharField(blank=True, max_length=100, null=True, verbose_name='Erstellt von')),
('started_at', models.DateTimeField(auto_now_add=True, verbose_name='Gestartet um')),
('completed_at', models.DateTimeField(blank=True, null=True, verbose_name='Abgeschlossen um')),
],
options={
'verbose_name': 'CSV Import',
'verbose_name_plural': 'CSV Imports',
'ordering': ['-started_at'],
},
),
]

View File

@@ -0,0 +1,93 @@
# Generated by Django 5.0.6 on 2025-08-14 10:38
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0004_csvimport'),
]
operations = [
migrations.CreateModel(
name='Destinataer',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('familienzweig', models.CharField(choices=[('hauptzweig', 'Hauptzweig'), ('nebenzweig', 'Nebenzweig'), ('verwandt', 'Verwandt'), ('anderer', 'Anderer')], default='hauptzweig', max_length=100)),
('vorname', models.CharField(max_length=100, verbose_name='Vorname')),
('nachname', models.CharField(max_length=100, verbose_name='Nachname')),
('geburtsdatum', models.DateField(blank=True, null=True, verbose_name='Geburtsdatum')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-Mail')),
('telefon', models.CharField(blank=True, max_length=20, null=True, verbose_name='Telefon')),
('iban', models.CharField(blank=True, max_length=34, null=True, verbose_name='IBAN')),
('adresse', models.TextField(blank=True, null=True, verbose_name='Adresse')),
('berufsgruppe', models.CharField(choices=[('student', 'Student/Studentin'), ('wissenschaftler', 'Wissenschaftler/in'), ('künstler', 'Künstler/in'), ('sozialarbeiter', 'Sozialarbeiter/in'), ('umweltschützer', 'Umweltschützer/in'), ('andere', 'Andere')], default='andere', max_length=20, verbose_name='Berufsgruppe')),
('ausbildungsstand', models.CharField(blank=True, max_length=100, null=True, verbose_name='Ausbildungsstand')),
('institution', models.CharField(blank=True, max_length=200, null=True, verbose_name='Institution/Organisation')),
('projekt_beschreibung', models.TextField(blank=True, null=True, verbose_name='Projektbeschreibung')),
('jaehrliches_einkommen', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Jährliches Einkommen (€)')),
('finanzielle_notlage', models.BooleanField(default=False, verbose_name='Finanzielle Notlage')),
('notizen', models.TextField(blank=True, null=True, verbose_name='Notizen')),
('aktiv', models.BooleanField(default=True, verbose_name='Aktiv')),
],
options={
'verbose_name': 'Destinatär',
'verbose_name_plural': 'Destinatäre',
'ordering': ['nachname', 'vorname'],
},
),
migrations.CreateModel(
name='Paechter',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('familienzweig', models.CharField(choices=[('hauptzweig', 'Hauptzweig'), ('nebenzweig', 'Nebenzweig'), ('verwandt', 'Verwandt'), ('anderer', 'Anderer')], default='hauptzweig', max_length=100)),
('vorname', models.CharField(max_length=100, verbose_name='Vorname')),
('nachname', models.CharField(max_length=100, verbose_name='Nachname')),
('geburtsdatum', models.DateField(blank=True, null=True, verbose_name='Geburtsdatum')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-Mail')),
('telefon', models.CharField(blank=True, max_length=20, null=True, verbose_name='Telefon')),
('iban', models.CharField(blank=True, max_length=34, null=True, verbose_name='IBAN')),
('adresse', models.TextField(blank=True, null=True, verbose_name='Adresse')),
('pachtnummer', models.CharField(blank=True, max_length=50, null=True, verbose_name='Pachtnummer')),
('pachtbeginn_erste', models.DateField(blank=True, null=True, verbose_name='Erster Pachtbeginn')),
('pachtende_letzte', models.DateField(blank=True, null=True, verbose_name='Letztes Pachtende')),
('pachtzins_aktuell', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Aktueller Pachtzins (€/Jahr)')),
('landwirtschaftliche_ausbildung', models.BooleanField(default=False, verbose_name='Landwirtschaftliche Ausbildung')),
('berufserfahrung_jahre', models.IntegerField(blank=True, null=True, verbose_name='Berufserfahrung (Jahre)')),
('spezialisierung', models.CharField(blank=True, max_length=100, null=True, verbose_name='Spezialisierung')),
('notizen', models.TextField(blank=True, null=True, verbose_name='Notizen')),
('aktiv', models.BooleanField(default=True, verbose_name='Aktiv')),
],
options={
'verbose_name': 'Pächter',
'verbose_name_plural': 'Pächter',
'ordering': ['nachname', 'vorname'],
},
),
migrations.AlterModelOptions(
name='person',
options={'ordering': ['nachname', 'vorname'], 'verbose_name': 'Person (Legacy)', 'verbose_name_plural': 'Personen (Legacy)'},
),
migrations.AlterUniqueTogether(
name='foerderung',
unique_together=set(),
),
migrations.AlterField(
model_name='foerderung',
name='person',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='stiftung.person', verbose_name='Person (Legacy)'),
),
migrations.AddField(
model_name='foerderung',
name='destinataer',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='stiftung.destinataer', verbose_name='Destinatär'),
),
migrations.AlterField(
model_name='verpachtung',
name='paechter',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.paechter', verbose_name='Pächter'),
),
]

View File

@@ -0,0 +1,22 @@
# Generated by Django 5.0.6 on 2025-08-14 12:00
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0005_destinataer_paechter_alter_person_options_and_more'),
]
operations = [
migrations.RemoveField(
model_name='paechter',
name='familienzweig',
),
migrations.AlterField(
model_name='csvimport',
name='import_type',
field=models.CharField(choices=[('destinataere', 'Destinatäre'), ('paechter', 'Pächter'), ('laendereien', 'Ländereien'), ('verpachtungen', 'Verpachtungen'), ('personen', 'Personen (Legacy)')], max_length=20, verbose_name='Import-Typ'),
),
]

View File

@@ -0,0 +1,56 @@
# Generated by Django 5.0.6 on 2025-08-14 12:10
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0006_remove_paechter_familienzweig_and_more'),
]
operations = [
migrations.RemoveField(
model_name='destinataer',
name='adresse',
),
migrations.RemoveField(
model_name='paechter',
name='adresse',
),
migrations.AddField(
model_name='destinataer',
name='ort',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Ort'),
),
migrations.AddField(
model_name='destinataer',
name='plz',
field=models.CharField(blank=True, max_length=10, null=True, verbose_name='PLZ'),
),
migrations.AddField(
model_name='destinataer',
name='strasse',
field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Straße'),
),
migrations.AddField(
model_name='paechter',
name='ort',
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Ort'),
),
migrations.AddField(
model_name='paechter',
name='personentyp',
field=models.CharField(choices=[('natuerlich', 'Natürliche Person'), ('gesellschaft', 'Gesellschaft (GmbH, KG, etc.)')], default='natuerlich', max_length=20, verbose_name='Typ des Pächters'),
),
migrations.AddField(
model_name='paechter',
name='plz',
field=models.CharField(blank=True, max_length=10, null=True, verbose_name='PLZ'),
),
migrations.AddField(
model_name='paechter',
name='strasse',
field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Straße'),
),
]

View File

@@ -0,0 +1,43 @@
# Generated by Django 5.0.6 on 2025-08-14 19:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0007_remove_destinataer_adresse_remove_paechter_adresse_and_more'),
]
operations = [
migrations.AddField(
model_name='dokumentlink',
name='destinataer_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Destinatär ID'),
),
migrations.AddField(
model_name='dokumentlink',
name='foerderung_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Förderung ID'),
),
migrations.AddField(
model_name='dokumentlink',
name='land_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Länderei ID'),
),
migrations.AddField(
model_name='dokumentlink',
name='paechter_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Pächter ID'),
),
migrations.AddField(
model_name='dokumentlink',
name='verpachtung_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Verpachtung ID'),
),
migrations.AlterField(
model_name='dokumentlink',
name='kontext',
field=models.CharField(choices=[('pachtvertrag', 'Pachtvertrag'), ('antrag', 'Antrag'), ('verwendungsnachweis', 'Verwendungsnachweis'), ('rechnung', 'Rechnung'), ('vertrag', 'Vertrag'), ('bericht', 'Bericht'), ('landkarte', 'Landkarte'), ('kataster', 'Kataster'), ('anderes', 'Anderes')], default='anderes', max_length=30),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-08-23 21:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0008_dokumentlink_destinataer_id_and_more'),
]
operations = [
migrations.AlterField(
model_name='dokumentlink',
name='paperless_document_id',
field=models.IntegerField(),
),
]

View File

@@ -0,0 +1,100 @@
# Generated by Django 5.0.6 on 2025-08-24 17:48
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0009_alter_dokumentlink_paperless_document_id'),
]
operations = [
migrations.CreateModel(
name='Rentmeister',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('anrede', models.CharField(blank=True, choices=[('herr', 'Herr'), ('frau', 'Frau'), ('dr', 'Dr.'), ('prof', 'Prof.'), ('prof_dr', 'Prof. Dr.')], max_length=10, verbose_name='Anrede')),
('vorname', models.CharField(max_length=100, verbose_name='Vorname')),
('nachname', models.CharField(max_length=100, verbose_name='Nachname')),
('titel', models.CharField(blank=True, max_length=50, verbose_name='Titel')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='E-Mail')),
('telefon', models.CharField(blank=True, max_length=20, verbose_name='Telefon')),
('mobil', models.CharField(blank=True, max_length=20, verbose_name='Mobil')),
('strasse', models.CharField(blank=True, max_length=200, verbose_name='Straße')),
('plz', models.CharField(blank=True, max_length=10, verbose_name='PLZ')),
('ort', models.CharField(blank=True, max_length=100, verbose_name='Ort')),
('iban', models.CharField(blank=True, max_length=34, verbose_name='IBAN')),
('bic', models.CharField(blank=True, max_length=11, verbose_name='BIC')),
('bank_name', models.CharField(blank=True, max_length=100, verbose_name='Bank')),
('seit_datum', models.DateField(verbose_name='Rentmeister seit')),
('bis_datum', models.DateField(blank=True, null=True, verbose_name='Rentmeister bis')),
('aktiv', models.BooleanField(default=True, verbose_name='Aktiv')),
('monatliche_verguetung', models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True, verbose_name='Monatliche Vergütung (€)')),
('km_pauschale', models.DecimalField(decimal_places=2, default=0.3, max_digits=4, verbose_name='Kilometerpauschale (€/km)')),
('notizen', models.TextField(blank=True, verbose_name='Notizen')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Rentmeister',
'verbose_name_plural': 'Rentmeister',
'ordering': ['nachname', 'vorname'],
},
),
migrations.CreateModel(
name='StiftungsKonto',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('kontoname', models.CharField(max_length=200, verbose_name='Kontoname')),
('bank_name', models.CharField(max_length=200, verbose_name='Bank')),
('iban', models.CharField(max_length=34, verbose_name='IBAN')),
('bic', models.CharField(blank=True, max_length=11, verbose_name='BIC')),
('konto_typ', models.CharField(choices=[('girokonto', 'Girokonto'), ('sparkonto', 'Sparkonto'), ('festgeld', 'Festgeld'), ('tagesgeld', 'Tagesgeld'), ('depot', 'Depot'), ('sonstiges', 'Sonstiges')], default='girokonto', max_length=20, verbose_name='Kontotyp')),
('saldo', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='Aktueller Saldo')),
('saldo_datum', models.DateField(blank=True, null=True, verbose_name='Saldo-Datum')),
('zinssatz', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True, verbose_name='Zinssatz (%)')),
('laufzeit_bis', models.DateField(blank=True, null=True, verbose_name='Laufzeit bis')),
('aktiv', models.BooleanField(default=True, verbose_name='Aktiv')),
('notizen', models.TextField(blank=True, verbose_name='Notizen')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
],
options={
'verbose_name': 'Stiftungskonto',
'verbose_name_plural': 'Stiftungskonten',
'ordering': ['bank_name', 'kontoname'],
},
),
migrations.CreateModel(
name='Verwaltungskosten',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('bezeichnung', models.CharField(max_length=200, verbose_name='Bezeichnung')),
('kategorie', models.CharField(choices=[('rechnung_intern', 'Interne Rechnung'), ('bueroausstattung', 'Büroausstattung'), ('fahrtkosten', 'Fahrtkosten'), ('porto', 'Porto & Versand'), ('telefon_internet', 'Telefon & Internet'), ('software', 'Software & Lizenzen'), ('beratung', 'Beratung & Dienstleistungen'), ('versicherung', 'Versicherungen'), ('steuerberatung', 'Steuerberatung'), ('bankgebuehren', 'Bankgebühren'), ('sonstiges', 'Sonstiges')], max_length=30, verbose_name='Kategorie')),
('betrag', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Betrag (€)')),
('datum', models.DateField(verbose_name='Datum')),
('lieferant_firma', models.CharField(blank=True, max_length=200, verbose_name='Lieferant/Firma')),
('rechnungsnummer', models.CharField(blank=True, max_length=100, verbose_name='Rechnungsnummer')),
('status', models.CharField(choices=[('geplant', 'Geplant'), ('bestellt', 'Bestellt'), ('erhalten', 'Erhalten'), ('bezahlt', 'Bezahlt'), ('storniert', 'Storniert')], default='geplant', max_length=20, verbose_name='Status')),
('km_anzahl', models.DecimalField(blank=True, decimal_places=1, max_digits=8, null=True, verbose_name='Kilometer')),
('km_satz', models.DecimalField(blank=True, decimal_places=2, max_digits=4, null=True, verbose_name='€/km')),
('von_ort', models.CharField(blank=True, max_length=100, verbose_name='Von (Ort)')),
('nach_ort', models.CharField(blank=True, max_length=100, verbose_name='Nach (Ort)')),
('zweck', models.CharField(blank=True, max_length=200, verbose_name='Zweck der Fahrt')),
('beschreibung', models.TextField(blank=True, verbose_name='Beschreibung')),
('notizen', models.TextField(blank=True, verbose_name='Notizen')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
('konto', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.stiftungskonto', verbose_name='Konto')),
('rentmeister', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.rentmeister', verbose_name='Rentmeister')),
],
options={
'verbose_name': 'Verwaltungskosten',
'verbose_name_plural': 'Verwaltungskosten',
'ordering': ['-datum', '-erstellt_am'],
},
),
]

View File

@@ -0,0 +1,44 @@
# Generated by Django 5.0.6 on 2025-08-24 19:27
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0010_rentmeister_stiftungskonto_verwaltungskosten'),
]
operations = [
migrations.CreateModel(
name='BankTransaction',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('datum', models.DateField(verbose_name='Buchungsdatum')),
('valuta', models.DateField(blank=True, null=True, verbose_name='Valutadatum')),
('betrag', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Betrag (€)')),
('waehrung', models.CharField(default='EUR', max_length=3, verbose_name='Währung')),
('verwendungszweck', models.TextField(verbose_name='Verwendungszweck')),
('empfaenger_zahlungspflichtiger', models.CharField(blank=True, max_length=200, verbose_name='Empfänger/Zahlungspflichtiger')),
('iban_gegenpartei', models.CharField(blank=True, max_length=34, verbose_name='IBAN Gegenpartei')),
('bic_gegenpartei', models.CharField(blank=True, max_length=11, verbose_name='BIC Gegenpartei')),
('referenz', models.CharField(blank=True, max_length=100, verbose_name='Referenz/Transaktions-ID')),
('transaction_type', models.CharField(choices=[('eingang', 'Eingang'), ('ausgang', 'Ausgang'), ('lastschrift', 'Lastschrift'), ('ueberweisung', 'Überweisung'), ('dauerauftrag', 'Dauerauftrag'), ('kartenzahlung', 'Kartenzahlung'), ('zinsen', 'Zinsen'), ('gebuehren', 'Gebühren'), ('sonstiges', 'Sonstiges')], default='sonstiges', max_length=20, verbose_name='Transaktionsart')),
('status', models.CharField(choices=[('imported', 'Importiert'), ('verified', 'Geprüft'), ('assigned', 'Zugeordnet'), ('ignored', 'Ignoriert')], default='imported', max_length=20, verbose_name='Status')),
('kommentare', models.TextField(blank=True, verbose_name='Kommentare')),
('import_datei', models.CharField(blank=True, max_length=255, verbose_name='Import-Datei')),
('importiert_am', models.DateTimeField(auto_now_add=True, verbose_name='Importiert am')),
('saldo_nach_buchung', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Saldo nach Buchung')),
('konto', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='stiftung.stiftungskonto', verbose_name='Konto')),
('verwaltungskosten', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.verwaltungskosten', verbose_name='Zugeordnete Verwaltungskosten')),
],
options={
'verbose_name': 'Banktransaktion',
'verbose_name_plural': 'Banktransaktionen',
'ordering': ['-datum', '-importiert_am'],
'unique_together': {('konto', 'datum', 'betrag', 'referenz')},
},
),
]

View File

@@ -0,0 +1,34 @@
# Generated by Django 5.0.6 on 2025-08-24 20:03
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0011_banktransaction'),
]
operations = [
migrations.AddField(
model_name='verwaltungskosten',
name='quellkonto',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='ausgaben', to='stiftung.stiftungskonto', verbose_name='Quellkonto'),
),
migrations.AddField(
model_name='verwaltungskosten',
name='zahlungskonto',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='zahlungen', to='stiftung.stiftungskonto', verbose_name='Zahlungskonto'),
),
migrations.AlterField(
model_name='verwaltungskosten',
name='konto',
field=models.ForeignKey(blank=True, help_text='Veraltet - verwende Zahlungskonto und Quellkonto', null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.stiftungskonto', verbose_name='Konto (Legacy)'),
),
migrations.AlterField(
model_name='verwaltungskosten',
name='rentmeister',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.rentmeister', verbose_name='Zuständiger Rentmeister'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-08-24 20:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0012_verwaltungskosten_quellkonto_and_more'),
]
operations = [
migrations.AlterField(
model_name='verwaltungskosten',
name='status',
field=models.CharField(choices=[('geplant', 'Geplant'), ('bestellt', 'Bestellt'), ('erhalten', 'Erhalten'), ('in_bearbeitung', 'In Bearbeitung'), ('bezahlt', 'Bezahlt'), ('storniert', 'Storniert')], default='geplant', max_length=20, verbose_name='Status'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-08-26 08:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0013_alter_verwaltungskosten_status'),
]
operations = [
migrations.AddField(
model_name='dokumentlink',
name='rentmeister_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Rentmeister ID'),
),
]

View File

@@ -0,0 +1,63 @@
# Generated by Django 5.0.6 on 2025-08-26 08:33
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0014_dokumentlink_rentmeister_id'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='BackupJob',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('backup_type', models.CharField(choices=[('full', 'Vollständiges Backup'), ('database', 'Nur Datenbank'), ('files', 'Nur Dateien')], max_length=20, verbose_name='Backup-Typ')),
('status', models.CharField(choices=[('pending', 'Wartend'), ('running', 'Läuft'), ('completed', 'Abgeschlossen'), ('failed', 'Fehlgeschlagen')], default='pending', max_length=20, verbose_name='Status')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Erstellt am')),
('started_at', models.DateTimeField(blank=True, null=True, verbose_name='Gestartet am')),
('completed_at', models.DateTimeField(blank=True, null=True, verbose_name='Abgeschlossen am')),
('backup_filename', models.CharField(blank=True, max_length=255, verbose_name='Backup-Dateiname')),
('backup_size', models.BigIntegerField(blank=True, null=True, verbose_name='Backup-Größe (Bytes)')),
('error_message', models.TextField(blank=True, verbose_name='Fehlermeldung')),
('database_size', models.BigIntegerField(blank=True, null=True, verbose_name='Datenbankgröße (Bytes)')),
('files_count', models.IntegerField(blank=True, null=True, verbose_name='Anzahl Dateien')),
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Erstellt von')),
],
options={
'verbose_name': 'Backup-Job',
'verbose_name_plural': 'Backup-Jobs',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='AuditLog',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('username', models.CharField(max_length=150, verbose_name='Benutzername')),
('timestamp', models.DateTimeField(auto_now_add=True, verbose_name='Zeitpunkt')),
('action', models.CharField(choices=[('create', 'Erstellt'), ('update', 'Aktualisiert'), ('delete', 'Gelöscht'), ('link', 'Verknüpft'), ('unlink', 'Verknüpfung entfernt'), ('login', 'Anmeldung'), ('logout', 'Abmeldung'), ('backup', 'Backup erstellt'), ('restore', 'Wiederherstellung'), ('export', 'Export'), ('import', 'Import')], max_length=20, verbose_name='Aktion')),
('entity_type', models.CharField(choices=[('destinataer', 'Destinatär'), ('land', 'Länderei'), ('paechter', 'Pächter'), ('verpachtung', 'Verpachtung'), ('foerderung', 'Förderung'), ('rentmeister', 'Rentmeister'), ('stiftungskonto', 'Stiftungskonto'), ('verwaltungskosten', 'Verwaltungskosten'), ('banktransaction', 'Bank-Transaktion'), ('dokumentlink', 'Dokument-Verknüpfung'), ('system', 'System'), ('user', 'Benutzer')], max_length=20, verbose_name='Entitätstyp')),
('entity_id', models.CharField(blank=True, max_length=100, verbose_name='Entitäts-ID')),
('entity_name', models.CharField(max_length=255, verbose_name='Entitätsname')),
('description', models.TextField(verbose_name='Beschreibung')),
('changes', models.JSONField(blank=True, null=True, verbose_name='Änderungen')),
('ip_address', models.GenericIPAddressField(blank=True, null=True, verbose_name='IP-Adresse')),
('user_agent', models.TextField(blank=True, verbose_name='User Agent')),
('session_key', models.CharField(blank=True, max_length=40, verbose_name='Session-Key')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Benutzer')),
],
options={
'verbose_name': 'Audit Log Eintrag',
'verbose_name_plural': 'Audit Log Einträge',
'ordering': ['-timestamp'],
'indexes': [models.Index(fields=['timestamp'], name='stiftung_au_timesta_c4591e_idx'), models.Index(fields=['user', 'timestamp'], name='stiftung_au_user_id_e3fc12_idx'), models.Index(fields=['entity_type', 'timestamp'], name='stiftung_au_entity__68f25d_idx'), models.Index(fields=['action', 'timestamp'], name='stiftung_au_action_288765_idx')],
},
),
]

View File

@@ -0,0 +1,24 @@
# Generated by Django 5.0.6 on 2025-08-26 08:50
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0015_backupjob_auditlog'),
]
operations = [
migrations.CreateModel(
name='ApplicationPermission',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
],
options={
'permissions': [('manage_destinataere', 'Kann Destinatäre verwalten'), ('view_destinataere', 'Kann Destinatäre anzeigen'), ('manage_land', 'Kann Ländereien verwalten'), ('view_land', 'Kann Ländereien anzeigen'), ('manage_paechter', 'Kann Pächter verwalten'), ('view_paechter', 'Kann Pächter anzeigen'), ('manage_verpachtungen', 'Kann Verpachtungen verwalten'), ('view_verpachtungen', 'Kann Verpachtungen anzeigen'), ('manage_foerderungen', 'Kann Förderungen verwalten'), ('view_foerderungen', 'Kann Förderungen anzeigen'), ('manage_documents', 'Kann Dokumente verwalten'), ('view_documents', 'Kann Dokumente anzeigen'), ('link_documents', 'Kann Dokumente verknüpfen'), ('manage_verwaltungskosten', 'Kann Verwaltungskosten verwalten'), ('view_verwaltungskosten', 'Kann Verwaltungskosten anzeigen'), ('approve_payments', 'Kann Zahlungen genehmigen'), ('manage_konten', 'Kann Stiftungskonten verwalten'), ('view_konten', 'Kann Stiftungskonten anzeigen'), ('manage_rentmeister', 'Kann Rentmeister verwalten'), ('view_rentmeister', 'Kann Rentmeister anzeigen'), ('access_administration', 'Kann Administration aufrufen'), ('view_audit_logs', 'Kann Audit-Logs anzeigen'), ('manage_backups', 'Kann Backups erstellen und verwalten'), ('manage_users', 'Kann Benutzer verwalten'), ('manage_permissions', 'Kann Berechtigungen verwalten'), ('import_data', 'Kann Daten importieren'), ('export_data', 'Kann Daten exportieren'), ('access_django_admin', 'Kann Django Admin aufrufen'), ('view_system_stats', 'Kann Systemstatistiken anzeigen')],
'managed': False,
'default_permissions': (),
},
),
]

View File

@@ -0,0 +1,54 @@
# Generated by Django 5.0.6 on 2025-08-29 13:15
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0016_applicationpermission'),
]
operations = [
migrations.AddField(
model_name='destinataer',
name='haushaltsgroesse',
field=models.PositiveIntegerField(default=1, verbose_name='Haushaltsgröße'),
),
migrations.AddField(
model_name='destinataer',
name='ist_abkoemmling',
field=models.BooleanField(default=False, verbose_name='Abkömmling gem. Satzung'),
),
migrations.AddField(
model_name='destinataer',
name='letzter_studiennachweis',
field=models.DateField(blank=True, null=True, verbose_name='Letzter Studiennachweis'),
),
migrations.AddField(
model_name='destinataer',
name='monatliche_bezuege',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True, verbose_name='Monatliche Bezüge (€)'),
),
migrations.AddField(
model_name='destinataer',
name='standard_konto',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='stiftung.stiftungskonto', verbose_name='Standard Auszahlungskonto'),
),
migrations.AddField(
model_name='destinataer',
name='studiennachweis_erforderlich',
field=models.BooleanField(default=False, verbose_name='Studiennachweis erforderlich'),
),
migrations.AddField(
model_name='destinataer',
name='unterstuetzung_bestaetigt',
field=models.BooleanField(default=False, verbose_name='Unterstützung bestätigt'),
),
migrations.AddField(
model_name='destinataer',
name='vermoegen',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Vermögen (€)'),
),
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-08-29 13:27
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0017_destinataer_haushaltsgroesse_and_more'),
]
operations = [
migrations.AddField(
model_name='destinataer',
name='vierteljaehrlicher_betrag',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, verbose_name='Vierteljährlicher Betrag (€)'),
),
]

View File

@@ -0,0 +1,35 @@
# Generated by Django 5.0.6 on 2025-08-29 13:40
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0018_destinataer_vierteljaehrlicher_betrag'),
]
operations = [
migrations.CreateModel(
name='DestinataerUnterstuetzung',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('betrag', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Betrag (€)')),
('faellig_am', models.DateField(verbose_name='Fällig am')),
('status', models.CharField(choices=[('geplant', 'Geplant'), ('in_bearbeitung', 'In Bearbeitung'), ('ausgezahlt', 'Ausgezahlt'), ('storniert', 'Storniert')], default='geplant', max_length=20, verbose_name='Status')),
('beschreibung', models.CharField(blank=True, max_length=255, verbose_name='Beschreibung')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
('destinataer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unterstuetzungen', to='stiftung.destinataer', verbose_name='Destinatär')),
('konto', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='stiftung.stiftungskonto', verbose_name='Zahlungskonto')),
],
options={
'verbose_name': 'Destinatärunterstützung',
'verbose_name_plural': 'Destinatärunterstützungen',
'ordering': ['-faellig_am', '-erstellt_am'],
'indexes': [models.Index(fields=['status', 'faellig_am'], name='stiftung_de_status_1e9799_idx'), models.Index(fields=['destinataer', 'status'], name='stiftung_de_destina_ba7286_idx')],
},
),
]

View File

@@ -0,0 +1,34 @@
# Generated by Django 5.0.6 on 2025-08-29 16:05
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0019_destinataerunterstuetzung'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='DestinataerNotiz',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('titel', models.CharField(blank=True, max_length=200, verbose_name='Titel')),
('text', models.TextField(blank=True, verbose_name='Notiz')),
('datei', models.FileField(blank=True, null=True, upload_to='destinataer_notizen/', verbose_name='Anhang')),
('erstellt_am', models.DateTimeField(auto_now_add=True, verbose_name='Erstellt am')),
('destinataer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notizen_eintraege', to='stiftung.destinataer', verbose_name='Destinatär')),
('erstellt_von', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Erstellt von')),
],
options={
'verbose_name': 'Destinatär-Notiz',
'verbose_name_plural': 'Destinatär-Notizen',
'ordering': ['-erstellt_am'],
},
),
]

View File

@@ -0,0 +1,134 @@
# Generated by Django 5.0.6 on 2025-08-30 14:20
import django.core.validators
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0020_destinataernotiz'),
]
operations = [
migrations.AddField(
model_name='land',
name='adresse',
field=models.CharField(blank=True, max_length=200, null=True, verbose_name='Adresse/Ortsangabe'),
),
migrations.AddField(
model_name='land',
name='aktueller_paechter',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='gepachtete_laendereien', to='stiftung.paechter', verbose_name='Aktueller Pächter'),
),
migrations.AddField(
model_name='land',
name='grundbuchblatt',
field=models.CharField(blank=True, max_length=50, null=True, verbose_name='Grundbuchblatt'),
),
migrations.AddField(
model_name='land',
name='grundsteuer_umlage',
field=models.BooleanField(default=True, verbose_name='Grundsteuer umlagefähig'),
),
migrations.AddField(
model_name='land',
name='jagdpacht_anteil_umlage',
field=models.BooleanField(default=False, verbose_name='Jagdpachtanteile umlagefähig'),
),
migrations.AddField(
model_name='land',
name='pachtbeginn',
field=models.DateField(blank=True, null=True, verbose_name='Pachtbeginn'),
),
migrations.AddField(
model_name='land',
name='pachtende',
field=models.DateField(blank=True, null=True, verbose_name='Pachtende'),
),
migrations.AddField(
model_name='land',
name='pachtzins_pauschal',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Pachtzins pauschal/Jahr (€)'),
),
migrations.AddField(
model_name='land',
name='pachtzins_pro_ha',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Pachtzins pro ha (€)'),
),
migrations.AddField(
model_name='land',
name='paechter_anschrift',
field=models.TextField(blank=True, null=True, verbose_name='Pächter Anschrift'),
),
migrations.AddField(
model_name='land',
name='paechter_name',
field=models.CharField(blank=True, max_length=150, null=True, verbose_name='Pächter Name'),
),
migrations.AddField(
model_name='land',
name='ust_option',
field=models.BooleanField(default=False, verbose_name='USt-Option'),
),
migrations.AddField(
model_name='land',
name='ust_satz',
field=models.DecimalField(decimal_places=2, default=19.0, max_digits=4, verbose_name='USt-Satz (%)'),
),
migrations.AddField(
model_name='land',
name='verbandsbeitraege_umlage',
field=models.BooleanField(default=True, verbose_name='Verbandsbeiträge umlagefähig'),
),
migrations.AddField(
model_name='land',
name='verlaengerung_klausel',
field=models.BooleanField(default=False, verbose_name='Automatische Verlängerung'),
),
migrations.AddField(
model_name='land',
name='versicherungen_umlage',
field=models.BooleanField(default=True, verbose_name='Versicherungen umlagefähig'),
),
migrations.AddField(
model_name='land',
name='zahlungsweise',
field=models.CharField(choices=[('jaehrlich', 'Jährlich'), ('halbjaehrlich', 'Halbjährlich'), ('vierteljaehrlich', 'Vierteljährlich'), ('monatlich', 'Monatlich')], default='jaehrlich', max_length=20, verbose_name='Zahlungsweise'),
),
migrations.CreateModel(
name='LandAbrechnung',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('abrechnungsjahr', models.IntegerField(validators=[django.core.validators.MinValueValidator(2000)], verbose_name='Abrechnungsjahr')),
('pacht_vereinnahmt', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Pacht vereinnahmt (€)')),
('umlagen_vereinnahmt', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Umlagen vereinnahmt (€)')),
('sonstige_einnahmen', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Sonstige Einnahmen (€)')),
('zahlungen', models.JSONField(blank=True, help_text='Liste von Objekten {datum, betrag, art}', null=True, verbose_name='Zahlungstermine')),
('grundsteuer_bescheid_nr', models.CharField(blank=True, max_length=80, null=True, verbose_name='Grundsteuer-Bescheid Nr.')),
('grundsteuer_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Grundsteuer Betrag (€)')),
('versicherungen_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Versicherungen Betrag (€)')),
('verbandsbeitraege_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Verbandsbeiträge Betrag (€)')),
('sonstige_abgaben_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Sonstige öffentliche Abgaben (€)')),
('instandhaltung_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Instandhaltung/Reparaturen (€)')),
('verwaltung_recht_betrag', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Verwaltung/Recht (€)')),
('vorsteuer_aus_umlagen', models.DecimalField(decimal_places=2, default=0, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Vorsteuer aus umgelegten Kosten (€)')),
('offene_posten', models.DecimalField(decimal_places=2, default=0, max_digits=12, verbose_name='Offene Posten (€)')),
('bemerkungen', models.TextField(blank=True, null=True, verbose_name='Bemerkungen Abrechnung')),
('pachtvertrag_datei', models.FileField(blank=True, null=True, upload_to='land_abrechnungen/vertraege/', verbose_name='Pachtvertrag (Datei)')),
('grundsteuer_bescheid_datei', models.FileField(blank=True, null=True, upload_to='land_abrechnungen/bescheide/', verbose_name='Grundsteuerbescheid (Datei)')),
('versicherungsnachweis_datei', models.FileField(blank=True, null=True, upload_to='land_abrechnungen/versicherungen/', verbose_name='Versicherungsnachweis (Datei)')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
('land', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='abrechnungen', to='stiftung.land', verbose_name='Länderei')),
],
options={
'verbose_name': 'Landabrechnung',
'verbose_name_plural': 'Landabrechnungen',
'ordering': ['-abrechnungsjahr', 'land__gemeinde', 'land__gemarkung'],
'unique_together': {('land', 'abrechnungsjahr')},
},
),
]

View File

@@ -0,0 +1,57 @@
# Generated by Django 5.0.6 on 2025-08-30 16:59
import django.core.validators
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0021_land_adresse_land_aktueller_paechter_and_more'),
]
operations = [
migrations.AddField(
model_name='dokumentlink',
name='land_verpachtung_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Landverpachtung ID (Neu)'),
),
migrations.AlterField(
model_name='dokumentlink',
name='verpachtung_id',
field=models.UUIDField(blank=True, null=True, verbose_name='Verpachtung ID (Legacy)'),
),
migrations.CreateModel(
name='LandVerpachtung',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('vertragsnummer', models.CharField(max_length=50, unique=True, verbose_name='Vertragsnummer')),
('pachtbeginn', models.DateField(verbose_name='Pachtbeginn')),
('pachtende', models.DateField(blank=True, null=True, verbose_name='Pachtende')),
('verlaengerung_klausel', models.BooleanField(default=False, verbose_name='Automatische Verlängerung')),
('verpachtete_flaeche', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(0.01)], verbose_name='Verpachtete Fläche (qm)')),
('pachtzins_pauschal', models.DecimalField(decimal_places=2, max_digits=12, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Pachtzins pauschal/Jahr (€)')),
('pachtzins_pro_ha', models.DecimalField(blank=True, decimal_places=2, max_digits=12, null=True, validators=[django.core.validators.MinValueValidator(0)], verbose_name='Pachtzins pro ha (€)')),
('zahlungsweise', models.CharField(choices=[('jaehrlich', 'Jährlich'), ('halbjaehrlich', 'Halbjährlich'), ('vierteljaehrlich', 'Vierteljährlich'), ('monatlich', 'Monatlich')], default='jaehrlich', max_length=20, verbose_name='Zahlungsweise')),
('ust_option', models.BooleanField(default=False, verbose_name='USt-Option')),
('ust_satz', models.DecimalField(decimal_places=2, default=19.0, max_digits=4, verbose_name='USt-Satz (%)')),
('grundsteuer_umlage', models.BooleanField(default=True, verbose_name='Grundsteuer umlagefähig')),
('versicherungen_umlage', models.BooleanField(default=True, verbose_name='Versicherungen umlagefähig')),
('verbandsbeitraege_umlage', models.BooleanField(default=True, verbose_name='Verbandsbeiträge umlagefähig')),
('jagdpacht_anteil_umlage', models.BooleanField(default=False, verbose_name='Jagdpachtanteile umlagefähig')),
('status', models.CharField(choices=[('aktiv', 'Aktiv'), ('beendet', 'Beendet'), ('gekuendigt', 'Gekündigt'), ('verlängert', 'Verlängert')], default='aktiv', max_length=20, verbose_name='Status')),
('bemerkungen', models.TextField(blank=True, null=True, verbose_name='Bemerkungen')),
('erstellt_am', models.DateTimeField(auto_now_add=True)),
('aktualisiert_am', models.DateTimeField(auto_now=True)),
('land', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='neue_verpachtungen', to='stiftung.land', verbose_name='Länderei')),
('paechter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='neue_verpachtungen', to='stiftung.paechter', verbose_name='Pächter')),
],
options={
'verbose_name': 'Landverpachtung',
'verbose_name_plural': 'Landverpachtungen',
'ordering': ['-pachtbeginn', 'land'],
},
),
]

View File