cmsmanage/membershipworks/admin.py

155 lines
4.2 KiB
Python

from django.contrib import admin
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.utils.html import format_html
from django_object_actions import DjangoObjectActions, action
from django_q.tasks import async_task
from django_q.models import Task
from .models import (
Member,
Flag,
Transaction,
Event,
EventExt,
EventMeetingTime,
EventInstructor,
)
from .tasks.scrape import scrape_membershipworks
class ReadOnlyAdmin(admin.ModelAdmin):
def has_add_permission(self, request, obj=None):
return False
def has_change_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False
class BaseMembershipWorksAdmin(DjangoObjectActions, ReadOnlyAdmin):
changelist_actions = ("refresh_membershipworks_data",)
# internal method from DjangoObjectActions
def _get_tool_dict(self, tool_name):
tool = super(DjangoObjectActions, self)._get_tool_dict(tool_name)
if tool_name == "refresh_membershipworks_data":
last_run = (
Task.objects.filter(group="Scrape Data from MembershipWorks")
.order_by("started")
.last()
)
last_run_time = (
naturaltime(last_run.started) if last_run is not None else "Never"
)
tool["label"] = f"Refresh Data [Last Run {last_run_time}]"
return tool
@action
def refresh_membershipworks_data(self, request, obj):
async_task(scrape_membershipworks, group="Scrape Data from MembershipWorks")
self.message_user(
request,
"Queued refresh, please wait a few seconds/minutes then refresh the page",
)
class MemberFlagInline(admin.TabularInline):
model = Member.flags.through
@admin.register(Member)
class MemberAdmin(BaseMembershipWorksAdmin):
search_fields = ["^first_name", "^last_name", "^account_name"]
inlines = [MemberFlagInline]
@admin.register(Flag)
class FlagAdmin(BaseMembershipWorksAdmin):
inlines = [MemberFlagInline]
list_display = ["name", "type"]
list_filter = ["type"]
show_facets = admin.ShowFacets.ALWAYS
search_fields = ["name"]
@admin.register(Transaction)
class TransactionAdmin(BaseMembershipWorksAdmin):
list_display = ["timestamp", "member", "name", "type", "sum", "note"]
list_filter = ["type"]
show_facets = admin.ShowFacets.ALWAYS
search_fields = ["member", "name", "type", "note"]
date_hierarchy = "timestamp"
class EventMeetingTimeInline(admin.TabularInline):
model = EventMeetingTime
extra = 0
min_num = 1
readonly_fields = ["duration"]
# TODO: remove when switched to GeneratedField
@admin.display()
def duration(self, obj):
return obj.duration
@admin.register(EventInstructor)
class EventInstructorAdmin(admin.ModelAdmin):
autocomplete_fields = ["member"]
@admin.register(EventExt)
class EventAdmin(admin.ModelAdmin):
inlines = [EventMeetingTimeInline]
list_display = [
"title",
"start",
"duration",
"count",
"cap",
"category",
]
list_filter = [
"category",
"calendar",
"venue",
("materials_fee", admin.EmptyFieldListFilter),
]
show_facets = admin.ShowFacets.ALWAYS
search_fields = ["eid", "title", "url"]
date_hierarchy = "start"
@property
def readonly_fields(self):
fields = []
for field in Event._meta.get_fields():
if field.auto_created or field.many_to_many or not field.concrete:
continue
elif field.name == "url":
fields.append("_url")
else:
fields.append(field.name)
fields.insert(fields.index("end") + 1, "duration")
return fields
@admin.display(ordering="duration")
def duration(self, obj):
return obj.duration
@admin.display(description="URL")
def _url(self, obj):
return format_html(
'<a href="https://claremontmakerspace.org/events/#!event/{0}">{0}</a>',
obj.url,
)
def has_add_permission(self, request, obj=None):
return False
def has_delete_permission(self, request, obj=None):
return False