4025c28eae
Moved contacts to new model
256 lines
8.2 KiB
Python
256 lines
8.2 KiB
Python
from django.contrib import admin
|
|
from django.db import models
|
|
from django.urls import reverse
|
|
from django.utils.html import format_html
|
|
from rangefilter.filters import DateRangeFilterBuilder
|
|
|
|
from common.admin import MyImportExportModelAdmin
|
|
from traveller.adminClone import CloneModelAdmin
|
|
from traveller.admin_mixins import SchoolRollMixin, TravellerRollMixin
|
|
from traveller.models import Family, TravellerRoute, Traveller, School, ContactPerson
|
|
|
|
|
|
class FamilyInline(admin.StackedInline):
|
|
model = Family
|
|
classes = ['collapse']
|
|
extra = 0
|
|
clone_parent = "traveller"
|
|
autocomplete_fields = [
|
|
"location",
|
|
"postal_location",
|
|
"contact_A",
|
|
"contact_B",
|
|
"emergency_contact_A",
|
|
"emergency_contact_B",
|
|
]
|
|
|
|
readonly_fields = [
|
|
"contact_A_phone_display",
|
|
"contact_B_phone_display",
|
|
"emergency_contact_A_phone_display",
|
|
"emergency_contact_B_phone_display",
|
|
]
|
|
|
|
fieldsets = (
|
|
("Residential Address", {
|
|
"fields": ("location",)
|
|
}),
|
|
|
|
("Postal Address", {
|
|
"fields": ("postal_location",)
|
|
}),
|
|
|
|
("Parents / Guardians", {
|
|
"fields": (
|
|
"contact_A_relation",
|
|
"contact_A",
|
|
"contact_A_phone_display",
|
|
"contact_B_relation",
|
|
"contact_B",
|
|
"contact_B_phone_display",
|
|
)
|
|
}),
|
|
|
|
("Emergency Contacts", {
|
|
"fields": (
|
|
"emergency_contact_A_relation",
|
|
"emergency_contact_A",
|
|
"emergency_contact_A_phone_display",
|
|
"emergency_contact_B_relation",
|
|
"emergency_contact_B",
|
|
"emergency_contact_B_phone_display",
|
|
)
|
|
}),
|
|
)
|
|
|
|
def contact_A_phone_display(self, obj):
|
|
return obj.contact_A.phone if obj.contact_A else "-"
|
|
|
|
def contact_B_phone_display(self, obj):
|
|
return obj.contact_B.phone if obj.contact_B else "-"
|
|
|
|
def emergency_contact_A_phone_display(self, obj):
|
|
return obj.emergency_contact_A.phone if obj.emergency_contact_A else "-"
|
|
|
|
def emergency_contact_B_phone_display(self, obj):
|
|
return obj.emergency_contact_B.phone if obj.emergency_contact_B else "-"
|
|
|
|
contact_A_phone_display.short_description = "Phone"
|
|
contact_B_phone_display.short_description = "Phone"
|
|
emergency_contact_A_phone_display.short_description = "Phone"
|
|
emergency_contact_B_phone_display.short_description = "Phone"
|
|
|
|
|
|
class TravellerRouteInline(admin.TabularInline):
|
|
model = TravellerRoute
|
|
extra = 0
|
|
clone_parent = "traveller"
|
|
|
|
|
|
@admin.register(Traveller)
|
|
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, TravellerRollMixin):
|
|
list_display = ["first_name", "last_name", "school", "year_level", "is_active", "address", "stop_route", "shuttle", "travel_start_date", "travel_end_date"]
|
|
list_filter = [
|
|
"is_active", "school", "year_level", "eligibility_status", "bus_stops__bus", "shuttle",
|
|
("travel_start_date", DateRangeFilterBuilder(
|
|
title="Start date"
|
|
)),
|
|
("travel_end_date", DateRangeFilterBuilder(
|
|
title="End date"
|
|
))
|
|
]
|
|
cloneable_fields = ["last_name"]
|
|
search_fields = ["first_name", "last_name", "address"]
|
|
inlines = [FamilyInline, TravellerRouteInline]
|
|
readonly_fields = ["travel_start_date", "travel_end_date", "created_on", "last_edit", "is_active", "address"]
|
|
actions = ["export_to_csv", "send_sms", "confirmation_letter", "letter_creator"]
|
|
fieldsets = [
|
|
(None, {
|
|
'fields': [
|
|
"is_active",
|
|
"school",
|
|
"first_name",
|
|
"last_name",
|
|
"year_level",
|
|
"dob",
|
|
"address",
|
|
]
|
|
}),
|
|
('Office Use', {
|
|
'classes': ('collapse',),
|
|
'fields': [
|
|
"distance_to_school",
|
|
"travel_start_date",
|
|
"travel_end_date",
|
|
"eligibility_status",
|
|
"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",
|
|
]
|
|
}),
|
|
(None, {'fields': ["notes", "shuttle"]})
|
|
]
|
|
# list_display_links = None
|
|
|
|
def stop_route(self, obj):
|
|
from transport.models import BusStop
|
|
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):
|
|
# if obj.is_archived and obj.travel_end_date is None:
|
|
# obj.is_archived = False
|
|
# super().save_model(request, obj, form, change)
|
|
|
|
@admin.register(ContactPerson)
|
|
class ContactPersonAdmin(MyImportExportModelAdmin):
|
|
list_display = [
|
|
"first_name",
|
|
"last_name",
|
|
"phone",
|
|
"email"
|
|
]
|
|
|
|
search_fields = [
|
|
"first_name",
|
|
"last_name",
|
|
"phone",
|
|
"email",
|
|
]
|
|
|
|
readonly_fields = [
|
|
"traveller_relationship_summary"
|
|
]
|
|
|
|
fieldsets = (
|
|
(None, {
|
|
"fields": ("first_name", "last_name", "phone", "email")
|
|
}),
|
|
|
|
("Relationships", {
|
|
"fields": ("traveller_relationship_summary",)
|
|
}),
|
|
)
|
|
|
|
def traveller_relationship_summary(self, obj):
|
|
from django.utils.html import format_html
|
|
|
|
families = Family.objects.filter(
|
|
models.Q(contact_A=obj) |
|
|
models.Q(contact_B=obj) |
|
|
models.Q(emergency_contact_A=obj) |
|
|
models.Q(emergency_contact_B=obj)
|
|
).select_related("traveller", "location")
|
|
|
|
if not families.exists():
|
|
return "No traveller relationships"
|
|
|
|
output = []
|
|
|
|
for family in families:
|
|
traveller = family.traveller
|
|
|
|
relation = ""
|
|
if family.contact_A == obj:
|
|
relation = family.contact_A_relation
|
|
elif family.contact_B == obj:
|
|
relation = family.contact_B_relation
|
|
elif family.emergency_contact_A == obj:
|
|
relation = family.emergency_contact_A_relation
|
|
elif family.emergency_contact_B == obj:
|
|
relation = family.emergency_contact_B_relation
|
|
|
|
address = family.location if family.location else "No address"
|
|
|
|
url = reverse(
|
|
"admin:traveller_traveller_change",
|
|
args=[traveller.id]
|
|
)
|
|
|
|
output.append(
|
|
format_html(
|
|
'<a href="{}">{}</a> ({})<br>'
|
|
'<small style="color:#888">{}</small>',
|
|
url,
|
|
f"{traveller.first_name} {traveller.last_name}",
|
|
relation,
|
|
address
|
|
)
|
|
)
|
|
|
|
return format_html("".join(output))
|
|
|
|
traveller_relationship_summary.short_description = "Traveller Relationships"
|
|
|
|
# @admin.register(Family)
|
|
class FamilyAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
|
|
list_display = ["traveller", "__str__",
|
|
"parent_A_firstname", "parent_A_lastname", "parent_A_phone",
|
|
"parent_B_firstname", "parent_B_lastname", "parent_B_phone",
|
|
"emergency_contact_A_firstname", "emergency_contact_A_lastname", "emergency_contact_A_phone",
|
|
"emergency_contact_B_firstname", "emergency_contact_B_lastname", "emergency_contact_B_phone"]
|
|
|
|
|
|
# @admin.register(TravellerRoute)
|
|
class TravellerRouteAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
|
|
list_display = ["traveller", "busStop"]
|
|
|
|
|
|
@admin.register(School)
|
|
class SchoolAdmin(MyImportExportModelAdmin, admin.ModelAdmin, SchoolRollMixin):
|
|
list_display = ["__str__", "address", "suburb", "school_email", "phone"]
|
|
actions = ["email_travellers_to_school", "show_school_travellers", "export_travellers_to_csv"]
|
|
|
|
def school_email(self, obj):
|
|
return format_html('<a href="mailto:{}">{}</a>', obj.email, obj.email) |