Added csv export for traveller and email to schools function

This commit is contained in:
John Mullins
2023-09-01 11:23:30 +10:00
parent b93d488598
commit 86c9b13c9a
5 changed files with 93 additions and 46 deletions
+31 -30
View File
@@ -1,7 +1,7 @@
import csv
from datetime import date
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
@@ -11,29 +11,11 @@ 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 .context_helpers import bus_roll_context, emergency_contacts_context, traveller_roll_context
from .email_helpers import email_companies_bus_roll, render_to_pdf, email_school_roll_csv
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):
@@ -48,6 +30,30 @@ class BusRollMixin:
email_company.short_description = "Email Bus Roll to Company"
class SchoolRollMixin:
def email_school_roll(self, request, queryset):
for school in queryset:
if not school.email:
return HttpResponse(f"No email is set for {school.name}")
email_school_roll_csv(request, school)
class TravellerRollMixin:
def export_to_csv(self, request, queryset):
traveller_list = traveller_roll_context(queryset)
response = HttpResponse(content_type="text/csv")
response["Content-Disposition"] = f"attachment; filename=traveller_list_{date.today()}.csv"
writer = csv.DictWriter(response, fieldnames=traveller_list[0].keys())
writer.writeheader()
writer.writerows(traveller_list)
return response
class HiddenNowTime(widgets.TimeInput):
pass
@@ -114,11 +120,6 @@ class BusStopAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
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):
@@ -131,7 +132,7 @@ class TravellerRouteInline(admin.TabularInline):
@admin.register(Traveller)
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin):
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin, TravellerRollMixin):
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"]
@@ -144,6 +145,7 @@ class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin
"emergency_contact_B_phone", "emergency_contact_B_relation"]
inlines = [TravellerRouteInline]
readonly_fields = ["fare_paying", "created_on", "last_edit", "is_archived"]
actions = ["export_to_csv", "yearly_rollover"]
fieldsets = [
(None, {
'fields': [
@@ -209,8 +211,6 @@ class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin
]
# list_display_links = None
actions = ["yearly_rollover"]
def yearly_rollover(self, request, queryset):
pass
@@ -236,8 +236,9 @@ class TravellerRouteAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
@admin.register(School)
class SchoolAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
class SchoolAdmin(MyImportExportModelAdmin, admin.ModelAdmin, SchoolRollMixin):
list_display = ["__str__", "address", "suburb", "school_email", "phone"]
actions = ["email_school_roll"]
def school_email(self, obj):
return format_html('<a href="mailto:{}">{}</a>', obj.email, obj.email)
+39 -2
View File
@@ -1,4 +1,4 @@
from coord.models import Bus, BusStop, TravellerRoute, Driver, Traveller, Shuttle
from coord.models import Bus, BusStop, TravellerRoute, Driver, Traveller, Shuttle, School
def bus_roll_context(queryset=None):
@@ -30,7 +30,6 @@ def bus_roll_context(queryset=None):
'pm': bus_stop.pm_time,
'travellers': traveller_list
}
# print(traveller_list)
bus_route.append(stop_result)
# Todo Add shuttles
@@ -39,6 +38,42 @@ def bus_roll_context(queryset=None):
return {'routes': bus_routes}
def traveller_roll_context(queryset):
travellers = []
for traveller in queryset:
for traveller_route in TravellerRoute.objects.filter(traveller=traveller):
travellers.append(traveller_route_context(traveller_route))
return travellers
def school_roll_context(school):
travellers = []
for travellerRoute in TravellerRoute.objects.filter(traveller__school=school):
traveller = travellerRoute.traveller
if not traveller.is_active():
continue
travellers.append(traveller_route_context(travellerRoute))
return travellers
def traveller_route_context(traveller_route):
traveller = traveller_route.traveller
return {
'first_name': traveller.first_name,
'last_name': traveller.last_name,
'school': traveller.school,
'dob': traveller.dob,
'year_level': traveller.year_level,
'address': f"{traveller.residential_address} {traveller.residential_suburb}",
'start_date': traveller.travel_start_date,
'end_date': traveller.travel_end_date,
'eligibility': traveller.get_eligibility_status_display(),
'shuttle': traveller.shuttle,
'route': traveller_route.busStop.bus,
'stop': f"#{traveller_route.busStop.get_stop_number()} - {traveller_route.busStop.address}"
}
def emergency_contacts_context(queryset=None):
if queryset is None:
buses = Bus.objects.all()
@@ -123,3 +158,5 @@ def bus_summary_context():
'over_capacity': over_capacity,
})
return {'routes': bus_routes}
+23 -5
View File
@@ -1,13 +1,13 @@
import csv
from datetime import date
from io import BytesIO
from io import BytesIO, StringIO
from django.contrib.admin.views.decorators import staff_member_required
from django.core.mail import send_mail, EmailMessage
from django.core.mail import EmailMessage
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
from coord.context_helpers import bus_roll_context
from coord.context_helpers import bus_roll_context, school_roll_context
from coord.models import Company
@@ -20,7 +20,6 @@ def render_to_pdf(template, context):
return HttpResponse(result.getvalue(), content_type='application/pdf')
@staff_member_required
def email_companies_bus_roll(request, query_set=None):
html_template = 'reports/bus_roll.html'
context = bus_roll_context(query_set)
@@ -46,3 +45,22 @@ def email_companies_bus_roll(request, query_set=None):
email.send(fail_silently=True)
return render_to_pdf(html_template, context)
def email_school_roll_csv(request, school):
travellers = school_roll_context(school)
csvFile = StringIO()
fieldnames = list(travellers[0].keys())
writer = csv.DictWriter(csvFile, fieldnames=fieldnames)
writer.writeheader(),
writer.writerows(travellers)
subject = "Bus Roll"
message = f"A new bus roll for {school.name} has been generated"
email_from = "bus.manager@education.vic.gov.au"
recipient = [school.email]
email = EmailMessage(subject, message, email_from, recipient)
email.attach(f"school_bus_roll_{date.today()}.csv", csvFile.getvalue(), 'text/csv')
email.send()
-1
View File
@@ -1,7 +1,6 @@
from datetime import datetime
from django.db import models
from django.db.models import Model
class Setting(models.Model):
-8
View File
@@ -1,10 +1,8 @@
from django.contrib.admin.views.decorators import staff_member_required
from django.shortcuts import render
from django.views.generic import ListView
from .context_helpers import *
from .email_helpers import render_to_pdf
from .models import Company, Bus, Traveller, BusStop, TravellerRoute, Shuttle, Driver
@staff_member_required
@@ -20,9 +18,3 @@ def emergency_contacts(request):
@staff_member_required
def bus_roll(request):
return render_to_pdf('reports/bus_roll.html', bus_roll_context())
@staff_member_required
class CompanyList(ListView):
model = Company
template_name = "companies.html"