fix(WP-0013): Feedback-Bugs — alle 8 Einträge aus Backlog behoben

- Fristen-Widget-Format: DateInput/DateTimeInput mit ISO-Format-Attribut, damit
  Browser date/datetime-local korrekt vorausfüllen (Feedback #4)
- Phase 2 Teilnahmeentscheidung: URL in build_phase_nav von
  /teilnahmeentscheidung/ → /entscheidung/ korrigiert (Feedback #6)
- Phase 3 Detaillierte Durchsicht: URL in build_phase_nav von
  /anforderungen/ → /lose/anforderungen/ korrigiert (Feedback #7)
- Phase 7 Abgabe: order_by('bezeichnung') → order_by('beschreibung') in
  abgabe_views.py (Dokument hat kein Feld 'bezeichnung') (Feedback #8)
- Ausschreibungen-Liste: Ausschreiber zuerst, Titel zweite Spalte,
  neues geschätztes Volumen (Feedback #5)
- Feedback-Backlog Leerstand: bereits durch vorherigen URL-Fix abgedeckt
  (Feedback #1)
- Rechtsgrundlage (VgV/UVgO/VOB/A/SektVO/GWB) als neues Formularfeld
  incl. Migration (Feedback #2)
- Bindefrist in Tagen + berechnetes Enddatum als Modell-Property
  bindefrist_berechnet, Formular und Detailansicht erweitert (Feedback #3)

68/68 Tests grün.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-05-14 00:31:55 +02:00
parent d6873d7b88
commit 7903f59f85
10 changed files with 240 additions and 14 deletions

View file

@ -1,4 +1,4 @@
from datetime import date
from datetime import date, timedelta
from django.db import models
@ -34,12 +34,21 @@ class Ausschreibung(FlexibleModel):
('rahmenvertrag', 'Rahmenvertrag'),
('sonstige', 'Sonstige'),
]
RECHTSGRUNDLAGE_CHOICES = [
('vgv', 'VgV'),
('uvgo', 'UVgO'),
('vob_a', 'VOB/A'),
('sektvo', 'SektVO'),
('gwb', 'GWB'),
('sonstige', 'Sonstige'),
]
titel = models.CharField(max_length=400)
ausschreiber = models.CharField(max_length=300)
vergabeplattform = models.CharField(max_length=200, blank=True)
vergabenummer = models.CharField(max_length=100, blank=True)
vergabeart = models.CharField(max_length=30, choices=VERGABEART_CHOICES, blank=True)
rechtsgrundlage = models.CharField(max_length=20, choices=RECHTSGRUNDLAGE_CHOICES, blank=True)
status = models.PositiveSmallIntegerField(choices=STATUS_CHOICES, default=1)
teilnahmeentscheidung = models.CharField(
max_length=20, choices=TEILNAHME_CHOICES, default='offen'
@ -51,6 +60,7 @@ class Ausschreibung(FlexibleModel):
bieterfragen_bis = models.DateField(null=True, blank=True)
abgabe_bis = models.DateTimeField(null=True, blank=True)
bindefrist = models.DateField(null=True, blank=True)
bindefrist_tage = models.PositiveSmallIntegerField(null=True, blank=True, help_text='Bindefrist in Tagen ab Abgabe')
# Verantwortlichkeiten
bid_manager = models.ForeignKey(
@ -92,6 +102,15 @@ class Ausschreibung(FlexibleModel):
def __str__(self):
return self.titel
@property
def bindefrist_berechnet(self):
"""Enddatum aus abgabe_bis + bindefrist_tage, falls kein festes bindefrist-Datum."""
if self.bindefrist:
return self.bindefrist
if self.abgabe_bis and self.bindefrist_tage:
return (self.abgabe_bis + timedelta(days=self.bindefrist_tage)).date()
return None
@property
def ist_aktiv(self):
return 1 <= self.status <= 9