add internal rentals with zero deposit

This commit is contained in:
2025-10-30 14:05:53 +01:00
parent 4a7076b120
commit 5d2a052c1e
3 changed files with 192 additions and 191 deletions

View File

@@ -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)

View File

@@ -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")

View File

@@ -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