feat(partner,bibliothek): Subunternehmer-Katalog, Dienstleistertypen und Bibliothek (WP-0010)
Implementiert Subunternehmer-Katalog mit Suche/Filter, Zuordnung zu Losen via HTMX-Modal, Dienstleistertyp-CRUD und Präferenz-Badges. Bibliothek: Nachweis-Katalog mit Ablaufwarnung und Versionierung, Referenz-Katalog mit Ausschreibungszuordnung, Leistungsblatt-CRUD, Entscheidungsregel-CRUD mit Aktiv-Toggle. Migration für referenzen M2M auf Ausschreibung. 56 Tests grün. Tests-Discovery auf tests.py-Dateien ausgedehnt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
ca8818254b
commit
278cc1014c
31 changed files with 1818 additions and 22 deletions
|
|
@ -0,0 +1,42 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{% if obj %}Bearbeiten{% else %}Neue Entscheidungsregel{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="max-w-2xl">
|
||||
<h1 class="page-title mb-6">{% if obj %}{{ obj.regelname }} bearbeiten{% else %}Neue Entscheidungsregel{% endif %}</h1>
|
||||
|
||||
<form method="post" class="space-y-4">
|
||||
{% csrf_token %}
|
||||
<div class="card space-y-4">
|
||||
<div><label class="form-label">Regelname *</label>{{ form.regelname }}</div>
|
||||
<div><label class="form-label">Beschreibung</label>{{ form.beschreibung }}</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div><label class="form-label">Kategorie *</label>{{ form.kategorie }}</div>
|
||||
<div><label class="form-label">Gewichtung</label>{{ form.gewichtung }}</div>
|
||||
</div>
|
||||
<div><label class="form-label">Bewertungslogik</label>{{ form.bewertungslogik }}</div>
|
||||
<div><label class="form-label">Schwellenwert</label>{{ form.schwellenwert }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card space-y-4">
|
||||
<h2 class="section-title">Empfehlung</h2>
|
||||
<div class="flex gap-4">{{ form.empfehlung }}</div>
|
||||
<div><label class="form-label">Begründung</label>{{ form.begruendung }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card space-y-4">
|
||||
<h2 class="section-title">Gültigkeit</h2>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div><label class="form-label">Gültig von</label>{{ form.gueltig_von }}</div>
|
||||
<div><label class="form-label">Gültig bis</label>{{ form.gueltig_bis }}</div>
|
||||
<div><label class="form-label">Verantwortlicher</label>{{ form.verantwortlicher }}</div>
|
||||
</div>
|
||||
<label class="flex items-center gap-2 text-sm">{{ form.aktiv }} Aktiv</label>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<button type="submit" class="btn-primary">Speichern</button>
|
||||
<a href="{% url 'bibliothek:entscheidungsregeln_liste' %}" class="btn-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Entscheidungsregeln{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="page-title">Entscheidungsregeln</h1>
|
||||
<a href="{% url 'bibliothek:entscheidungsregel_neu' %}" class="btn-primary">+ Neu</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
{% if regeln %}
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-slate-200">
|
||||
<th class="pb-2 font-medium text-slate-600">Regelname</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Kategorie</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Empfehlung</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Aktiv</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for r in regeln %}
|
||||
<tr class="border-b border-slate-100 hover:bg-slate-50">
|
||||
<td class="py-2 font-medium">{{ r.regelname }}</td>
|
||||
<td class="py-2 text-slate-600">{{ r.get_kategorie_display }}</td>
|
||||
<td class="py-2">
|
||||
{% if r.empfehlung == 'teilnehmen' %}<span class="badge-green">Teilnehmen</span>
|
||||
{% elif r.empfehlung == 'nicht_teilnehmen' %}<span class="badge-red">Nicht teilnehmen</span>
|
||||
{% else %}<span class="badge-gray">Prüfen</span>{% endif %}
|
||||
</td>
|
||||
<td class="py-2" id="er-toggle-{{ r.pk }}">
|
||||
<form hx-post="{% url 'bibliothek:er_toggle' pk=r.pk %}"
|
||||
hx-target="#er-toggle-{{ r.pk }}"
|
||||
hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="text-sm {% if r.aktiv %}text-green-600{% else %}text-slate-400{% endif %}">
|
||||
{% if r.aktiv %}✓ Aktiv{% else %}✗ Inaktiv{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<a href="{% url 'bibliothek:entscheidungsregel_bearbeiten' pk=r.pk %}" class="text-slate-400 hover:text-slate-700 text-xs">Bearbeiten</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="text-slate-500 text-sm">Noch keine Entscheidungsregeln angelegt.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{% if obj %}Bearbeiten{% else %}Neues Leistungsblatt{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="max-w-3xl">
|
||||
<h1 class="page-title mb-6">{% if obj %}{{ obj.produktfunktion }} bearbeiten{% else %}Neues Leistungsblatt{% endif %}</h1>
|
||||
|
||||
<form method="post" class="card space-y-4">
|
||||
{% csrf_token %}
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div class="col-span-2"><label class="form-label">Produktfunktion *</label>{{ form.produktfunktion }}</div>
|
||||
<div><label class="form-label">Version</label>{{ form.version }}</div>
|
||||
</div>
|
||||
<div><label class="form-label">Beschreibung</label>{{ form.beschreibung }}</div>
|
||||
<div><label class="form-label">Leistungsumfang</label>{{ form.leistungsumfang }}</div>
|
||||
<div><label class="form-label">Grenzen & Ausschlüsse</label>{{ form.grenzen_ausschluesse }}</div>
|
||||
<div><label class="form-label">Technische Voraussetzungen</label>{{ form.technische_voraussetzungen }}</div>
|
||||
<div><label class="form-label">Typische Nachweise</label>{{ form.typische_nachweise }}</div>
|
||||
<div><label class="form-label">Eigentümer</label>{{ form.eigentuemer }}</div>
|
||||
<div class="flex gap-3 pt-2">
|
||||
<button type="submit" class="btn-primary">Speichern</button>
|
||||
<a href="{% url 'bibliothek:leistungsblaetter_liste' %}" class="btn-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Leistungsblätter{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="page-title">Leistungsblätter</h1>
|
||||
<a href="{% url 'bibliothek:leistungsblatt_neu' %}" class="btn-primary">+ Neu</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
{% if blaetter %}
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-slate-200">
|
||||
<th class="pb-2 font-medium text-slate-600">Produktfunktion</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Version</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Eigentümer</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for b in blaetter %}
|
||||
<tr class="border-b border-slate-100 hover:bg-slate-50">
|
||||
<td class="py-2 font-medium">{{ b.produktfunktion }}</td>
|
||||
<td class="py-2 text-slate-600">{{ b.version }}</td>
|
||||
<td class="py-2 text-slate-600">{{ b.eigentuemer|default:"—" }}</td>
|
||||
<td class="py-2 text-right">
|
||||
<a href="{% url 'bibliothek:leistungsblatt_bearbeiten' pk=b.pk %}" class="text-slate-400 hover:text-slate-700 text-xs">Bearbeiten</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="text-slate-500 text-sm">Noch keine Leistungsblätter angelegt.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
45
vergabe_teilnahme/templates/bibliothek/nachweis_detail.html
Normal file
45
vergabe_teilnahme/templates/bibliothek/nachweis_detail.html
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ nachweis.titel }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-start justify-between mb-5">
|
||||
<div>
|
||||
<h1 class="page-title">{{ nachweis.titel }}</h1>
|
||||
<p class="text-slate-500 text-sm">Version {{ nachweis.version }} · {{ nachweis.get_freigabestatus_display }}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<a href="{% url 'bibliothek:nachweis_version' pk=nachweis.pk %}" class="btn-secondary">Neue Version</a>
|
||||
<a href="{% url 'bibliothek:nachweis_bearbeiten' pk=nachweis.pk %}" class="btn-secondary">Bearbeiten</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div class="card col-span-2 space-y-3">
|
||||
{% if nachweis.kurzbeschreibung %}<p class="text-sm">{{ nachweis.kurzbeschreibung }}</p>{% endif %}
|
||||
{% if nachweis.zugehoerige_standards %}
|
||||
<p class="text-sm"><strong>Standards:</strong> {{ nachweis.zugehoerige_standards }}</p>
|
||||
{% endif %}
|
||||
{% if nachweis.datei %}
|
||||
<p class="text-sm"><a href="{{ nachweis.datei.url }}" class="text-brand-600 hover:underline">Datei herunterladen</a></p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card space-y-2 text-sm">
|
||||
<p><span class="text-slate-500">Gültig ab:</span> {{ nachweis.gueltig_ab|date:"d.m.Y"|default:"—" }}</p>
|
||||
<p><span class="text-slate-500">Gültig bis:</span>
|
||||
{% if nachweis.gueltig_bis %}
|
||||
{% if nachweis.ist_abgelaufen %}<span class="text-red-600 font-medium">{{ nachweis.gueltig_bis|date:"d.m.Y" }} (abgelaufen)</span>
|
||||
{% else %}{{ nachweis.gueltig_bis|date:"d.m.Y" }}{% endif %}
|
||||
{% else %}—{% endif %}
|
||||
</p>
|
||||
<p><span class="text-slate-500">Vertraulichkeit:</span> {{ nachweis.get_vertraulichkeit_display }}</p>
|
||||
<p><span class="text-slate-500">Öffentliche Vergabe:</span> {% if nachweis.fuer_oeffentliche %}Ja{% else %}Nein{% endif %}</p>
|
||||
<p><span class="text-slate-500">Privatwirtschaft:</span> {% if nachweis.fuer_privatwirtschaftliche %}Ja{% else %}Nein{% endif %}</p>
|
||||
{% if nachweis.eigentuemer %}
|
||||
<p><span class="text-slate-500">Eigentümer:</span> {{ nachweis.eigentuemer }}</p>
|
||||
{% endif %}
|
||||
{% if nachweis.letzte_pruefung %}
|
||||
<p><span class="text-slate-500">Letzte Prüfung:</span> {{ nachweis.letzte_pruefung|date:"d.m.Y" }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
58
vergabe_teilnahme/templates/bibliothek/nachweis_form.html
Normal file
58
vergabe_teilnahme/templates/bibliothek/nachweis_form.html
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{% if neue_version %}Neue Version: {{ nachweis.titel }}{% elif nachweis %}Bearbeiten{% else %}Neuer Nachweis{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="max-w-3xl">
|
||||
<h1 class="page-title mb-6">
|
||||
{% if neue_version %}Neue Version: {{ nachweis.titel }}
|
||||
{% elif nachweis %}{{ nachweis.titel }} bearbeiten
|
||||
{% else %}Neuer Nachweis{% endif %}
|
||||
</h1>
|
||||
|
||||
{% if neue_version %}
|
||||
<div class="bg-amber-50 border border-amber-200 rounded p-3 mb-4 text-sm text-amber-800">
|
||||
Der alte Nachweis (Version {{ nachweis.version }}) wird als „ersetzt" markiert.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="space-y-4">
|
||||
{% csrf_token %}
|
||||
<div class="card space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="col-span-2"><label class="form-label">Titel *</label>{{ form.titel }}</div>
|
||||
</div>
|
||||
<div><label class="form-label">Kurzbeschreibung</label>{{ form.kurzbeschreibung }}</div>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div><label class="form-label">Dokumenttyp</label>{{ form.dokumenttyp }}</div>
|
||||
<div><label class="form-label">Kategorie</label>{{ form.kategorie }}</div>
|
||||
<div><label class="form-label">Version</label>{{ form.version }}</div>
|
||||
</div>
|
||||
<div><label class="form-label">Datei</label>{{ form.datei }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card space-y-4">
|
||||
<h2 class="section-title">Gültigkeit & Freigabe</h2>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div><label class="form-label">Gültig ab</label>{{ form.gueltig_ab }}</div>
|
||||
<div><label class="form-label">Gültig bis</label>{{ form.gueltig_bis }}</div>
|
||||
<div><label class="form-label">Letzte Prüfung</label>{{ form.letzte_pruefung }}</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div><label class="form-label">Freigabestatus</label>{{ form.freigabestatus }}</div>
|
||||
<div><label class="form-label">Vertraulichkeit</label>{{ form.vertraulichkeit }}</div>
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<label class="flex items-center gap-2 text-sm">{{ form.fuer_oeffentliche }} Öffentliche Vergabe</label>
|
||||
<label class="flex items-center gap-2 text-sm">{{ form.fuer_privatwirtschaftliche }} Privatwirtschaft</label>
|
||||
</div>
|
||||
<div><label class="form-label">Eigentümer</label>{{ form.eigentuemer }}</div>
|
||||
<div><label class="form-label">Zugehörige Standards</label>{{ form.zugehoerige_standards }}</div>
|
||||
<div><label class="form-label">Sprache</label>{{ form.sprache }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<button type="submit" class="btn-primary">Speichern</button>
|
||||
<a href="{% url 'bibliothek:nachweise_liste' %}" class="btn-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
62
vergabe_teilnahme/templates/bibliothek/nachweis_liste.html
Normal file
62
vergabe_teilnahme/templates/bibliothek/nachweis_liste.html
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Nachweise{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="page-title">Nachweise</h1>
|
||||
<a href="{% url 'bibliothek:nachweis_neu' %}" class="btn-primary">+ Neu</a>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mb-4">
|
||||
<a href="?tab=alle" class="{% if tab == 'alle' %}btn-primary{% else %}btn-secondary{% endif %} btn-sm">Alle</a>
|
||||
<a href="?tab=bald_ablaufend" class="{% if tab == 'bald_ablaufend' %}btn-primary{% else %}btn-secondary{% endif %} btn-sm">Bald ablaufend</a>
|
||||
<a href="?tab=abgelaufen" class="{% if tab == 'abgelaufen' %}btn-primary{% else %}btn-secondary{% endif %} btn-sm">Abgelaufen</a>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
{% if nachweise %}
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-slate-200">
|
||||
<th class="pb-2 font-medium text-slate-600">Titel</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Version</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Gültig bis</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Freigabe</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for n in nachweise %}
|
||||
<tr class="border-b border-slate-100 hover:bg-slate-50">
|
||||
<td class="py-2 font-medium">
|
||||
<a href="{% url 'bibliothek:nachweis_detail' pk=n.pk %}" class="text-brand-600 hover:underline">{{ n.titel }}</a>
|
||||
</td>
|
||||
<td class="py-2 text-slate-600">{{ n.version }}</td>
|
||||
<td class="py-2">
|
||||
{% if n.gueltig_bis %}
|
||||
{% if n.ist_abgelaufen %}
|
||||
<span class="badge-red">{{ n.gueltig_bis|date:"d.m.Y" }}</span>
|
||||
{% elif n.gueltig_bis <= in_60_tagen %}
|
||||
<span class="badge-orange">{{ n.gueltig_bis|date:"d.m.Y" }}</span>
|
||||
{% else %}
|
||||
<span class="text-slate-600">{{ n.gueltig_bis|date:"d.m.Y" }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="text-slate-400">—</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="py-2">
|
||||
<span class="badge-gray">{{ n.get_freigabestatus_display }}</span>
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<a href="{% url 'bibliothek:nachweis_bearbeiten' pk=n.pk %}" class="text-slate-400 hover:text-slate-700 text-xs mr-2">Bearbeiten</a>
|
||||
<a href="{% url 'bibliothek:nachweis_version' pk=n.pk %}" class="text-slate-400 hover:text-slate-700 text-xs">Neue Version</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="text-slate-500 text-sm">Keine Nachweise gefunden.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<form hx-post="{% url 'bibliothek:er_toggle' pk=obj.pk %}"
|
||||
hx-target="closest td"
|
||||
hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="text-sm {% if obj.aktiv %}text-green-600{% else %}text-slate-400{% endif %}">
|
||||
{% if obj.aktiv %}✓ Aktiv{% else %}✗ Inaktiv{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<div>
|
||||
<div class="mb-3">
|
||||
<input type="text" name="q" value="{{ q }}" class="form-input w-full"
|
||||
placeholder="Referenz suchen (Titel, Branche)..."
|
||||
hx-get="{% url 'bibliothek:referenz_zuordnen' ausschreibung_id=ausschreibung.pk %}"
|
||||
hx-target="closest div"
|
||||
hx-trigger="input changed delay:300ms"
|
||||
hx-include="[name='q']">
|
||||
</div>
|
||||
|
||||
{% if referenzen %}
|
||||
<ul class="space-y-1 max-h-80 overflow-y-auto">
|
||||
{% for ref in referenzen %}
|
||||
<li class="flex items-start justify-between p-2 rounded border border-slate-100 hover:bg-slate-50">
|
||||
<div>
|
||||
<p class="font-medium text-sm">{{ ref.referenztitel|truncatechars:60 }}</p>
|
||||
<p class="text-xs text-slate-500">{{ ref.kunde }} · {{ ref.branche|default:"" }}</p>
|
||||
{% if ref.freigabestatus_verwendung == 'eingeschraenkt' %}
|
||||
<p class="text-xs text-amber-700">⚠ Eingeschränkte Verwendung: {{ ref.einschraenkungen_verwendung|truncatechars:60 }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<form method="post" action="{% url 'bibliothek:referenz_zuordnen' ausschreibung_id=ausschreibung.pk %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="referenz_id" value="{{ ref.pk }}">
|
||||
<button type="submit" class="btn-primary btn-sm">Zuordnen</button>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="text-slate-500 text-sm">Keine Referenzen gefunden.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
67
vergabe_teilnahme/templates/bibliothek/referenz_detail.html
Normal file
67
vergabe_teilnahme/templates/bibliothek/referenz_detail.html
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{{ ref.referenztitel }}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-start justify-between mb-5">
|
||||
<div>
|
||||
<h1 class="page-title">{{ ref.referenztitel }}</h1>
|
||||
<p class="text-slate-500 text-sm">{{ ref.kunde }}{% if ref.branche %} · {{ ref.branche }}{% endif %}</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
{% if ref.whitepaper %}
|
||||
<a href="{{ ref.whitepaper.url }}" class="btn-secondary" download>Whitepaper</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'bibliothek:referenz_bearbeiten' pk=ref.pk %}" class="btn-secondary">Bearbeiten</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div class="card col-span-2 space-y-4">
|
||||
{% if ref.kurzfassung %}
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-1">Kurzfassung</h3>
|
||||
<p class="text-sm text-slate-700">{{ ref.kurzfassung }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ref.leistungsbeschreibung %}
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-1">Leistungsbeschreibung</h3>
|
||||
<p class="text-sm text-slate-700">{{ ref.leistungsbeschreibung }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ref.eingesetzte_produkte %}
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-1">Eingesetzte Produkte</h3>
|
||||
<p class="text-sm text-slate-700">{{ ref.eingesetzte_produkte }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ref.leistungsblaetter.exists %}
|
||||
<div>
|
||||
<h3 class="text-sm font-semibold text-slate-700 mb-1">Leistungsblätter</h3>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{% for lb in ref.leistungsblaetter.all %}
|
||||
<span class="badge-gray">{{ lb.produktfunktion }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="card space-y-2 text-sm">
|
||||
<p><span class="text-slate-500">Projektzeitraum:</span> {{ ref.projektzeitraum|default:"—" }}</p>
|
||||
<p><span class="text-slate-500">Art:</span> {{ ref.oeffentlich_oder_privat|default:"—" }}</p>
|
||||
{% if ref.vertragsvolumen %}
|
||||
<p><span class="text-slate-500">Volumen:</span> {{ ref.vertragsvolumen|floatformat:0 }} €</p>
|
||||
{% endif %}
|
||||
<p><span class="text-slate-500">Freigabe:</span> {{ ref.get_freigabestatus_verwendung_display }}</p>
|
||||
{% if not ref.verwendbar_fuer_ausschreibungen %}
|
||||
<p class="text-red-600">Nicht für Ausschreibungen verwendbar</p>
|
||||
{% endif %}
|
||||
{% if ref.einschraenkungen_verwendung %}
|
||||
<p class="text-amber-700 text-xs">⚠ {{ ref.einschraenkungen_verwendung }}</p>
|
||||
{% endif %}
|
||||
{% if ref.ansprechpartner_referenzkunde %}
|
||||
<p><span class="text-slate-500">Ansprechpartner:</span> {{ ref.ansprechpartner_referenzkunde }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
52
vergabe_teilnahme/templates/bibliothek/referenz_form.html
Normal file
52
vergabe_teilnahme/templates/bibliothek/referenz_form.html
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}{% if ref %}{{ ref.referenztitel }} bearbeiten{% else %}Neue Referenz{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
<div class="max-w-3xl">
|
||||
<h1 class="page-title mb-6">{% if ref %}Bearbeiten{% else %}Neue Referenz{% endif %}</h1>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="space-y-4">
|
||||
{% csrf_token %}
|
||||
<div class="card space-y-4">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="col-span-2"><label class="form-label">Referenztitel *</label>{{ form.referenztitel }}</div>
|
||||
<div><label class="form-label">Kunde *</label>{{ form.kunde }}</div>
|
||||
<div><label class="form-label">Branche</label>{{ form.branche }}</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-3 gap-4">
|
||||
<div><label class="form-label">Art (öffentlich/privat)</label>{{ form.oeffentlich_oder_privat }}</div>
|
||||
<div><label class="form-label">Projektzeitraum</label>{{ form.projektzeitraum }}</div>
|
||||
<div><label class="form-label">Vertragsvolumen (€)</label>{{ form.vertragsvolumen }}</div>
|
||||
</div>
|
||||
<div><label class="form-label">Leistungsbeschreibung</label>{{ form.leistungsbeschreibung }}</div>
|
||||
<div><label class="form-label">Eingesetzte Produkte</label>{{ form.eingesetzte_produkte }}</div>
|
||||
<div><label class="form-label">Ansprechpartner Referenzkunde</label>{{ form.ansprechpartner_referenzkunde }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card space-y-4">
|
||||
<h2 class="section-title">Freigabe & Verwendung</h2>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div><label class="form-label">Freigabestatus</label>{{ form.freigabestatus_verwendung }}</div>
|
||||
<div><label class="form-label">Vertraulichkeit</label>{{ form.vertraulichkeit }}</div>
|
||||
</div>
|
||||
<label class="flex items-center gap-2 text-sm">{{ form.verwendbar_fuer_ausschreibungen }} Verwendbar für Ausschreibungen</label>
|
||||
<div><label class="form-label">Einschränkungen</label>{{ form.einschraenkungen_verwendung }}</div>
|
||||
</div>
|
||||
|
||||
<div class="card space-y-4">
|
||||
<h2 class="section-title">Inhalte & Dokumente</h2>
|
||||
<div><label class="form-label">Kurzfassung</label>{{ form.kurzfassung }}</div>
|
||||
<div><label class="form-label">Langfassung</label>{{ form.langfassung }}</div>
|
||||
<div><label class="form-label">Whitepaper</label>{{ form.whitepaper }}</div>
|
||||
<div>
|
||||
<label class="form-label">Leistungsblätter</label>
|
||||
<div class="mt-1 space-y-1">{{ form.leistungsblaetter }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-3">
|
||||
<button type="submit" class="btn-primary">Speichern</button>
|
||||
<a href="{% url 'bibliothek:referenz_liste' %}" class="btn-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
59
vergabe_teilnahme/templates/bibliothek/referenz_liste.html
Normal file
59
vergabe_teilnahme/templates/bibliothek/referenz_liste.html
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Referenzen{% endblock %}
|
||||
{% block content %}
|
||||
<div class="flex items-center justify-between mb-5">
|
||||
<h1 class="page-title">Referenzen</h1>
|
||||
<a href="{% url 'bibliothek:referenz_neu' %}" class="btn-primary">+ Neu</a>
|
||||
</div>
|
||||
|
||||
<div class="card mb-4">
|
||||
<form method="get" class="flex gap-3 items-end">
|
||||
<div class="flex-1">
|
||||
<label class="form-label">Suche (Titel, Branche, Leistung)</label>
|
||||
<input type="text" name="q" value="{{ q }}" class="form-input w-full" placeholder="Suchen...">
|
||||
</div>
|
||||
<button type="submit" class="btn-secondary">Suchen</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
{% if referenzen %}
|
||||
<table class="w-full text-sm">
|
||||
<thead>
|
||||
<tr class="text-left border-b border-slate-200">
|
||||
<th class="pb-2 font-medium text-slate-600">Referenz</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Kunde</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Branche</th>
|
||||
<th class="pb-2 font-medium text-slate-600">Freigabe</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ref in referenzen %}
|
||||
<tr class="border-b border-slate-100 hover:bg-slate-50">
|
||||
<td class="py-2 font-medium">
|
||||
<a href="{% url 'bibliothek:referenz_detail' pk=ref.pk %}" class="text-brand-600 hover:underline">{{ ref.referenztitel|truncatechars:60 }}</a>
|
||||
</td>
|
||||
<td class="py-2 text-slate-600">{{ ref.kunde }}</td>
|
||||
<td class="py-2 text-slate-600">{{ ref.branche|default:"—" }}</td>
|
||||
<td class="py-2">
|
||||
{% if ref.freigabestatus_verwendung == 'freigegeben' %}
|
||||
<span class="badge-green">Freigegeben</span>
|
||||
{% elif ref.freigabestatus_verwendung == 'eingeschraenkt' %}
|
||||
<span class="badge-orange">Eingeschränkt</span>
|
||||
{% else %}
|
||||
<span class="badge-red">Nicht freigegeben</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="py-2 text-right">
|
||||
<a href="{% url 'bibliothek:referenz_bearbeiten' pk=ref.pk %}" class="text-slate-400 hover:text-slate-700 text-xs">Bearbeiten</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p class="text-slate-500 text-sm">Keine Referenzen gefunden.</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue