Fix payment system balance integration and add calendar functionality

- Implement automated payment tracking with Django signals
- Fix duplicate transaction creation with unique referenz system
- Add calendar system with CRUD operations and event management
- Reorganize navigation menu (rename sections, move admin functions)
- Replace Geschichte editor with EasyMDE markdown editor
- Add management commands for balance reconciliation
- Create missing transactions for previously paid payments
- Ensure account balances accurately reflect all payment activity

Features added:
- Calendar entries creation and administration via menu
- Payment status tracking with automatic balance updates
- Duplicate prevention for payment transactions
- Markdown editor with live preview for Geschichte pages
- Database reconciliation tools for payment/balance sync

Bug fixes:
- Resolved IntegrityError on payment status changes
- Fixed missing account balance updates for paid payments
- Prevented duplicate balance deductions on re-saves
- Corrected menu structure and admin function placement
This commit is contained in:
2025-10-05 00:38:18 +02:00
parent 2961f376c3
commit c289cc3c58
36 changed files with 4039 additions and 99 deletions

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-10-02 20:07
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0037_add_geschichte_models'),
]
operations = [
migrations.AlterField(
model_name='geschichteseite',
name='inhalt',
field=models.TextField(blank=True, verbose_name='Inhalt'),
),
]

View File

@@ -0,0 +1,41 @@
# Generated by Django 5.0.6 on 2025-10-04 20:21
import django.db.models.deletion
import uuid
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0038_allow_blank_content'),
]
operations = [
migrations.CreateModel(
name='StiftungsKalenderEintrag',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('titel', models.CharField(max_length=200, verbose_name='Titel')),
('beschreibung', models.TextField(blank=True, verbose_name='Beschreibung')),
('datum', models.DateField(verbose_name='Datum')),
('uhrzeit', models.TimeField(blank=True, null=True, verbose_name='Uhrzeit')),
('ganztags', models.BooleanField(default=True, verbose_name='Ganztägig')),
('kategorie', models.CharField(choices=[('termin', 'Termin/Meeting'), ('zahlung', 'Zahlungserinnerung'), ('deadline', 'Frist/Deadline'), ('geburtstag', 'Geburtstag'), ('vertrag', 'Vertrag läuft aus'), ('pruefung', 'Prüfung/Nachweis'), ('sonstiges', 'Sonstiges')], default='termin', max_length=20, verbose_name='Kategorie')),
('prioritaet', models.CharField(choices=[('niedrig', 'Niedrig'), ('normal', 'Normal'), ('hoch', 'Hoch'), ('kritisch', 'Kritisch')], default='normal', max_length=20, verbose_name='Priorität')),
('erledigt', models.BooleanField(default=False, verbose_name='Erledigt')),
('erledigt_am', models.DateTimeField(blank=True, null=True, verbose_name='Erledigt am')),
('erstellt_von', models.CharField(blank=True, max_length=100, null=True, verbose_name='Erstellt von')),
('erstellt_am', models.DateTimeField(auto_now_add=True, verbose_name='Erstellt am')),
('aktualisiert_am', models.DateTimeField(auto_now=True, verbose_name='Aktualisiert am')),
('destinataer', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='stiftung.destinataer', verbose_name='Bezogener Destinatär')),
('verpachtung', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='stiftung.landverpachtung', verbose_name='Bezogene Verpachtung')),
],
options={
'verbose_name': 'Kalender Eintrag',
'verbose_name_plural': 'Kalender Einträge',
'ordering': ['datum', 'uhrzeit'],
'indexes': [models.Index(fields=['datum'], name='stiftung_st_datum_9e97ed_idx'), models.Index(fields=['kategorie', 'datum'], name='stiftung_st_kategor_d7c7f9_idx'), models.Index(fields=['erledigt', 'datum'], name='stiftung_st_erledig_115235_idx')],
},
),
]

View File

@@ -0,0 +1,13 @@
# Generated by Django 5.0.6 on 2025-10-04 20:28
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0039_stiftungskalendereintrag'),
]
operations = [
]

View File

@@ -0,0 +1,18 @@
# Generated by Django 5.0.6 on 2025-10-04 21:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('stiftung', '0040_add_calendar_model'),
]
operations = [
migrations.AlterField(
model_name='geschichteseite',
name='inhalt',
field=models.TextField(blank=True, help_text='Sie können Markdown verwenden: **fett**, *kursiv*, # Überschriften, [Links](URL), Listen, etc.', verbose_name='Inhalt (Markdown)'),
),
]