- 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
93 lines
3.6 KiB
Python
93 lines
3.6 KiB
Python
from django.core.management.base import BaseCommand
|
|
from django.db import transaction
|
|
from datetime import date
|
|
from stiftung.models import DestinataerUnterstuetzung
|
|
|
|
|
|
class Command(BaseCommand):
|
|
help = 'Fix Q4 payment due dates from December 31 to December 15'
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument(
|
|
'--dry-run',
|
|
action='store_true',
|
|
help='Show what would be updated without making 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 Q4/2025 payments with wrong due date (Dec 31 instead of Dec 15)
|
|
wrong_payments = DestinataerUnterstuetzung.objects.filter(
|
|
faellig_am='2025-12-31',
|
|
beschreibung__icontains='Q4/2025'
|
|
)
|
|
|
|
total_count = wrong_payments.count()
|
|
self.stdout.write(f'Found {total_count} Q4/2025 payments with wrong due date (31.12 instead of 15.12)')
|
|
|
|
if total_count == 0:
|
|
self.stdout.write(self.style.SUCCESS('No payments need fixing!'))
|
|
return
|
|
|
|
updated_count = 0
|
|
correct_date = date(2025, 12, 15) # December 15, 2025
|
|
|
|
with transaction.atomic():
|
|
for payment in wrong_payments:
|
|
old_date = payment.faellig_am
|
|
|
|
if not dry_run:
|
|
payment.faellig_am = correct_date
|
|
payment.save(update_fields=['faellig_am'])
|
|
|
|
updated_count += 1
|
|
|
|
# Show progress for every 5 updates or if verbose
|
|
if updated_count % 5 == 0 or options['verbosity'] >= 2:
|
|
self.stdout.write(
|
|
f' {payment.destinataer.get_full_name()}: '
|
|
f'{old_date} → {correct_date} ({payment.betrag}€)'
|
|
)
|
|
|
|
# Summary
|
|
if dry_run:
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f'DRY RUN: Would update {updated_count} payment due dates from 31.12.2025 to 15.12.2025'
|
|
)
|
|
)
|
|
else:
|
|
self.stdout.write(
|
|
self.style.SUCCESS(
|
|
f'Successfully updated {updated_count} payment due dates to December 15, 2025'
|
|
)
|
|
)
|
|
|
|
# Also check for other quarters that might have wrong dates
|
|
self.stdout.write('\nChecking other quarters for potential issues:')
|
|
|
|
quarter_checks = {
|
|
'Q1/2025': ('2025-02-15', '2025-03-15'),
|
|
'Q2/2025': ('2025-05-15', '2025-06-15'),
|
|
'Q3/2025': ('2025-08-15', '2025-09-15'),
|
|
}
|
|
|
|
for quarter_desc, (old_expected, new_expected) in quarter_checks.items():
|
|
old_date_payments = DestinataerUnterstuetzung.objects.filter(
|
|
faellig_am=old_expected,
|
|
beschreibung__icontains=quarter_desc
|
|
).count()
|
|
|
|
if old_date_payments > 0:
|
|
self.stdout.write(f' ⚠️ {quarter_desc}: {old_date_payments} payments still use old date {old_expected}')
|
|
self.stdout.write(f' Should be: {new_expected}')
|
|
|
|
self.stdout.write('\nSemester-based payment schedule:')
|
|
self.stdout.write(' Q1: March 15 (Spring semester)')
|
|
self.stdout.write(' Q2: June 15 (Auto-approved with Q1)')
|
|
self.stdout.write(' Q3: September 15 (Fall semester)')
|
|
self.stdout.write(' Q4: December 15 (Auto-approved with Q3)') |