Files
stiftung-management-system/app/stiftung/management/commands/fix_q4_payment_dates.py
Jan Remmer Siebels 6aa218004c Implement advance payment schedule for quarterly payments
BREAKING CHANGE: Payment due dates now follow advance payment schedule:
- Q1 payments: Due December 15 of previous year
- Q2 payments: Due March 15 of same year
- Q3 payments: Due June 15 of same year
- Q4 payments: Due September 15 of same year

Changes:
- Updated create_quarterly_support_payment() to use advance schedule
- Enhanced diagnostic commands to check advance payment dates
- Added fix_advance_payment_dates command for comprehensive fixes
- Updated fix_q4_payment_dates to correct Q4 from 31.12 to 15.09

This aligns with semester-based document submissions while maintaining
the advance payment system where payments are made before each quarter.
2025-10-01 12:04:34 +02:00

93 lines
3.7 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 Sep 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, 9, 15) # September 15, 2025 (advance payment for Q4)
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.09.2025'
)
)
else:
self.stdout.write(
self.style.SUCCESS(
f'Successfully updated {updated_count} payment due dates to September 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('\nAdvance payment schedule (payments made in advance):')
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')