Files
bus-manager/busManager/coord/admin.py
T
2023-08-30 12:06:09 +10:00

271 lines
9.2 KiB
Python

import csv
from django.contrib.admin import DateFieldListFilter
from django.contrib.admin.views.decorators import staff_member_required
from django.forms import widgets
from django.contrib import admin
from django.http import HttpResponse
from django.urls import reverse
from django.utils.html import format_html
from django.utils.http import urlencode
from import_export.admin import ImportExportModelAdmin
from .adminClone import CloneModelAdmin
from .context_helpers import bus_roll_context, emergency_contacts_context
from .email_helpers import email_companies_bus_roll, render_to_pdf
from .models import *
class ExportCsvMixin:
def export_as_csv(self, request, queryset):
meta = self.model._meta
field_names = [field.name for field in meta.fields]
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
writer = csv.writer(response)
writer.writerow(field_names)
for obj in queryset:
row = writer.writerow([getattr(obj, field) for field in field_names])
return response
export_as_csv.short_description = "Export Selected"
class BusRollMixin:
def show_bus_roll(self, request, queryset):
return render_to_pdf('reports/bus_roll.html', bus_roll_context(queryset))
def show_emergency_contacts(self, request, queryset):
return render_to_pdf('reports/emergency_contacts.html', emergency_contacts_context(queryset))
def email_company(self, request, queryset):
return email_companies_bus_roll(request, queryset)
email_company.short_description = "Email Bus Roll to Company"
class HiddenNowTime(widgets.TimeInput):
pass
class MyImportExportModelAdmin(ImportExportModelAdmin):
def has_import_permission(self, request):
return request.user.is_superuser
@admin.register(Company)
class CompanyAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["name", "contact_name", "email", "buses"]
def buses(self, obj):
count = obj.bus_set.count()
url = (
reverse("admin:coord_bus_changelist")
+ "?"
+ urlencode({"company__id__exact": f"{obj.id}"})
)
return format_html('<a href="{}">{} Buses</a>', url, count)
def email(self, obj):
return format_html('<a href="mailto:{}">{}</a>', obj.contact_email, obj.contact_email)
class DriverInline(admin.StackedInline):
model = Driver
extra = 0
class BusStopInline(admin.TabularInline):
model = BusStop
extra = 0
ordering = ("am_time",)
@admin.register(Bus)
class BusesAdmin(MyImportExportModelAdmin, admin.ModelAdmin, BusRollMixin):
list_filter = ["company"]
list_display = ["route_name", "company", "contract_number", "seating_capacity", "route_travellers"]
readonly_fields = ["traveller_count"]
actions = ["email_company", "show_bus_roll", "show_emergency_contacts"]
inlines = [DriverInline, BusStopInline]
fieldsets = [
(None, {'fields': [
"company", "route_name", "contract_number", "registration",
"traveller_count", "seating_capacity", "make", "model", "notes"
]})
]
def route_travellers(self, obj):
url = (
reverse("admin:coord_traveller_changelist")
+ "?"
+ urlencode({"bus_stops__bus__id__exact": f"{obj.id}"})
)
return format_html('<a href="{}">{} Travellers</a>', url, obj.traveller_count())
@admin.register(BusStop)
class BusStopAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_filter = ["bus__company", "bus__route_name"]
list_display = ["__str__", "am_time", "pm_time", "address"]
search_fields = ["bus__route_name", "address"]
# change_form_template = 'admin/change_form_busStops.html'
def export_as_csv(self, request, queryset):
pass
@admin.register(Suburb)
class SuburbsAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_filter = ["state"]
class TravellerRouteInline(admin.TabularInline):
model = TravellerRoute
extra = 0
@admin.register(Traveller)
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin):
list_display = ["first_name", "last_name", "school", "year_level", "residential_address", "residential_suburb", "stop_route", "travel_start_date", "travel_end_date"]
list_filter = ["school", "eligibility_status", "bus_stops__bus", "residential_suburb", ("travel_end_date", DateFieldListFilter), "is_archived"]
search_fields = ["first_name", "last_name", "residential_address"]
cloneable_fields = ["last_name", "residential_address", "residential_suburb",
"postal_address", "postal_suburb", "eligibility_status", "shuttle",
"parent_A_firstname", "parent_A_lastname", "parent_A_phone", "parent_A_email",
"parent_B_firstname", "parent_B_lastname", "parent_B_phone", "parent_B_email",
"emergency_contact_A_firstname", "emergency_contact_A_lastname", "emergency_contact_A_phone",
"emergency_contact_A_relation", "emergency_contact_B_firstname", "emergency_contact_B_lastname",
"emergency_contact_B_phone", "emergency_contact_B_relation"]
inlines = [TravellerRouteInline]
readonly_fields = ["fare_paying", "created_on", "last_edit", "is_archived"]
fieldsets = [
(None, {
'fields': [
"school",
"first_name",
"last_name",
"dob",
"year_level",
]
}),
('Address', {
'classes': ('collapse',),
'fields': [
"residential_address",
"residential_suburb",
"postal_address",
"postal_suburb",
]
}),
('Office Use', {
'classes': ('collapse',),
'fields': [
"distance_to_school",
"travel_start_date",
"travel_end_date",
"eligibility_status",
"fare_paying",
"term_1_paid",
"term_2_paid",
"term_3_paid",
"term_4_paid",
"assessment_date",
"application_form_completed",
"parent_notified",
"seat_number",
"created_on",
"last_edit",
"is_archived",
]
}),
('Adult Contacts', {
'classes': ('collapse',),
'fields': [
"parent_A_firstname",
"parent_A_lastname",
"parent_A_phone",
"parent_A_email",
"parent_B_firstname",
"parent_B_lastname",
"parent_B_phone",
"parent_B_email",
"emergency_contact_A_firstname",
"emergency_contact_A_lastname",
"emergency_contact_A_phone",
"emergency_contact_A_relation",
"emergency_contact_B_firstname",
"emergency_contact_B_lastname",
"emergency_contact_B_phone",
"emergency_contact_B_relation"
]
}),
(None, {'fields': ["notes", "shuttle"]})
]
# list_display_links = None
actions = ["yearly_rollover"]
def yearly_rollover(self, request, queryset):
pass
def stop_route(self, obj):
stops = BusStop.objects.filter(traveller__id__exact=obj.id)
if stops.count() == 0:
return ""
if stops.count() == 1:
return stops.first()
return "Multiple"
def save_model(self, request, obj, form, change):
print("Saving")
if obj.is_archived and obj.travel_end_date is None:
obj.is_archived = False
print("Pulling out of archive")
super().save_model(request, obj, form, change)
@admin.register(TravellerRoute)
class TravellerRouteAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["traveller", "busStop"]
@admin.register(School)
class SchoolAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["__str__", "address", "suburb", "school_email", "phone"]
def school_email(self, obj):
return format_html('<a href="mailto:{}">{}</a>', obj.email, obj.email)
@admin.register(Setting)
class SettingAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["name", "value"]
@admin.register(Shuttle)
class ShuttleAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["__str__", "school", "bus", "shuttle_travellers"]
def shuttle_travellers(self, obj):
url = (
reverse("admin:coord_traveller_changelist")
+ "?"
+ urlencode({"shuttle__id__exact": f"{obj.id}"})
)
return format_html('<a href="{}">{} Travellers</a>', url, obj.traveller_count())
@admin.register(Driver)
class DriverAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
list_display = ["__str__", "route", "phone_number"]
def route(self, obj):
url = reverse("admin:coord_bus_change", args=(obj.bus.id,))
return format_html('<a href="{}">{}</a>', url, obj.bus)