Files
stiftung-management-system/app/stiftung/management/commands/diagnose_deadlines.py
Jan Remmer Siebels 149078aaee Add production diagnostic and fix commands for semester deadlines
- diagnose_deadlines: Check migration status, deadline correctness, and payment patterns
- fix_q4_payment_dates: Fix payments with wrong due dates (31.12 → 15.12)
- includes dry-run modes and detailed reporting
- helps identify why production dates haven't updated

Usage on production:
  python manage.py diagnose_deadlines
  python manage.py fix_q4_payment_dates --dry-run
  python manage.py fix_q4_payment_dates
2025-09-30 22:11:18 +02:00

102 lines
4.7 KiB
Python

from django.core.management.base import BaseCommand
from django.db import connection
from stiftung.models import VierteljahresNachweis, DestinataerUnterstuetzung
class Command(BaseCommand):
help = 'Diagnose deadline and payment due date issues on production'
def handle(self, *args, **options):
self.stdout.write(self.style.SUCCESS('=== PRODUCTION DEADLINE DIAGNOSTIC ==='))
# Check if migrations have been applied
with connection.cursor() as cursor:
cursor.execute(
"SELECT name FROM django_migrations WHERE app = 'stiftung' AND name LIKE '%deadline%' ORDER BY id"
)
migration_results = cursor.fetchall()
self.stdout.write('\n1. Migration Status:')
if migration_results:
for migration in migration_results:
self.stdout.write(f'{migration[0]}')
else:
self.stdout.write(' ❌ No deadline-related migrations found!')
# Check quarterly confirmation deadlines
self.stdout.write('\n2. Quarterly Confirmation Deadlines (2025):')
quarterly_records = VierteljahresNachweis.objects.filter(jahr=2025).order_by('quartal', 'destinataer__nachname')
deadline_summary = {}
for record in quarterly_records[:20]: # Limit to first 20 for readability
quarter = record.quartal
if quarter not in deadline_summary:
deadline_summary[quarter] = []
deadline_summary[quarter].append(str(record.faelligkeitsdatum))
for quarter in sorted(deadline_summary.keys()):
unique_dates = list(set(deadline_summary[quarter]))
expected_dates = {
1: '2025-03-15',
2: '2025-06-15',
3: '2025-09-15',
4: '2025-12-15'
}
expected = expected_dates[quarter]
status = '' if len(unique_dates) == 1 and unique_dates[0] == expected else ''
self.stdout.write(f' Q{quarter}: {status} Found: {unique_dates}, Expected: {expected}')
# Check payment due dates
self.stdout.write('\n3. Payment Due Dates (Recent):')
recent_payments = DestinataerUnterstuetzung.objects.filter(
beschreibung__icontains='Q4/2025'
).order_by('-faellig_am')[:5]
if recent_payments:
for payment in recent_payments:
self.stdout.write(f' {payment.destinataer.get_full_name()}: {payment.faellig_am} - {payment.beschreibung}')
else:
self.stdout.write(' No Q4/2025 payments found')
# Check all 2025 payments pattern
self.stdout.write('\n4. All 2025 Payment Due Date Pattern:')
all_2025_payments = DestinataerUnterstuetzung.objects.filter(
faellig_am__year=2025,
beschreibung__icontains='/'
).values_list('faellig_am', 'beschreibung').order_by('faellig_am')
payment_patterns = {}
for payment_date, desc in all_2025_payments:
if 'Q' in desc and '2025' in desc:
quarter_info = desc.split('/')[-1] if '/' in desc else desc
if quarter_info not in payment_patterns:
payment_patterns[quarter_info] = []
payment_patterns[quarter_info].append(str(payment_date))
for quarter_desc in sorted(payment_patterns.keys()):
unique_dates = list(set(payment_patterns[quarter_desc]))
self.stdout.write(f' {quarter_desc}: {unique_dates[:3]}{"..." if len(unique_dates) > 3 else ""}')
# Provide recommendations
self.stdout.write('\n5. Recommendations:')
# Check if deadline migration worked
q4_deadlines = VierteljahresNachweis.objects.filter(jahr=2025, quartal=4).values_list('faelligkeitsdatum', flat=True)
unique_q4_deadlines = list(set(q4_deadlines))
if len(unique_q4_deadlines) == 1 and str(unique_q4_deadlines[0]) == '2025-12-15':
self.stdout.write(' ✓ Quarterly confirmation deadlines are correct')
else:
self.stdout.write(' ❌ Run: python manage.py update_semester_deadlines')
# Check if payments need updating
wrong_payments = DestinataerUnterstuetzung.objects.filter(
faellig_am='2025-12-31',
beschreibung__icontains='Q4/2025'
).count()
if wrong_payments > 0:
self.stdout.write(f'{wrong_payments} payments have wrong due date (31.12 instead of 15.12)')
self.stdout.write(' Run: python manage.py fix_q4_payment_dates')
else:
self.stdout.write(' ✓ Payment due dates appear correct')