From 5d2a052c1e14e079e4337ed3134b350196273e99 Mon Sep 17 00:00:00 2001 From: Patrick Mayr Date: Thu, 30 Oct 2025 14:05:53 +0100 Subject: [PATCH] add internal rentals with zero deposit --- fet2020/rental/admin.py | 250 ++++++++++++++++++++------------------- fet2020/rental/models.py | 3 +- fet2020/rental/utils.py | 130 ++++++++++---------- 3 files changed, 192 insertions(+), 191 deletions(-) diff --git a/fet2020/rental/admin.py b/fet2020/rental/admin.py index 42227a1d..b8f60b8a 100644 --- a/fet2020/rental/admin.py +++ b/fet2020/rental/admin.py @@ -1,124 +1,126 @@ -from django.contrib import admin, messages -from django.http import HttpResponseRedirect - -from .forms import RentalAdminForm, RentalItemAdminForm -from .models import Rental, RentalItem -from .utils import generate_rental_pdf - - -@admin.register(Rental) -class RentalAdmin(admin.ModelAdmin): - form = RentalAdminForm - model = Rental - - list_display = [ - "id", - "firstname", - "surname", - "status", - "total_disposit", - "date_start", - "date_end", - ] - ordering = ["-id"] - - readonly_fields = ["total_disposit"] - - fieldsets = ( - ( - "Persönliche Daten", - { - "fields": ( - ("firstname", "surname"), - ("organization", "matriculation_number"), - ("email", "phone"), - ), - }, - ), - ( - "Verleih", - { - "fields": ( - ("date_start", "date_end"), - "reason", - "rentalitems", - "total_disposit", - ), - }, - ), - ( - "Sonstiges", - { - "fields": ( - "comment", - "file_field", - "status", - ), - }, - ), - ) - - def add_view(self, request, form_url="", extra_context=None): - extra_context = extra_context or {} - extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." - return super().add_view(request, form_url, extra_context=extra_context) - - def change_view(self, request, object_id, form_url="", extra_context=None): - extra_context = extra_context or {} - extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." - extra_context["generate_rental_pdf"] = True - return super().change_view(request, object_id, form_url, extra_context=extra_context) - - def response_change(self, request, obj): - if "_generate_rental_pdf" in request.POST: - if generate_rental_pdf(obj): - self.message_user( - request, - "Neues Verleihformular wurde generiert.", - messages.SUCCESS, - ) - else: - self.message_user( - request, - ( - "Das PDF-Dokument konnte nicht generiert werden, da der Status nicht auf " - "'Verleih genehmigt' gesetzt ist." - ), - messages.WARNING, - ) - return HttpResponseRedirect(".") - return super().response_change(request, obj) - - def save_model(self, request, obj, form, change): - obj.author = request.user - super().save_model(request, obj, form, change) - - @admin.display(description="Kaution (EUR)") - def total_disposit(self, obj): - total_disposit = 0 - for elem in obj.rentalitems.all(): - total_disposit += elem.deposit - - return f"{total_disposit}" - - -@admin.register(RentalItem) -class RentalItemAdmin(admin.ModelAdmin): - form = RentalItemAdminForm - model = RentalItem - - ordering = ["name"] - - def add_view(self, request, form_url="", extra_context=None): - extra_context = extra_context or {} - extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." - return super().add_view(request, form_url, extra_context=extra_context) - - def change_view(self, request, object_id, form_url="", extra_context=None): - extra_context = extra_context or {} - extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." - return super().change_view(request, object_id, form_url, extra_context=extra_context) - - def save_model(self, request, obj, form, change): - obj.author = request.user - super().save_model(request, obj, form, change) +from django.contrib import admin, messages +from django.http import HttpResponseRedirect + +from .forms import RentalAdminForm, RentalItemAdminForm +from .models import Rental, RentalItem +from .utils import generate_rental_pdf + + +@admin.register(Rental) +class RentalAdmin(admin.ModelAdmin): + form = RentalAdminForm + model = Rental + + list_display = [ + "id", + "firstname", + "surname", + "status", + "total_disposit", + "date_start", + "date_end", + ] + ordering = ["-id"] + + readonly_fields = ["total_disposit"] + + fieldsets = ( + ( + "Persönliche Daten", + { + "fields": ( + ("firstname", "surname"), + ("organization", "matriculation_number"), + ("email", "phone"), + ), + }, + ), + ( + "Verleih", + { + "fields": ( + ("date_start", "date_end"), + "reason", + "rentalitems", + ("total_disposit", "intern"), + ), + }, + ), + ( + "Sonstiges", + { + "fields": ( + "comment", + "file_field", + "status", + ), + }, + ), + ) + + def add_view(self, request, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." + return super().add_view(request, form_url, extra_context=extra_context) + + def change_view(self, request, object_id, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." + extra_context["generate_rental_pdf"] = True + return super().change_view(request, object_id, form_url, extra_context=extra_context) + + def response_change(self, request, obj): + if "_generate_rental_pdf" in request.POST: + if generate_rental_pdf(obj): + self.message_user( + request, + "Neues Verleihformular wurde generiert.", + messages.SUCCESS, + ) + else: + self.message_user( + request, + ( + "Das PDF-Dokument konnte nicht generiert werden, da der Status nicht auf " + "'Verleih genehmigt' gesetzt ist." + ), + messages.WARNING, + ) + return HttpResponseRedirect(".") + return super().response_change(request, obj) + + def save_model(self, request, obj, form, change): + obj.author = request.user + super().save_model(request, obj, form, change) + + @admin.display(description="Kaution (EUR)") + def total_disposit(self, obj): + total_disposit = 0 + + if not obj.intern: + for elem in obj.rentalitems.all(): + total_disposit += elem.deposit + + return f"{total_disposit}" + + +@admin.register(RentalItem) +class RentalItemAdmin(admin.ModelAdmin): + form = RentalItemAdminForm + model = RentalItem + + ordering = ["name"] + + def add_view(self, request, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." + return super().add_view(request, form_url, extra_context=extra_context) + + def change_view(self, request, object_id, form_url="", extra_context=None): + extra_context = extra_context or {} + extra_context["help_text"] = "Fette Schriften sind Pflichtfelder." + return super().change_view(request, object_id, form_url, extra_context=extra_context) + + def save_model(self, request, obj, form, change): + obj.author = request.user + super().save_model(request, obj, form, change) diff --git a/fet2020/rental/models.py b/fet2020/rental/models.py index c57b8b10..6a31d3ab 100644 --- a/fet2020/rental/models.py +++ b/fet2020/rental/models.py @@ -2,7 +2,7 @@ from django.core.validators import FileExtensionValidator from django.db import models from django.forms import ValidationError -from .mails import send_mail_approved, send_mail_rejected +from .mails import send_mail_approved, send_mail_rejected from .managers import RentalItemsManager from .validators import PhoneNumberValidator @@ -44,6 +44,7 @@ class Rental(models.Model): ) organization = models.CharField(verbose_name="Organisation", max_length=128) + intern = models.BooleanField(verbose_name="Interner Verleih", default=False) date_start = models.DateField(verbose_name="Abholdatum") date_end = models.DateField(verbose_name="Rückgabedatum") diff --git a/fet2020/rental/utils.py b/fet2020/rental/utils.py index afd9cf29..72404a63 100644 --- a/fet2020/rental/utils.py +++ b/fet2020/rental/utils.py @@ -1,67 +1,65 @@ -import io - -from django.contrib.staticfiles import finders -from django.core.files import File -from pypdf import PdfReader, PdfWriter - -from .models import Rental - - -def generate_rental_pdf(rental: Rental) -> bool: - if not rental or rental.status != Rental.Status.APPROVED: - return False - - # Get data for pdf - data = {} - data.update( - { - "Vorname": rental.firstname, - "Nachname": rental.surname, - "Orga": rental.organization, - "Matrikelnummer": rental.matriculation_number, - "E-Mail": rental.email, - "Telefonnummer": rental.phone, - # Change to the correct date format - "Abholdatum": str(rental.date_start.strftime("%d.%m.%Y")), - "Rückgabedatum": str(rental.date_end.strftime("%d.%m.%Y")), - }, - ) - - total_deposit = 0 - - for i, item in enumerate(rental.rentalitems.all(), start=1): - total_deposit += item.deposit - data.update( - { - f"Produkt Row{i}": item.name, - f"Menge Row{i}": "1", - f"Kaution Row{i}": item.deposit, - }, - ) - - data.update( - { - "Gesamtkaution": total_deposit, - }, - ) - - # Write data in pdf - pdf_path_str = finders.find("rental/Verleihformular.pdf") - reader = PdfReader(pdf_path_str) - writer = PdfWriter() - writer.append(reader) - - writer.update_page_form_field_values( - writer.pages[0], - data, - ) - - with io.BytesIO() as bytes_stream: +import io + +from django.contrib.staticfiles import finders +from django.core.files import File +from pypdf import PdfReader, PdfWriter + +from .models import Rental + + +def generate_rental_pdf(rental: Rental) -> bool: + if not rental or rental.status != Rental.Status.APPROVED: + return False + + # Get data for pdf + data = {} + data.update( + { + "Vorname": rental.firstname, + "Nachname": rental.surname, + "Orga": rental.organization, + "Matrikelnummer": rental.matriculation_number, + "E-Mail": rental.email, + "Telefonnummer": rental.phone, + # Change to the correct date format + "Abholdatum": str(rental.date_start.strftime("%d.%m.%Y")), + "Rückgabedatum": str(rental.date_end.strftime("%d.%m.%Y")), + }, + ) + + total_deposit = 0 + + for i, item in enumerate(rental.rentalitems.all(), start=1): + if not rental.intern: + total_deposit += item.deposit + + data.update( + { + f"Produkt Row{i}": item.name, + f"Menge Row{i}": "1", + f"Kaution Row{i}": (str(item.deposit) if not rental.intern else "0"), + }, + ) + + data.update({"Gesamtkaution": str(total_deposit)}) + + # Write data in pdf + pdf_path_str = finders.find("rental/Verleihformular.pdf") + reader = PdfReader(pdf_path_str) + writer = PdfWriter() + writer.append(reader) + + writer.update_page_form_field_values( + writer.pages[0], + data, + ) + + with io.BytesIO() as bytes_stream: writer.write(bytes_stream) - bytes_stream.seek(0) - - # Save pdf in rental - rental_name = f"Verleihformular-{str(rental.pk).zfill(4)}.pdf" - rental.file_field.save(rental_name, File(bytes_stream, rental_name)) - - return True + bytes_stream.seek(0) + + # Save pdf in rental + rental_name = f"Verleihformular-{str(rental.pk).zfill(4)}.pdf" + rental.file_field.save(rental_name, File(bytes_stream, rental_name)) + + return True