shiftregister/shiftregister/app/admin.py

144 lines
3.9 KiB
Python

import logging
import sentry_sdk
from django.contrib import admin, messages
from django.contrib.admin import DateFieldListFilter
from django.db import transaction
from django.utils import timezone
from shiftregister.messaging.outbound import send
from .models import Helper, LoginToken, Message, Room, Shift, ShiftRegistration
logger = logging.getLogger(__name__)
class ShiftInline(admin.TabularInline):
model = Shift
fields = ("deleted", "start_at", "required_helpers")
@admin.register(Room)
class RoomAdmin(admin.ModelAdmin):
list_display = ("name", "description_length", "shift_count")
inlines = [ShiftInline]
def description_length(self, object):
if object.description:
return len(object.description)
return 0
def shift_count(self, object):
return object.shift_set.filter(deleted=False).count()
@admin.register(Shift)
class ShiftAdmin(admin.ModelAdmin):
list_display = ("room_name", "description", "start_at", "free_slots", "deleted")
def room_name(self, object):
return object.room.name
# def helpers(self, object):
# object.helpers.count()
def free_slots(self, object):
return (
object.required_helpers or object.room.required_helpers
) - object.registration_count()
def send_login(modeladmin, request, queryset):
for helper in queryset:
helper.send_confirmation()
class RegistrationInline(admin.TabularInline):
model = ShiftRegistration
@admin.register(Helper)
class HelperAdmin(admin.ModelAdmin):
readonly_fields = ("phone",)
fields = ("name", "phone", "number_validated")
list_display = ("name",)
inlines = (RegistrationInline,)
actions = (send_login,)
@admin.register(ShiftRegistration)
class ShiftRegistrationAdmin(admin.ModelAdmin):
list_display = ("start_at", "room", "helper_name", "state")
list_filter = (("shift__start_at", DateFieldListFilter), "shift__room", "state")
def room(self, obj):
return obj.shift.room.name
def start_at(self, obj):
return obj.shift.start_at
start_at.admin_order_field = "shift__start_at"
def helper_name(self, obj):
return obj.helper.name
def send_messages(modeladmin, request, queryset):
msgs = queryset.select_for_update()
with transaction.atomic():
sent_msg_ids = []
try:
for msg in send(msg.as_outbound() for msg in msgs if not msg.sent_at):
sent_msg_ids.append(msg.key)
except Exception as e:
logger.error(e)
sentry_sdk.capture_exception(e)
Message.objects.select_for_update().filter(id__in=sent_msg_ids).update(
sent_at=timezone.now()
)
num_sent_msgs = len(sent_msg_ids)
if num_sent_msgs == 0:
modeladmin.message_user(
request, "Keine Nachrichten wurden versendet.", messages.WARNING
)
elif num_sent_msgs == 1:
modeladmin.message_user(
request, "Eine Nachricht wurde erfolgreich versendet.", messages.SUCCESS
)
else:
modeladmin.message_user(
request,
f"{num_sent_msgs} Nachrichten wurden erfolgreich versendet.",
messages.SUCCESS,
)
class WasSentListFilter(admin.SimpleListFilter):
parameter_name = "sent"
title = "sent status"
def lookups(self, request, model_admin):
return [("0", "Not sent"), ("1", "Sent")]
def queryset(self, request, queryset):
if self.value() == "1":
return queryset.exclude(sent_at=None)
elif self.value() == "0":
return queryset.filter(sent_at=None)
@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
actions = (send_messages,)
list_display = ("__str__", "was_sent")
list_filter = (WasSentListFilter,)
@admin.display(boolean=True)
def was_sent(self, obj):
return obj.sent_at is not None
admin.site.register(LoginToken)