generated from coulomb/repo-seed
5.4 KiB
5.4 KiB
id, title, status, phase, created, depends_on
| id | title | status | phase | created | depends_on |
|---|---|---|---|---|---|
| WP-0006 | Aufgaben und Bieterfragen | done | 6-of-12 | 2026-05-08 | WP-0005 |
WP-0006 — Aufgaben und Bieterfragen
Implementiert alle Views für Aufgaben (UC-AU-01 bis UC-AU-04) und Bieterfragen (UC-BF-01 bis UC-BF-03) inklusive globaler Aufgabenliste und Fristwarnung.
id: WP-0006-T01
title: Aufgabenliste pro Ausschreibung und globale Liste (UC-OV-03, UC-AU-01)
status: done
`aufgaben/views.py` — aufgaben_liste:
**Pro Ausschreibung** (`/ausschreibungen/<id>/aufgaben/`):
Zeigt alle Aufgaben dieser Ausschreibung, filterbar nach Status, Typ, Verantwortlicher.
Template `aufgaben/liste.html` — Tabelle mit: Titel, Typ-Badge, Priorität, Frist (rot wenn überfällig),
Verantwortlicher, Status-Badge, Inline-Status-Dropdown.
**Globale Liste** (`/aufgaben/`):
Gleiche View mit `ausschreibung_id=None`. Zusätzlicher Filter: "Nur meine Aufgaben"
(request.user als Verantwortlicher).
Zeigt zusätzliche Spalte "Ausschreibung" mit Link.
`Aufgabe.objects.filter(frist__lt=today, status__in=AKTIVE_STATUS)`:
Vor dem Rendering: Update alle überfälligen Aufgaben via `update()` auf status='ueberfaellig'.
(Kein Celery nötig — wird beim Seitenaufruf der Liste getriggert.)
URL in `aufgaben/urls.py`:
```python
path('', views.aufgaben_liste, name='liste'),
Globale URL in Haupt-urls.py: path('aufgaben/', include('vergabe_teilnahme.apps.aufgaben.urls'))
```task
id: WP-0006-T02
title: Aufgabe anlegen und zuweisen (UC-AU-01)
status: done
`AufgabeForm(ModelForm)`:
- `typ` als Select, `prioritaet` als Radio (Hoch/Mittel/Niedrig)
- `frist` als DateInput type="date"
- `los`, `anforderung`, `bieterfrage` als optionale Selects (gefiltert auf aktuelle Ausschreibung)
`aufgabe_neu (POST)`: Bei HTMX-Request gibt es die neue Tabellenzeile zurück
(kein Full-Page-Reload). Sonst Redirect zu Aufgabenliste.
`aufgabe_bearbeiten`: Gleiche Form mit `instance`.
`aufgabe_loeschen (POST)`: Setzt status='verworfen' statt hartem Delete.
`aufgabe_detail`: Zeigt alle Felder, verknüpfte Anforderung/Bieterfrage, Ergebnisfeld.
id: WP-0006-T03
title: Aufgabenstatus inline ändern und Ergebnis dokumentieren (UC-AU-03)
status: done
**Status-Widget** (analog zum Ausschreibungs-Status-Widget):
Jede Zeile in der Aufgabenliste enthält ein Status-Dropdown:
```html
<select name="status"
hx-post="{% url 'aufgaben:status' ausschreibung.pk aufgabe.pk %}"
hx-target="closest tr"
hx-swap="outerHTML"
class="form-input text-xs">
{% for val, label in Aufgabe.STATUS_CHOICES %}
<option value="{{ val }}" {% if val == aufgabe.status %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
Bei Status-Wechsel auf 'erledigt': HTMX-Response zeigt zusätzlich ein Ergebnis-Eingabefeld inline. Nutzer kann Ergebnis eintragen und separat abspeichern.
aufgabe_status (POST): Aktualisiert Status, gibt einzelne Tabellenzeile zurück.
aufgabe_ergebnis (POST): Speichert Ergebnistext.
```task
id: WP-0006-T04
title: Bieterfragen-Liste und Bieterfrage anlegen (UC-BF-01, UC-BF-02)
status: done
`aufgaben/views.py` — bieterfragen_liste und bieterfrage_neu:
Template `aufgaben/bieterfragen_liste.html`:
- Fristwarnung oben: "Bieterfragen bis: <Datum> — noch X Tage" (roter/gelber Banner)
- Filter: Status, Priorität, Verantwortlicher
- Tabelle: Frage (gekürzt), Status-Badge, Priorität, Einreichungsdatum, Verantwortlicher
`BieterfragenForm(ModelForm)`:
`frage` als Textarea, `hintergrund` als Textarea,
`anforderung` + `dokument` als optionale Selects.
bieterfrage_neu: Kann aus Anforderung vorausgefüllt werden (GET-Parameter `anforderung_id`).
bieterfrage_detail: Zeigt Frage, Hintergrund, verknüpfte Anforderung, Status-Timeline.
URLs in `aufgaben/bieterfragen_urls.py`:
```python
path('', views.bieterfragen_liste, name='liste'),
path('neu/', views.bieterfrage_neu, name='neu'),
path('<int:pk>/', views.bieterfrage_detail, name='detail'),
path('<int:pk>/status/', views.bieterfrage_status, name='status'),
path('<int:pk>/antwort/', views.bieterfrage_antwort, name='antwort'),
```task
id: WP-0006-T05
title: Bieterfragen-Workflow und Antwort einarbeiten (UC-BF-03)
status: done
`bieterfrage_status (POST)`: Ermöglicht Status-Wechsel über definierte Übergänge:
entwurf → abgestimmt → eingereicht → beantwortet → eingearbeitet.
Beim Wechsel auf 'eingereicht': Setzt einreichungsdatum=heute (wenn noch nicht gesetzt).
`bieterfrage_antwort (POST)`:
Speichert `antwort`, `auswirkung_angebot`.
Falls eine Anforderung verknüpft ist: Zeigt Button "Anforderungsstatus aktualisieren" →
Weiterleitung zur Anforderungsdetailseite mit vorausgefülltem Erfüllungsstatus.
Auf der Bieterfragen-Detailseite:
- Status-Timeline als vertikale Stepper-Darstellung (CSS-only mit Tailwind)
- Antwortformular (erscheint nur bei Status 'eingereicht'/'beantwortet')
- "Einarbeiten"-Checkbox setzt Status direkt auf 'eingearbeitet' und `eingearbeitet=True`
id: WP-0006-T06
title: Aufgaben- und Bieterfragen-Tests
status: done
`aufgaben/tests/test_views.py`:
- Test: Aufgabenliste gibt 200 zurück
- Test: Neue Aufgabe anlegen → erscheint in Liste
- Test: Status-Wechsel via HTMX → Zeile enthält neuen Status-Badge
- Test: Überfällige Aufgabe → status wird auf 'ueberfaellig' gesetzt bei Listenabruf
- Test: Bieterfrage aus Anforderung vorausgefüllt (GET mit anforderung_id)
- Test: Antwort speichern → antwort-Feld befüllt, Status auf 'beantwortet'