diff --git a/busManager/coord/admin.py b/busManager/coord/admin.py index ab287f8..24c1a30 100644 --- a/busManager/coord/admin.py +++ b/busManager/coord/admin.py @@ -12,7 +12,8 @@ from django.utils.translation import gettext_lazy from import_export.admin import ImportExportModelAdmin from .adminClone import CloneModelAdmin -from .context_helpers import bus_roll_context, emergency_contacts_context, traveller_roll_context +from .context_helpers import bus_roll_context, emergency_contacts_context, traveller_roll_context, \ + traveller_route_context from .email_helpers import email_companies_bus_roll, render_to_pdf, email_school_roll_csv from .models import * @@ -33,11 +34,23 @@ class BusRollMixin: class SchoolRollMixin: - def email_school_roll(self, request, queryset): + def export_travellers_to_csv(self, request, queryset): + + traveller_list = [] for school in queryset: - if not school.email: - return HttpResponse(f"No email is set for {school.name}") - email_school_roll_csv(request, school) + for travellerRoute in TravellerRoute.objects.filter(traveller__school=school): + if not travellerRoute.traveller.is_active(): + continue + traveller_list.append(traveller_route_context(travellerRoute)) + + 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 TravellerRollMixin: @@ -55,7 +68,6 @@ class TravellerRollMixin: class ArchiveFilter(BooleanFieldListFilter): - title = gettext_lazy('Previous Years') parameter_name = 'is_archived' def choices(self, changelist): @@ -258,7 +270,7 @@ class TravellerRouteAdmin(MyImportExportModelAdmin, admin.ModelAdmin): @admin.register(School) class SchoolAdmin(MyImportExportModelAdmin, admin.ModelAdmin, SchoolRollMixin): list_display = ["__str__", "address", "suburb", "school_email", "phone"] - actions = ["email_school_roll"] + actions = ["export_travellers_to_csv"] def school_email(self, obj): return format_html('{}', obj.email, obj.email) diff --git a/busManager/coord/context_helpers.py b/busManager/coord/context_helpers.py index 8c542de..6e21ebb 100644 --- a/busManager/coord/context_helpers.py +++ b/busManager/coord/context_helpers.py @@ -1,3 +1,5 @@ +from django.db.models import Q + from coord.models import Bus, BusStop, TravellerRoute, Driver, Traveller, Shuttle, School @@ -38,6 +40,48 @@ def bus_roll_context(queryset=None): return {'routes': bus_routes} +def school_roll_context(queryset=None): + school_list = [] + if queryset is None: + schools = School.objects.all() + else: + schools = queryset + + for school in schools: + school_routes = [] + query = Q(traveller__school=school) | Q(traveller__shuttle__school=school) + for bus in Bus.objects.all(): + travellers = [] + for trav_route in TravellerRoute.objects.filter(query).filter(busStop__bus=bus).order_by('busStop__am_time'): + traveller = trav_route.traveller + if not traveller.is_active(): + continue + bus_stop = trav_route.busStop + + display_name = f"{traveller} ({traveller.get_year_level_display()})" + if traveller.school != school: + display_name = f"{traveller} ({traveller.get_year_level_display()}, {traveller.school.shortName})" + is_fared = "---" + if traveller.eligibility_status == "2": + is_fared = "Y" + travellers.append({ + 'display': display_name, + 'isFared': is_fared, + 'stop': f"#{bus_stop.get_stop_number()} - {bus_stop.address}", + 'am_time': bus_stop.am_time, + 'pm_time': bus_stop.pm_time + }) + if travellers: + school_routes.append({ + 'bus': bus, + 'travellers': travellers + }) + + + school_list.append({"name": school.name, "routes": school_routes}) + return {"schools": school_list} + + def traveller_roll_context(queryset): travellers = [] for traveller in queryset: @@ -46,7 +90,7 @@ def traveller_roll_context(queryset): return travellers -def school_roll_context(school): +def school_travellerRoute_context(school): travellers = [] for travellerRoute in TravellerRoute.objects.filter(traveller__school=school): traveller = travellerRoute.traveller diff --git a/busManager/coord/email_helpers.py b/busManager/coord/email_helpers.py index c5f0e90..2b83686 100644 --- a/busManager/coord/email_helpers.py +++ b/busManager/coord/email_helpers.py @@ -7,7 +7,7 @@ from django.http import HttpResponse from django.template.loader import get_template from xhtml2pdf import pisa -from coord.context_helpers import bus_roll_context, school_roll_context +from coord.context_helpers import bus_roll_context, school_travellerRoute_context from coord.models import Company @@ -49,7 +49,7 @@ def email_companies_bus_roll(request, query_set=None): def email_school_roll_csv(request, school): - travellers = school_roll_context(school) + travellers = school_travellerRoute_context(school) csvFile = StringIO() fieldnames = list(travellers[0].keys()) diff --git a/busManager/coord/templates/reports/school_roll.html b/busManager/coord/templates/reports/school_roll.html new file mode 100644 index 0000000..d96411f --- /dev/null +++ b/busManager/coord/templates/reports/school_roll.html @@ -0,0 +1,35 @@ + + +{% for school in schools %} +

{{ school.name }}

+ {% for route in school.routes %} +
+

{{ route.bus }}

+ + + + + + + + + {% for traveller in route.travellers %} + + + + + + + + {% endfor %} +
TravellerFareStopAM TimePM Time
{{ traveller.display }}{{ traveller.isFared }}{{ traveller.stop }}{{ traveller.am_time }}{{ traveller.pm_time }}
+ {% endfor %} +

+{% endfor %} \ No newline at end of file diff --git a/busManager/coord/urls.py b/busManager/coord/urls.py index 5ca41e4..2aa2885 100644 --- a/busManager/coord/urls.py +++ b/busManager/coord/urls.py @@ -7,4 +7,5 @@ urlpatterns = [ path("contacts", views.emergency_contacts, name="emergency_contacts"), path("roll", views.bus_roll, name="bus_roll"), path("summary", views.bus_summary, name="bus_summary"), + path("school", views.school_roll, name="school_roll"), ] diff --git a/busManager/coord/views.py b/busManager/coord/views.py index 7e66581..c2706b6 100644 --- a/busManager/coord/views.py +++ b/busManager/coord/views.py @@ -18,3 +18,8 @@ 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 +def school_roll(request): + return render_to_pdf('reports/school_roll.html', school_roll_context())