add detailview, mail sending and new db values
This commit is contained in:
@@ -14,9 +14,14 @@ class RentalAdmin(admin.ModelAdmin):
|
||||
"firstname",
|
||||
"surname",
|
||||
"status",
|
||||
"total_disposit",
|
||||
"date_start",
|
||||
"date_end",
|
||||
]
|
||||
ordering = ["-id"]
|
||||
|
||||
readonly_fields = ["total_disposit"]
|
||||
|
||||
fieldsets = (
|
||||
(
|
||||
"Persönliche Daten",
|
||||
@@ -35,6 +40,7 @@ class RentalAdmin(admin.ModelAdmin):
|
||||
("date_start", "date_end"),
|
||||
"reason",
|
||||
"rentalitems",
|
||||
"total_disposit",
|
||||
),
|
||||
},
|
||||
),
|
||||
@@ -63,12 +69,22 @@ class RentalAdmin(admin.ModelAdmin):
|
||||
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."
|
||||
|
||||
@@ -12,14 +12,7 @@ class RentalCreateForm(forms.ModelForm):
|
||||
# Conformation
|
||||
conformation = forms.BooleanField(
|
||||
required=True,
|
||||
label=(
|
||||
"1. Fachschaft Elektrotechnik (FET) hat stets Vorrecht. 2. Bereits bestätigte Objekte "
|
||||
"können storniert werden, falls FET sie selber braucht. 3. Sachen dürfen nur über das "
|
||||
"Verleihsystem verborgt werden. 4. Objekte müssen pünktlich und gereinigt retouniert "
|
||||
"werden. 5. Verleihpersonen entscheiden über Kaution (lediglich für Pünktlichkeit und "
|
||||
"Reinheit) 6. Geht was kaputt, muss dies umgehend mitgeteilt werden und finanziell "
|
||||
"dafür aufgekommen werden. "
|
||||
),
|
||||
label=("Ich habe die Verleihregeln gelesen und akzeptiere sie."),
|
||||
initial=False,
|
||||
)
|
||||
|
||||
|
||||
39
fet2020/rental/mails.py
Normal file
39
fet2020/rental/mails.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import logging
|
||||
|
||||
from django.core.mail import send_mail
|
||||
|
||||
RENTAL_EMAIL = "patrick@fet.at"
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def send_mail_approved(obj):
|
||||
subject = f"Verleih #{obj.id}: {obj.get_status_display()}"
|
||||
|
||||
total_deposit = 0
|
||||
for rentalitem in obj.rentalitems.all():
|
||||
total_deposit += rentalitem.deposit
|
||||
|
||||
message = (
|
||||
f"Deine Verleihanfrage mit der Nummer #{obj.id} wurde erfolgreich genehmigt. Die "
|
||||
f"Gegenstände können am {obj.date_start.strftime('%d.%m.%Y')} während der Beratungszeit "
|
||||
"(Montag - Donnerstag: 09:00 - 14:00, Freitag: 09:00 - 12:00) abgeholt werden. Bitte bring "
|
||||
f"den Gesamtpfand in Höhe von {total_deposit} € in bar mit.\nLiebe Grüße,\ndas Verleih-Team"
|
||||
)
|
||||
|
||||
try:
|
||||
send_mail(subject, message, RENTAL_EMAIL, [f"{obj.email}", RENTAL_EMAIL])
|
||||
except Exception as exc:
|
||||
logger.error("Failed to send approval email for rental #%s. Error: %s", obj.id, exc)
|
||||
|
||||
|
||||
def send_mail_rejected(obj):
|
||||
subject = f"Verleih #{obj.id}: {obj.get_status_display()}"
|
||||
message = (
|
||||
f"Deine Verleihanfrage mit der Nummer #{obj.id} wurde abgelehnt.\nLiebe Grüße,\ndas "
|
||||
"Verleih-Team"
|
||||
)
|
||||
|
||||
try:
|
||||
send_mail(subject, message, RENTAL_EMAIL, [f"{obj.email}", RENTAL_EMAIL])
|
||||
except Exception as exc:
|
||||
logger.error("Failed to send rejection email for rental #%s. Error: %s", obj.id, exc)
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.db import models
|
||||
from django.forms import ValidationError
|
||||
|
||||
from .mails import send_mail_approved, send_mail_rejected
|
||||
from .validators import PhoneNumberValidator
|
||||
|
||||
|
||||
@@ -10,6 +11,16 @@ class RentalItem(models.Model):
|
||||
verbose_name="Beschreibung", max_length=128, blank=True, default=""
|
||||
)
|
||||
|
||||
deposit = models.DecimalField(
|
||||
verbose_name="Kaution (EUR)", max_digits=6, decimal_places=2, default=0
|
||||
)
|
||||
|
||||
image = models.ImageField(verbose_name="Bild", upload_to="rentalitems", blank=True, null=True)
|
||||
|
||||
induction = models.BooleanField(verbose_name="Einschulung notwendig", default=False)
|
||||
|
||||
location = models.CharField(verbose_name="Standort", max_length=128, blank=True, default="")
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Verleihgegenstand"
|
||||
verbose_name_plural = "Verleihgegenstände"
|
||||
@@ -63,6 +74,24 @@ class Rental(models.Model):
|
||||
def __str__(self):
|
||||
return f"Verleih #{self.id}: {self.firstname} {self.surname}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
pre_obj = Rental.objects.filter(pk=self.pk).first()
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
if (
|
||||
pre_obj
|
||||
and pre_obj.status != self.Status.APPROVED
|
||||
and self.status == self.Status.APPROVED
|
||||
):
|
||||
send_mail_approved(self)
|
||||
elif (
|
||||
pre_obj
|
||||
and pre_obj.status != self.Status.REJECTED
|
||||
and self.status == self.Status.REJECTED
|
||||
):
|
||||
send_mail_rejected(self)
|
||||
|
||||
def clean(self):
|
||||
if not self.date_end:
|
||||
self.date_end = self.date_start
|
||||
|
||||
BIN
fet2020/rental/static/rental/Verleihregeln.pdf
Normal file
BIN
fet2020/rental/static/rental/Verleihregeln.pdf
Normal file
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
from django.urls import path
|
||||
|
||||
from . import apps
|
||||
from .views import RentalCreateDoneView, RentalCreateView, RentalListView
|
||||
from .views import RentalCreateDoneView, RentalCreateView, RentalItemDetailView, RentalListView
|
||||
|
||||
app_name = apps.RentalConfig.name
|
||||
|
||||
@@ -13,4 +13,5 @@ urlpatterns = [
|
||||
RentalCreateDoneView.as_view(),
|
||||
name="rental_create_done",
|
||||
),
|
||||
path("rentalitems/<int:pk>/", RentalItemDetailView.as_view(), name="rentalitem_detail"),
|
||||
]
|
||||
|
||||
@@ -4,6 +4,7 @@ import datetime
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
from django.views.generic import ListView, TemplateView
|
||||
from django.views.generic.detail import DetailView
|
||||
from django.views.generic.edit import CreateView
|
||||
|
||||
from .forms import RentalCreateForm
|
||||
@@ -150,3 +151,22 @@ class RentalCreateView(CreateView):
|
||||
|
||||
class RentalCreateDoneView(TemplateView):
|
||||
template_name = "rental/create_done.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
|
||||
obj = Rental.objects.get(pk=self.kwargs["pk"])
|
||||
|
||||
total_deposit = 0
|
||||
for elem in obj.rentalitems.all():
|
||||
total_deposit += elem.deposit
|
||||
|
||||
context["object"] = obj
|
||||
context["total_deposit"] = total_deposit
|
||||
|
||||
return context
|
||||
|
||||
|
||||
class RentalItemDetailView(DetailView):
|
||||
model = RentalItem
|
||||
template_name = "rental/rentalitem_detail.html"
|
||||
|
||||
Reference in New Issue
Block a user