Files
stiftung-management-system/app/stiftung/management/commands/fix_quarterly_payment_schedule.py
Jan Remmer Siebels c3e0cc0f6a Fix quarterly payment schedule to correct advance payment dates
- Q1: Due December 15 (previous year)
- Q2: Due March 15
- Q3: Due June 15
- Q4: Due September 15

Added new management command fix_quarterly_payment_schedule to update existing payments
2025-10-01 13:12:52 +02:00

107 lines
4.1 KiB
Python

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")