generated from coulomb/repo-seed
196 lines
6.6 KiB
Python
196 lines
6.6 KiB
Python
from datetime import date, timedelta
|
|
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
|
from django.utils import timezone
|
|
|
|
from vergabe_teilnahme.apps.accounts.models import Mitarbeiter
|
|
|
|
from .models import Ausschreibung
|
|
|
|
|
|
def _is_htmx(request):
|
|
return request.headers.get('HX-Request') == 'true'
|
|
|
|
|
|
def dashboard(request):
|
|
from vergabe_teilnahme.apps.aufgaben.models import Aufgabe
|
|
|
|
heute = date.today()
|
|
in_14_tagen = heute + timedelta(days=14)
|
|
|
|
ctx = {
|
|
'kritische_fristen': Ausschreibung.objects.filter(
|
|
abgabe_bis__date__lte=in_14_tagen,
|
|
abgabe_bis__date__gte=heute,
|
|
status__lt=10,
|
|
).order_by('abgabe_bis')[:10],
|
|
|
|
'ohne_entscheidung': Ausschreibung.objects.filter(
|
|
teilnahmeentscheidung='offen',
|
|
erstellt_am__lte=timezone.now() - timedelta(days=3),
|
|
status__lt=10,
|
|
).order_by('erstellt_am')[:10],
|
|
|
|
'ueberfaellige_aufgaben': Aufgabe.objects.filter(
|
|
frist__lt=heute,
|
|
status__in=['offen', 'in_bearbeitung', 'wartend_intern', 'wartend_sub', 'wartend_ausschreiber'],
|
|
).select_related('ausschreibung').order_by('frist')[:15],
|
|
|
|
'laufende_ausschreibungen': Ausschreibung.objects.filter(
|
|
status__range=(1, 9),
|
|
).order_by('-geaendert_am')[:10],
|
|
|
|
'breadcrumbs': [{'label': 'Übersicht', 'url': None}],
|
|
}
|
|
return render(request, 'ausschreibungen/dashboard.html', ctx)
|
|
|
|
|
|
def ausschreibung_liste(request):
|
|
qs = Ausschreibung.objects.all()
|
|
|
|
status_filter = request.GET.get('status')
|
|
if status_filter:
|
|
qs = qs.filter(status=status_filter)
|
|
|
|
archiviert = request.GET.get('archiviert', '0') == '1'
|
|
qs = qs.filter(archiviert=archiviert)
|
|
|
|
bid_manager_filter = request.GET.get('bid_manager')
|
|
if bid_manager_filter:
|
|
qs = qs.filter(bid_manager=bid_manager_filter)
|
|
|
|
qs = qs.select_related('bid_manager').order_by('-geaendert_am')
|
|
|
|
ctx = {
|
|
'ausschreibungen': qs,
|
|
'status_choices': Ausschreibung.STATUS_CHOICES,
|
|
'mitarbeiter': Mitarbeiter.objects.all(),
|
|
'archiviert': archiviert,
|
|
'current_status': status_filter or '',
|
|
'current_bid_manager': bid_manager_filter or '',
|
|
'breadcrumbs': [{'label': 'Ausschreibungen', 'url': None}],
|
|
}
|
|
|
|
if _is_htmx(request):
|
|
return render(request, 'ausschreibungen/liste_partial.html', ctx)
|
|
return render(request, 'ausschreibungen/liste.html', ctx)
|
|
|
|
|
|
def ausschreibung_neu(request):
|
|
from .forms import AusschreibungForm
|
|
|
|
historisch = request.GET.get('historisch') == '1'
|
|
if request.method == 'POST':
|
|
form = AusschreibungForm(request.POST)
|
|
if form.is_valid():
|
|
a = form.save()
|
|
return redirect('ausschreibungen:detail', pk=a.pk)
|
|
else:
|
|
form = AusschreibungForm()
|
|
|
|
return render(request, 'ausschreibungen/form.html', {
|
|
'form': form,
|
|
'historisch': historisch,
|
|
'titel': 'Neue Ausschreibung',
|
|
'breadcrumbs': [
|
|
{'label': 'Ausschreibungen', 'url': '/ausschreibungen/'},
|
|
{'label': 'Neu', 'url': None},
|
|
],
|
|
})
|
|
|
|
|
|
def ausschreibung_detail(request, pk):
|
|
from vergabe_teilnahme.apps.core.services import build_phase_nav, get_deadline_warnings
|
|
|
|
a = get_object_or_404(Ausschreibung, pk=pk)
|
|
ctx = {
|
|
'ausschreibung': a,
|
|
'ausschreibung_id': pk,
|
|
'phases': build_phase_nav(a),
|
|
'warnungen': get_deadline_warnings(a),
|
|
'breadcrumbs': [
|
|
{'label': 'Ausschreibungen', 'url': '/ausschreibungen/'},
|
|
{'label': a.titel, 'url': None},
|
|
],
|
|
}
|
|
return render(request, 'ausschreibungen/detail.html', ctx)
|
|
|
|
|
|
def ausschreibung_bearbeiten(request, pk):
|
|
from .forms import AusschreibungForm
|
|
|
|
a = get_object_or_404(Ausschreibung, pk=pk)
|
|
form = AusschreibungForm(request.POST or None, instance=a)
|
|
if request.method == 'POST' and form.is_valid():
|
|
form.save()
|
|
return redirect('ausschreibungen:detail', pk=pk)
|
|
return render(request, 'ausschreibungen/form.html', {
|
|
'form': form,
|
|
'titel': 'Ausschreibung bearbeiten',
|
|
'ausschreibung': a,
|
|
'breadcrumbs': [
|
|
{'label': 'Ausschreibungen', 'url': '/ausschreibungen/'},
|
|
{'label': a.titel, 'url': f'/ausschreibungen/{pk}/'},
|
|
{'label': 'Bearbeiten', 'url': None},
|
|
],
|
|
})
|
|
|
|
|
|
def ausschreibung_status(request, pk):
|
|
a = get_object_or_404(Ausschreibung, pk=pk)
|
|
if request.method == 'POST':
|
|
neuer_status = request.POST.get('status')
|
|
if neuer_status and neuer_status.isdigit():
|
|
a.status = int(neuer_status)
|
|
a.save(update_fields=['status', 'geaendert_am'])
|
|
return render(request, 'ausschreibungen/partials/status_widget.html', {'ausschreibung': a})
|
|
|
|
|
|
def ausschreibung_entscheidung(request, pk):
|
|
from .services import entscheidungsregel_auswertung
|
|
|
|
a = get_object_or_404(Ausschreibung, pk=pk)
|
|
if request.method == 'POST':
|
|
a.teilnahmeentscheidung = request.POST.get('teilnahmeentscheidung', 'offen')
|
|
a.entscheidungsbegruendung = request.POST.get('begruendung', a.entscheidungsbegruendung)
|
|
if a.teilnahmeentscheidung in ['teilnahme', 'ablehnung']:
|
|
a.status = max(a.status, 3)
|
|
a.save()
|
|
return redirect('ausschreibungen:detail', pk=pk)
|
|
|
|
from vergabe_teilnahme.apps.lose.models import Anforderung
|
|
ausschlusskriterien = Anforderung.objects.filter(
|
|
ausschreibung=a,
|
|
ausschlusskriterium=True,
|
|
erfuellungsstatus='nicht_erfuellbar',
|
|
).select_related('los')
|
|
|
|
ctx = {
|
|
'ausschreibung': a,
|
|
'regelergebnis': entscheidungsregel_auswertung(a),
|
|
'ausschlusskriterien_nicht_erfuellbar': ausschlusskriterien,
|
|
'breadcrumbs': [
|
|
{'label': 'Ausschreibungen', 'url': '/ausschreibungen/'},
|
|
{'label': a.titel, 'url': f'/ausschreibungen/{pk}/'},
|
|
{'label': 'Teilnahmeentscheidung', 'url': None},
|
|
],
|
|
}
|
|
return render(request, 'ausschreibungen/entscheidung.html', ctx)
|
|
|
|
|
|
def ausschreibung_archivieren(request, pk):
|
|
a = get_object_or_404(Ausschreibung, pk=pk)
|
|
if request.method == 'POST':
|
|
a.archiviert = True
|
|
a.status = 13
|
|
a.save(update_fields=['archiviert', 'status', 'geaendert_am'])
|
|
return redirect('ausschreibungen:liste')
|
|
return render(request, 'ausschreibungen/archivieren_confirm.html', {
|
|
'ausschreibung': a,
|
|
'breadcrumbs': [
|
|
{'label': 'Ausschreibungen', 'url': '/ausschreibungen/'},
|
|
{'label': a.titel, 'url': f'/ausschreibungen/{pk}/'},
|
|
{'label': 'Archivieren', 'url': None},
|
|
],
|
|
})
|