Added reports to top left admin menu bar
Combined summary pages Changed admin panel to index
This commit is contained in:
+1
-2
@@ -132,5 +132,4 @@ GitHub.sublime-settings
|
||||
/media
|
||||
/static
|
||||
/busManager/busManager/settings.py
|
||||
/busManager/coord/migrations
|
||||
/busManager/busManager/templates/admin/base.html
|
||||
/busManager/coord/migrations
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends 'admin/base.html' %} {% block extrahead %}{{ block.super }}
|
||||
{% load i18n static %}
|
||||
<style>
|
||||
:root {
|
||||
--header-bg: #502977;
|
||||
--primary: #8053a2;
|
||||
--secondary: #502977;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block userlinks %}
|
||||
<a href={% url 'report:emergency_contacts' %}>Emergency Contacts</a> /
|
||||
<a href={% url 'report:bus_roll' %}>Bus Roll</a> /
|
||||
<a href={% url 'report:bus_summary' %}>Bus Routes</a> /
|
||||
<a href="https://www2.education.vic.gov.au/pal/school-bus-program/resources">Resources</a> /
|
||||
<form id="logout-form" method="post" action="{% url 'admin:logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit">{% translate 'Log out' %}</button>
|
||||
</form>
|
||||
{% include "admin/color_theme_toggle.html" %}
|
||||
{% endblock %}
|
||||
@@ -22,7 +22,7 @@ admin.site.site_header = "Bus Portal Admin"
|
||||
|
||||
urlpatterns = [
|
||||
path('report/', include("coord.urls")),
|
||||
path('admin/logout/', azure_auth_logout),
|
||||
path('admin/', admin.site.urls),
|
||||
path('logout/', azure_auth_logout),
|
||||
path('auth/', include("azure_auth.urls"),),
|
||||
path('', admin.site.urls),
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from coord.models import Bus, BusStop, TravellerRoute, Driver
|
||||
from coord.models import Bus, BusStop, TravellerRoute, Driver, Traveller, Shuttle
|
||||
|
||||
|
||||
def bus_roll_context(queryset=None):
|
||||
@@ -78,3 +78,48 @@ def emergency_contacts_context(queryset=None):
|
||||
bus_routes.append({'bus': bus, 'drivers': drivers, 'travellers': traveller_list})
|
||||
|
||||
return {'routes': bus_routes}
|
||||
|
||||
|
||||
def bus_summary_context():
|
||||
bus_routes = []
|
||||
for bus in Bus.objects.all():
|
||||
|
||||
drivers = []
|
||||
for driver in Driver.objects.filter(bus=bus):
|
||||
drivers.append(driver)
|
||||
|
||||
stops = []
|
||||
for bus_stop in BusStop.objects.filter(bus=bus):
|
||||
stops.append(bus_stop)
|
||||
|
||||
traveller_count = 0
|
||||
for travellerRoute in TravellerRoute.objects.filter(busStop__bus=bus):
|
||||
if travellerRoute.traveller.is_active():
|
||||
traveller_count += 1
|
||||
|
||||
shuttle_name = ""
|
||||
shuttle_count = 0
|
||||
for shuttle in Shuttle.objects.filter(bus=bus):
|
||||
if shuttle_name == "":
|
||||
shuttle_name = shuttle.school.shortName
|
||||
else:
|
||||
shuttle_name += f", {shuttle.school.shortName}"
|
||||
|
||||
for traveller in Traveller.objects.filter(shuttle=shuttle):
|
||||
if traveller.is_active():
|
||||
shuttle_count += 1
|
||||
|
||||
over_capacity = traveller_count > bus.seating_capacity or shuttle_count > bus.seating_capacity
|
||||
if shuttle_count == 0:
|
||||
shuttle_count = ""
|
||||
|
||||
bus_routes.append({
|
||||
'bus': bus,
|
||||
'drivers': drivers,
|
||||
'stops': stops,
|
||||
'traveller_count': traveller_count,
|
||||
'shuttle_name': shuttle_name,
|
||||
'shuttle_count': shuttle_count,
|
||||
'over_capacity': over_capacity,
|
||||
})
|
||||
return {'routes': bus_routes}
|
||||
|
||||
@@ -1,24 +1,61 @@
|
||||
<style>
|
||||
td {
|
||||
text-align: left;
|
||||
padding-inline: 5px;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #dddfe1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h1>Routes Overview</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Route Name</th>
|
||||
<th>Driver</th>
|
||||
<th>Route Travellers</th>
|
||||
<th>Shuttle</th>
|
||||
<th>Shuttle Travellers</th>
|
||||
<th>Seating Max</th>
|
||||
</tr>
|
||||
{% for route in routes %}
|
||||
<tr>
|
||||
<td>{{ route.bus.route_name }}</td>
|
||||
<td>
|
||||
{% for driver in route.drivers %}
|
||||
{{ driver }}<br>
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>{{ route.traveller_count }}</td>
|
||||
<td>{{ route.shuttle_name }}</td>
|
||||
<td>{{ route.shuttle_count }}</td>
|
||||
{% if route.over_capacity %}
|
||||
<td style="color:red"><b>{{ route.seating_capacity }}</b></td>
|
||||
{% else %}
|
||||
<td>{{ route.seating_capacity }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<p style="page-break-after: always">
|
||||
|
||||
{% for route in routes %}
|
||||
<h1>{{ route.bus.company }}</h1>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Route name</th>
|
||||
<th>Driver</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{{ route.bus.route_name }}</td>
|
||||
<td>{{ route.drivers }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h1>{{ route.bus.company }} - {{ route.bus }}</h1>
|
||||
{% for driver in route.drivers %}
|
||||
<p><b>Driver:</b> {{ driver }} ({{ driver.phone_number }})</p>
|
||||
{% endfor %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Stop #</th>
|
||||
<th>Address</th>
|
||||
<th>AM Time</th>
|
||||
<th>PM Time</th>
|
||||
</tr>
|
||||
{% for stop in route.stops %}
|
||||
<tr>
|
||||
<td>{{ stop.get_stop_number }}</td>
|
||||
<td>{{ stop.address }}</td>
|
||||
<td>{{ stop.am_time }}</td>
|
||||
<td>{{ stop.pm_time }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
@@ -23,29 +23,29 @@
|
||||
|
||||
{% for route in routes %}
|
||||
<h1 style="font-size: 2.5em">{{ route.bus.company }} - {{ route.bus }}</h1>
|
||||
{% for driver in route.drivers %}
|
||||
<p><b>Driver:</b> {{ driver }} ({{ driver.phone_number }})</p>
|
||||
{% endfor %}
|
||||
<table class="traveller">
|
||||
{% for driver in route.drivers %}
|
||||
<p><b>Driver:</b> {{ driver }} ({{ driver.phone_number }})</p>
|
||||
{% endfor %}
|
||||
<table class="traveller">
|
||||
<tr>
|
||||
<th style="width: 25%">Student</th>
|
||||
<th style="width: 25%">Parent A</th>
|
||||
<th style="width: 25%">Parent B</th>
|
||||
<th style="width: 25%">Emergency Contact A</th>
|
||||
<th style="width: 25%">Emergency Contact B</th>
|
||||
<th style="width: 40%">Driver notes</th>
|
||||
</tr>
|
||||
{% for traveller in route.travellers %}
|
||||
<tr>
|
||||
<th style="width: 25%">Student</th>
|
||||
<th style="width: 25%">Parent A</th>
|
||||
<th style="width: 25%">Parent B</th>
|
||||
<th style="width: 25%">Emergency Contact A</th>
|
||||
<th style="width: 25%">Emergency Contact B</th>
|
||||
<th style="width: 40%">Driver notes</th>
|
||||
<td>{{ traveller.traveller.last_name }}, {{ traveller.traveller.first_name }} ({{ traveller.traveller.school.shortName }})</td>
|
||||
<td>{{ traveller.parent_a }}</td>
|
||||
<td>{{ traveller.parent_b }}</td>
|
||||
<td>{{ traveller.contact_a }}</td>
|
||||
<td>{{ traveller.contact_b }}</td>
|
||||
<td>{{ traveller.note }}</td>
|
||||
</tr>
|
||||
{% for traveller in route.travellers %}
|
||||
<tr>
|
||||
<td>{{ traveller.traveller.last_name }}, {{ traveller.traveller.first_name }} ({{ traveller.traveller.school.shortName }})</td>
|
||||
<td>{{ traveller.parent_a }}</td>
|
||||
<td>{{ traveller.parent_b }}</td>
|
||||
<td>{{ traveller.contact_a }}</td>
|
||||
<td>{{ traveller.contact_b }}</td>
|
||||
<td>{{ traveller.note }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<br>
|
||||
{% endfor %}
|
||||
</table>
|
||||
<br>
|
||||
<p style="page-break-after: always">
|
||||
{% endfor %}
|
||||
@@ -2,8 +2,9 @@ from django.urls import path
|
||||
|
||||
from . import views
|
||||
|
||||
app_name = "report"
|
||||
urlpatterns = [
|
||||
path("contacts", views.emergency_contacts, name="Emergency Contacts"),
|
||||
path("stops", views.bus_summary, name="Stop Summary"),
|
||||
path("summary", views.bus_numbers, name="Bus Summary"),
|
||||
path("contacts", views.emergency_contacts, name="emergency_contacts"),
|
||||
path("roll", views.bus_roll, name="bus_roll"),
|
||||
path("summary", views.bus_summary, name="bus_summary"),
|
||||
]
|
||||
|
||||
@@ -2,80 +2,24 @@ 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 bus_roll_context, emergency_contacts_context
|
||||
from .context_helpers import *
|
||||
from .email_helpers import render_to_pdf
|
||||
from .models import Company, Bus, Traveller, BusStop, TravellerRoute, Shuttle, Driver
|
||||
|
||||
|
||||
@staff_member_required
|
||||
def bus_numbers(request):
|
||||
buses = []
|
||||
for bus in Bus.objects.all():
|
||||
|
||||
drivers = ""
|
||||
for driver in Driver.objects.filter(bus=bus):
|
||||
driver_name = f"{driver.first_name} {driver.last_name}"
|
||||
if drivers == "":
|
||||
drivers = driver_name
|
||||
else:
|
||||
drivers += f", {driver_name}"
|
||||
|
||||
route_travellers = Traveller.objects.filter(bus_stops__bus=bus).count()
|
||||
over_capacity = route_travellers > bus.seating_capacity
|
||||
shuttle = Shuttle.objects.filter(bus=bus).first()
|
||||
if shuttle:
|
||||
shuttle = shuttle.school.shortName
|
||||
shuttle_travellers = Traveller.objects.filter(shuttle__bus=bus).count()
|
||||
over_capacity = over_capacity or int(shuttle_travellers) > bus.seating_capacity
|
||||
else:
|
||||
shuttle = ""
|
||||
shuttle_travellers = ""
|
||||
buses.append({
|
||||
'route_name': bus.route_name,
|
||||
'drivers': drivers,
|
||||
'route_travellers': route_travellers,
|
||||
'shuttle': shuttle,
|
||||
'shuttle_travellers': shuttle_travellers,
|
||||
'seating_capacity': bus.seating_capacity,
|
||||
'over_capacity': over_capacity,
|
||||
})
|
||||
return render(request, 'reports/bus_numbers.html', {'buses': buses})
|
||||
def bus_summary(request):
|
||||
return render(request, 'reports/bus_summary.html', bus_summary_context())
|
||||
|
||||
|
||||
@staff_member_required
|
||||
def bus_summary(request, queryset=None):
|
||||
bus_routes = []
|
||||
if queryset is None:
|
||||
buses = Bus.objects.all()
|
||||
else:
|
||||
buses = queryset
|
||||
|
||||
for bus in buses:
|
||||
|
||||
drivers = ""
|
||||
for driver in Driver.objects.filter(bus=bus):
|
||||
driver_name = f"{driver.first_name} {driver.last_name}"
|
||||
if drivers == "":
|
||||
drivers = driver_name
|
||||
else:
|
||||
drivers += f", {driver_name}"
|
||||
|
||||
stops = []
|
||||
for bus_stop in BusStop.objects.filter(bus=bus):
|
||||
stops.append(bus_stop)
|
||||
|
||||
bus_routes.append({
|
||||
'bus': bus,
|
||||
'drivers': drivers,
|
||||
'stops': stops
|
||||
})
|
||||
return render(request, 'reports/bus_summary.html', {'routes': bus_routes})
|
||||
def emergency_contacts(request):
|
||||
return render_to_pdf('reports/emergency_contacts.html', emergency_contacts_context())
|
||||
|
||||
|
||||
@staff_member_required
|
||||
def emergency_contacts(request, queryset=None):
|
||||
pdf = render_to_pdf('reports/emergency_contacts.html', emergency_contacts_context(queryset))
|
||||
return pdf
|
||||
def bus_roll(request):
|
||||
return render_to_pdf('reports/bus_roll.html', bus_roll_context())
|
||||
|
||||
|
||||
@staff_member_required
|
||||
|
||||
Reference in New Issue
Block a user