Implement semester-based quarterly tracking system

- Update quarterly confirmation deadlines to semester-based schedule:
  - Q1: March 15 (covers Spring semester Q1+Q2)
  - Q2: June 15 (auto-approved when Q1 approved)
  - Q3: September 15 (covers Fall semester Q3+Q4)
  - Q4: December 15 (auto-approved when Q3 approved)

- Add auto-approval functionality:
  - Q1 approval automatically approves Q2 with same document status
  - Q3 approval automatically approves Q4 with same document status
  - New 'auto_geprueft' status with distinct badge UI

- Maintain quarterly payment cycle while simplifying document submissions
- Remove modal edit functionality, keep full-screen editor only
- Update copilot instructions documentation

Changes align with academic semester system where students submit
documents twice yearly instead of quarterly.
This commit is contained in:
2025-09-30 21:32:12 +02:00
parent ed6a02232e
commit 656af599bb
6 changed files with 140 additions and 144 deletions

View File

@@ -2534,6 +2534,7 @@ class VierteljahresNachweis(models.Model):
("teilweise", "Teilweise eingereicht"),
("eingereicht", "Vollständig eingereicht"),
("geprueft", "Geprüft & Freigegeben"),
("auto_geprueft", "Automatisch freigegeben (Semesterbasis)"),
("nachbesserung", "Nachbesserung erforderlich"),
("abgelehnt", "Abgelehnt"),
]
@@ -2747,14 +2748,14 @@ class VierteljahresNachweis(models.Model):
def save(self, *args, **kwargs):
"""Override save to auto-update status and timestamps"""
# Auto-set deadline if not provided (15th of the quarter's second month)
# Auto-set deadline if not provided (semester-based deadlines)
if not self.faelligkeitsdatum:
from datetime import date
quarter_deadlines = {
1: date(self.jahr, 2, 15), # Q1 deadline: Feb 15
2: date(self.jahr, 5, 15), # Q2 deadline: May 15
3: date(self.jahr, 8, 15), # Q3 deadline: Aug 15
4: date(self.jahr, 11, 15), # Q4 deadline: Nov 15
1: date(self.jahr, 3, 15), # Q1 deadline: March 15 (covers Q1+Q2 semester)
2: date(self.jahr, 6, 15), # Q2 deadline: June 15 (auto-approved if Q1 complete)
3: date(self.jahr, 9, 15), # Q3 deadline: September 15 (covers Q3+Q4 semester)
4: date(self.jahr, 12, 15), # Q4 deadline: December 15 (auto-approved if Q3 complete)
}
self.faelligkeitsdatum = quarter_deadlines.get(self.quartal)
@@ -2824,3 +2825,34 @@ class VierteljahresNachweis(models.Model):
faelligkeitsdatum__lt=today,
status__in=["offen", "teilweise"]
).select_related("destinataer")
def auto_approve_next_quarter(self):
"""Auto-approve the next quarter when Q1 or Q3 is approved (semester-based logic)"""
if self.quartal in [1, 3] and self.status == "geprueft":
next_quarter = self.quartal + 1
try:
next_nachweis = VierteljahresNachweis.objects.get(
destinataer=self.destinataer,
jahr=self.jahr,
quartal=next_quarter
)
if next_nachweis.status in ["offen", "teilweise"]:
# Copy document confirmations from current quarter
next_nachweis.studiennachweis_eingereicht = self.studiennachweis_eingereicht
next_nachweis.einkommenssituation_bestaetigt = self.einkommenssituation_bestaetigt
next_nachweis.vermogenssituation_bestaetigt = self.vermogenssituation_bestaetigt
# Set auto-approved status
next_nachweis.status = "auto_geprueft"
next_nachweis.geprueft_am = timezone.now()
next_nachweis.geprueft_von = self.geprueft_von
next_nachweis.save(update_fields=[
'studiennachweis_eingereicht', 'einkommenssituation_bestaetigt',
'vermogenssituation_bestaetigt', 'status', 'geprueft_am', 'geprueft_von'
])
return next_nachweis
except VierteljahresNachweis.DoesNotExist:
pass
return None