Coverage for website/pizzas/admin.py: 70.59%
71 statements
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
« prev ^ index » next coverage.py v7.6.7, created at 2025-08-14 10:31 +0000
1from functools import partial
3from django.contrib import admin
4from django.core.exceptions import PermissionDenied
5from django.forms import Field
6from django.urls import path, reverse
7from django.utils.html import format_html
8from django.utils.translation import gettext_lazy as _
10from events import services
11from events.services import is_organiser
12from payments.widgets import PaymentWidget
13from pizzas import admin_views
14from utils.admin import DoNextModelAdmin
16from .models import FoodEvent, FoodOrder, Product
19@admin.register(Product)
20class ProductAdmin(admin.ModelAdmin):
21 """Manage the products."""
23 list_display = ("name", "price", "available")
24 list_filter = ("available", "restricted")
25 search_fields = ("name",)
28@admin.register(FoodEvent)
29class FoodEventAdmin(admin.ModelAdmin):
30 """Manage the pizza events."""
32 list_display = ("title", "start", "end", "notification_enabled", "orders")
33 date_hierarchy = "start"
34 search_fields = ("event__title",)
35 autocomplete_fields = ("event",)
37 def notification_enabled(self, obj):
38 return obj.send_notification
40 notification_enabled.short_description = _("reminder")
41 notification_enabled.admin_order_field = "send_notification"
42 notification_enabled.boolean = True
44 def has_change_permission(self, request, obj=None):
45 """Only allow access to the change form if the user is an organiser."""
46 if obj is not None and not services.is_organiser(request.member, obj.event): 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 return False
48 return super().has_change_permission(request, obj)
50 def has_delete_permission(self, request, obj=None):
51 """Only allow access to delete if the user is an organiser."""
52 if obj is not None and not services.is_organiser(request.member, obj.event): 52 ↛ 53line 52 didn't jump to line 53 because the condition on line 52 was never true
53 return False
54 return super().has_delete_permission(request, obj)
56 def orders(self, obj):
57 url = reverse("admin:pizzas_foodevent_details", kwargs={"pk": obj.pk})
58 return format_html('<a href="{url}">{text}</a>', url=url, text=_("Orders"))
60 def get_urls(self):
61 urls = super().get_urls()
62 custom_urls = [
63 path(
64 "<int:pk>/details/",
65 self.admin_site.admin_view(
66 admin_views.PizzaOrderDetails.as_view(admin=self)
67 ),
68 name="pizzas_foodevent_details",
69 ),
70 path(
71 "<int:pk>/overview/",
72 self.admin_site.admin_view(
73 admin_views.PizzaOrderSummary.as_view(admin=self)
74 ),
75 name="pizzas_foodevent_overview",
76 ),
77 ]
78 return custom_urls + urls
81@admin.register(FoodOrder)
82class FoodOrderAdmin(DoNextModelAdmin):
83 """Manage the orders."""
85 list_display = (
86 "food_event",
87 "member_first_name",
88 "member_last_name",
89 "product",
90 "payment",
91 )
93 fields = (
94 "food_event",
95 "member",
96 "name",
97 "product",
98 "payment",
99 )
101 def get_form(self, request, obj=None, **kwargs):
102 return super().get_form(
103 request,
104 obj,
105 formfield_callback=partial(
106 self.formfield_for_dbfield, request=request, obj=obj
107 ),
108 **kwargs,
109 )
111 def formfield_for_dbfield(self, db_field, request, obj=None, **kwargs):
112 """Payment field widget."""
113 field = super().formfield_for_dbfield(db_field, request, **kwargs)
114 if db_field.name == "payment":
115 return Field(
116 widget=PaymentWidget(obj=obj),
117 initial=field.initial,
118 required=False,
119 )
120 return field
122 def save_model(self, request, obj, form, change):
123 """You can only save the orders if you have permission."""
124 if not is_organiser(request.member, obj.food_event.event):
125 raise PermissionDenied
126 return super().save_model(request, obj, form, change)
128 def has_view_permission(self, request, obj=None):
129 """Only give view permission if the user is an organiser."""
130 if obj is not None and not is_organiser(request.member, obj.food_event.event): 130 ↛ 131line 130 didn't jump to line 131 because the condition on line 130 was never true
131 return False
132 return super().has_view_permission(request, obj)
134 def has_change_permission(self, request, obj=None):
135 """Only give change permission if the user is an organiser."""
136 if obj is not None and not is_organiser(request.member, obj.food_event.event): 136 ↛ 137line 136 didn't jump to line 137 because the condition on line 136 was never true
137 return False
138 return super().has_change_permission(request, obj)
140 def has_delete_permission(self, request, obj=None):
141 """Only give delete permission if the user is an organiser."""
142 if obj is not None and not is_organiser(request.member, obj.food_event.event): 142 ↛ 143line 142 didn't jump to line 143 because the condition on line 142 was never true
143 return False
144 return super().has_delete_permission(request, obj)