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_A_email_display", "contact_B_phone_display", "contact_B_email_display", "emergency_contact_A_phone_display", "emergency_contact_A_email_display", "emergency_contact_B_phone_display", "emergency_contact_B_email_display", ] fieldsets = ( ("Residential Address", { "fields": ("location",) }), ("Postal Address", { "fields": ("postal_location",) }), ("Parents / Guardians", { "fields": ( "contact_A_relation", "contact_A", "contact_A_phone_display", "contact_A_email_display", "contact_B_relation", "contact_B", "contact_B_phone_display", "contact_B_email_display", ) }), ("Emergency Contacts", { "fields": ( "emergency_contact_A_relation", "emergency_contact_A", "emergency_contact_A_phone_display", "emergency_contact_A_email_display", "emergency_contact_B_relation", "emergency_contact_B", "emergency_contact_B_phone_display", "emergency_contact_B_email_display", ) }), ) def contact_A_phone_display(self, obj): return obj.contact_A.phone if obj.contact_A else "-" def contact_A_email_display(self, obj): return obj.contact_A.email if obj.contact_A else "-" def contact_B_phone_display(self, obj): return obj.contact_B.phone if obj.contact_B else "-" def contact_B_email_display(self, obj): return obj.contact_B.email 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_A_email_display(self, obj): return obj.emergency_contact_A.email 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 "-" def emergency_contact_B_email_display(self, obj): return obj.emergency_contact_B.email if obj.emergency_contact_B else "-" contact_A_phone_display.short_description = "Phone" contact_A_email_display.short_description = "Email" contact_B_phone_display.short_description = "Phone" contact_B_email_display.short_description = "Email" emergency_contact_A_phone_display.short_description = "Phone" emergency_contact_A_email_display.short_description = "Email" emergency_contact_B_phone_display.short_description = "Phone" emergency_contact_B_email_display.short_description = "Email" 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( '{} ({})
' '{}', 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('{}', obj.email, obj.email)