from django.core.management.base import BaseCommand from django.db.models import Q from datetime import date from stiftung.models import DestinataerUnterstuetzung class Command(BaseCommand): help = 'Fix quarterly payment due dates to correct advance payment schedule' def add_arguments(self, parser): parser.add_argument( '--dry-run', action='store_true', help='Show what would be changed without making actual changes', ) def handle(self, *args, **options): dry_run = options['dry_run'] if dry_run: self.stdout.write( self.style.WARNING('DRY RUN MODE - No changes will be made') ) # Find all quarterly support payments that need fixing payments_to_fix = DestinataerUnterstuetzung.objects.filter( beschreibung__contains="Vierteljährliche Unterstützung" ).exclude( beschreibung__contains="Korrektur" # Avoid fixing already corrected payments ) total_fixed = 0 for payment in payments_to_fix: # Extract quarter and year from description desc = payment.beschreibung try: # Look for pattern like "Q1/2025", "Q2/2025", etc. import re match = re.search(r'Q(\d)/(\d{4})', desc) if not match: continue quartal = int(match.group(1)) jahr = int(match.group(2)) # Calculate correct due date based on advance payment schedule if quartal == 1: # Q1 payment due December 15 of previous year correct_due_date = date(jahr - 1, 12, 15) elif quartal == 2: # Q2 payment due March 15 correct_due_date = date(jahr, 3, 15) elif quartal == 3: # Q3 payment due June 15 correct_due_date = date(jahr, 6, 15) elif quartal == 4: # Q4 payment due September 15 correct_due_date = date(jahr, 9, 15) else: continue # Check if this payment needs updating if payment.faellig_am != correct_due_date: old_date = payment.faellig_am if dry_run: self.stdout.write( f"Would update {payment.destinataer.get_full_name()} " f"Q{quartal}/{jahr} payment: {old_date} -> {correct_due_date}" ) else: payment.faellig_am = correct_due_date payment.save() self.stdout.write( self.style.SUCCESS( f"Updated {payment.destinataer.get_full_name()} " f"Q{quartal}/{jahr} payment: {old_date} -> {correct_due_date}" ) ) total_fixed += 1 except (ValueError, AttributeError) as e: self.stdout.write( self.style.WARNING( f"Could not parse quarter/year from: {desc} - {e}" ) ) continue if dry_run: self.stdout.write( self.style.WARNING( f"Would fix {total_fixed} payment due dates" ) ) else: self.stdout.write( self.style.SUCCESS( f"Successfully fixed {total_fixed} payment due dates" ) ) # Show the expected schedule self.stdout.write("\nCorrect advance payment schedule:") self.stdout.write("Q1: Due December 15 (previous year)") self.stdout.write("Q2: Due March 15") self.stdout.write("Q3: Due June 15") self.stdout.write("Q4: Due September 15")