generated from coulomb/repo-seed
Established workplans
This commit is contained in:
150
workplans/WP-0006-aufgaben-bieterfragen.md
Normal file
150
workplans/WP-0006-aufgaben-bieterfragen.md
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
id: WP-0006
|
||||
title: Aufgaben und Bieterfragen
|
||||
status: todo
|
||||
phase: 6-of-12
|
||||
created: "2026-05-08"
|
||||
depends_on: 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.
|
||||
|
||||
---
|
||||
|
||||
```task
|
||||
id: WP-0006-T01
|
||||
title: Aufgabenliste pro Ausschreibung und globale Liste (UC-OV-03, UC-AU-01)
|
||||
status: todo
|
||||
|
||||
`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: todo
|
||||
|
||||
`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.
|
||||
```
|
||||
|
||||
```task
|
||||
id: WP-0006-T03
|
||||
title: Aufgabenstatus inline ändern und Ergebnis dokumentieren (UC-AU-03)
|
||||
status: todo
|
||||
|
||||
**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: todo
|
||||
|
||||
`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: todo
|
||||
|
||||
`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`
|
||||
```
|
||||
|
||||
```task
|
||||
id: WP-0006-T06
|
||||
title: Aufgaben- und Bieterfragen-Tests
|
||||
status: todo
|
||||
|
||||
`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'
|
||||
```
|
||||
Reference in New Issue
Block a user