from decimal import Decimal from django.contrib.contenttypes.models import ContentType from django.shortcuts import get_object_or_404, redirect, render from vergabe_teilnahme.apps.ausschreibungen.models import Ausschreibung from vergabe_teilnahme.apps.core.models import Freigabe from vergabe_teilnahme.apps.core.services import gewichteter_durchschnitt from .forms import PreispunktForm from .models import Preispunkt def preispunkte_liste(request, ausschreibung_id): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) qs = Preispunkt.objects.filter(ausschreibung=ausschreibung).select_related('los', 'subunternehmer') leistungstyp_filter = request.GET.get('leistungstyp', '').strip() los_filter = request.GET.get('los', '').strip() sub_filter = request.GET.get('subunternehmer', '') if leistungstyp_filter: qs = qs.filter(leistungstyp__icontains=leistungstyp_filter) if los_filter: qs = qs.filter(los_id=los_filter) if sub_filter == 'ja': qs = qs.filter(subunternehmeranteil=True) elif sub_filter == 'nein': qs = qs.filter(subunternehmeranteil=False) summe_gesamt = sum(p.gesamtpreis for p in qs if p.gesamtpreis is not None) from vergabe_teilnahme.apps.lose.models import Los lose = Los.objects.filter(ausschreibung=ausschreibung) leistungstypen = Preispunkt.objects.filter(ausschreibung=ausschreibung).values_list( 'leistungstyp', flat=True ).distinct() ctx = { 'ausschreibung': ausschreibung, 'preispunkte': qs, 'summe_gesamt': summe_gesamt, 'lose': lose, 'leistungstypen': leistungstypen, 'filter': { 'leistungstyp': leistungstyp_filter, 'los': los_filter, 'subunternehmer': sub_filter, }, } return render(request, 'preise/liste.html', ctx) def preispunkt_neu(request, ausschreibung_id): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) form = PreispunktForm(request.POST or None, ausschreibung=ausschreibung) if request.method == 'POST' and form.is_valid(): pp = form.save(commit=False) pp.ausschreibung = ausschreibung pp.save() return redirect('ausschreibungen:preise:liste', ausschreibung_id=ausschreibung_id) leistungstypen = Preispunkt.objects.values_list('leistungstyp', flat=True).distinct() return render(request, 'preise/form.html', { 'ausschreibung': ausschreibung, 'form': form, 'leistungstypen': leistungstypen, 'titel': 'Neuer Preispunkt', }) def preispunkt_detail(request, ausschreibung_id, pk): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) pp = get_object_or_404(Preispunkt, pk=pk, ausschreibung=ausschreibung) ct = ContentType.objects.get_for_model(Preispunkt) freigaben = Freigabe.objects.filter(content_type=ct, object_id=pp.pk) return render(request, 'preise/detail.html', { 'ausschreibung': ausschreibung, 'preispunkt': pp, 'freigaben': freigaben, }) def preispunkt_bearbeiten(request, ausschreibung_id, pk): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) pp = get_object_or_404(Preispunkt, pk=pk, ausschreibung=ausschreibung) form = PreispunktForm(request.POST or None, instance=pp, ausschreibung=ausschreibung) if request.method == 'POST' and form.is_valid(): form.save() return redirect('ausschreibungen:preise:detail', ausschreibung_id=ausschreibung_id, pk=pk) leistungstypen = Preispunkt.objects.values_list('leistungstyp', flat=True).distinct() return render(request, 'preise/form.html', { 'ausschreibung': ausschreibung, 'form': form, 'preispunkt': pp, 'leistungstypen': leistungstypen, 'titel': 'Preispunkt bearbeiten', }) def preispunkt_loeschen(request, ausschreibung_id, pk): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) pp = get_object_or_404(Preispunkt, pk=pk, ausschreibung=ausschreibung) if request.method == 'POST': pp.delete() return redirect('ausschreibungen:preise:liste', ausschreibung_id=ausschreibung_id) return render(request, 'preise/loeschen_bestaetigen.html', { 'ausschreibung': ausschreibung, 'preispunkt': pp, }) def leistungstyp_auswertung(request, ausschreibung_id): ausschreibung = get_object_or_404(Ausschreibung, pk=ausschreibung_id) leistungstyp = request.GET.get('leistungstyp', '').strip() filter_gewonnen = request.GET.get('gewonnen') qs = Preispunkt.objects.filter(einzelpreis__isnull=False) if leistungstyp: qs = qs.filter(leistungstyp__icontains=leistungstyp) if filter_gewonnen == 'ja': qs = qs.filter(ausschreibung_gewonnen=True) elif filter_gewonnen == 'nein': qs = qs.filter(ausschreibung_gewonnen=False) ergebnis = gewichteter_durchschnitt(list(qs)) ungewichtet = None if qs.exists(): werte = [p.einzelpreis for p in qs if p.einzelpreis is not None] ungewichtet = sum(werte) / len(werte) if werte else None alle_leistungstypen = Preispunkt.objects.values_list('leistungstyp', flat=True).distinct() return render(request, 'preise/auswertung.html', { 'ausschreibung': ausschreibung, 'leistungstyp': leistungstyp, 'filter_gewonnen': filter_gewonnen, 'ergebnis': ergebnis, 'ungewichtet': ungewichtet, 'preispunkte': qs.order_by('-ausschreibung__erstellt_am'), 'alle_leistungstypen': alle_leistungstypen, }) def globaler_preisvergleich(request): leistungstyp = request.GET.get('leistungstyp', '').strip() filter_gewonnen = request.GET.get('gewonnen', '') von = request.GET.get('von', '') bis = request.GET.get('bis', '') qs = Preispunkt.objects.filter(einzelpreis__isnull=False).select_related('ausschreibung') if leistungstyp: qs = qs.filter(leistungstyp__icontains=leistungstyp) if filter_gewonnen == 'ja': qs = qs.filter(ausschreibung_gewonnen=True) elif filter_gewonnen == 'nein': qs = qs.filter(ausschreibung_gewonnen=False) if von: qs = qs.filter(preisstand__gte=von) if bis: qs = qs.filter(preisstand__lte=bis) ergebnis = gewichteter_durchschnitt(list(qs)) ungewichtet = None if qs.exists(): werte = [p.einzelpreis for p in qs if p.einzelpreis is not None] ungewichtet = sum(werte) / len(werte) if werte else None gewonnen_punkte = list(qs.filter(ausschreibung_gewonnen=True)) verloren_punkte = list(qs.filter(ausschreibung_gewonnen=False)) ergebnis_gewonnen = gewichteter_durchschnitt(gewonnen_punkte) if gewonnen_punkte else None ergebnis_verloren = gewichteter_durchschnitt(verloren_punkte) if verloren_punkte else None alle_leistungstypen = Preispunkt.objects.values_list('leistungstyp', flat=True).distinct() return render(request, 'preise/globaler_vergleich.html', { 'leistungstyp': leistungstyp, 'filter_gewonnen': filter_gewonnen, 'von': von, 'bis': bis, 'ergebnis': ergebnis, 'ungewichtet': ungewichtet, 'ergebnis_gewonnen': ergebnis_gewonnen, 'ergebnis_verloren': ergebnis_verloren, 'preispunkte': qs.order_by('-ausschreibung__erstellt_am'), 'alle_leistungstypen': alle_leistungstypen, }) def preisfreigabe(request, ausschreibung_id): return redirect('ausschreibungen:preise:liste', ausschreibung_id=ausschreibung_id)