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 (advance payment schedule) wrong_q4_payments = DestinataerUnterstuetzung.objects.filter( faellig_am='2025-12-31', beschreibung__icontains='Q4/2025' ).count() # Also check for other quarters with wrong advance payment dates wrong_q1_payments = DestinataerUnterstuetzung.objects.filter( faellig_am='2025-03-31', beschreibung__icontains='Q1/2025' ).count() if wrong_q4_payments > 0: self.stdout.write(f' ❌ {wrong_q4_payments} Q4 payments have wrong due date (31.12 instead of 15.09)') self.stdout.write(' Run: python manage.py fix_q4_payment_dates') elif wrong_q1_payments > 0: self.stdout.write(f' ❌ {wrong_q1_payments} Q1 payments have wrong due date (advance payment schedule)') else: self.stdout.write(' ✓ Payment due dates appear correct') # Show the advance payment schedule self.stdout.write('\nAdvance Payment Schedule:') self.stdout.write(' Q1 payments: Due December 15 of previous year') self.stdout.write(' Q2 payments: Due March 15 of same year') self.stdout.write(' Q3 payments: Due June 15 of same year') self.stdout.write(' Q4 payments: Due September 15 of same year')