Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -67,7 +67,8 @@ MIDDLEWARE = [
|
|||||||
if "AZURE_CLIENT_ID" in os.environ:
|
if "AZURE_CLIENT_ID" in os.environ:
|
||||||
AUTHENTICATION_BACKENDS = ("custom_user.backends.AzureBackend",)
|
AUTHENTICATION_BACKENDS = ("custom_user.backends.AzureBackend",)
|
||||||
MIDDLEWARE.append('custom_user.middleware.AzureMiddleware')
|
MIDDLEWARE.append('custom_user.middleware.AzureMiddleware')
|
||||||
LOGIN_URL = "/azure_auth/login"
|
LOGIN_URL = "/auth/login"
|
||||||
|
LOGOUT_REDIRECT_URL = "/auth/logout"
|
||||||
AZURE_AUTH = {
|
AZURE_AUTH = {
|
||||||
"CLIENT_ID": os.environ.get('AZURE_CLIENT_ID'),
|
"CLIENT_ID": os.environ.get('AZURE_CLIENT_ID'),
|
||||||
"CLIENT_SECRET": os.environ.get('AZURE_CLIENT_SECRET'),
|
"CLIENT_SECRET": os.environ.get('AZURE_CLIENT_SECRET'),
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ Including another URLconf
|
|||||||
1. Import the include() function: from django.urls import include, path
|
1. Import the include() function: from django.urls import include, path
|
||||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||||
"""
|
"""
|
||||||
from azure_auth.views import azure_auth_logout
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
@@ -22,8 +21,7 @@ admin.site.site_header = "Bus Portal Admin"
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('report/', include("coord.urls")),
|
path('report/', include("coord.urls")),
|
||||||
path('logout/', azure_auth_logout),
|
path('auth/', include("custom_user.urls")),
|
||||||
path('auth/', include("azure_auth.urls"),),
|
|
||||||
path('settings/', include('coord.urls_settings')),
|
path('settings/', include('coord.urls_settings')),
|
||||||
path('', admin.site.urls),
|
path('', admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
import csv
|
import csv
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from django.contrib.admin import DateFieldListFilter, BooleanFieldListFilter
|
|
||||||
from django.forms import widgets
|
from django.forms import widgets
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.html import format_html
|
from django.utils.html import format_html
|
||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
from django.utils.translation import gettext_lazy
|
|
||||||
from import_export.admin import ImportExportModelAdmin
|
from import_export.admin import ImportExportModelAdmin
|
||||||
from rangefilter.filters import DateRangeFilterBuilder
|
from rangefilter.filters import DateRangeFilterBuilder
|
||||||
|
|
||||||
@@ -159,7 +157,7 @@ class BusStopAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
|
|||||||
search_fields = ["bus__route_name", "address"]
|
search_fields = ["bus__route_name", "address"]
|
||||||
|
|
||||||
|
|
||||||
# @admin.register(Suburb)
|
@admin.register(Suburb)
|
||||||
class SuburbsAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
|
class SuburbsAdmin(MyImportExportModelAdmin, admin.ModelAdmin):
|
||||||
list_filter = ["state"]
|
list_filter = ["state"]
|
||||||
|
|
||||||
@@ -171,7 +169,7 @@ class TravellerRouteInline(admin.TabularInline):
|
|||||||
|
|
||||||
@admin.register(Traveller)
|
@admin.register(Traveller)
|
||||||
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin, TravellerRollMixin):
|
class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin, TravellerRollMixin):
|
||||||
list_display = ["first_name", "last_name", "school", "year_level", "residential_address", "residential_suburb", "stop_route", "shuttle", "travel_start_date", "travel_end_date"]
|
list_display = ["first_name", "last_name", "school", "year_level", "is_active", "residential_address", "residential_suburb", "stop_route", "shuttle", "travel_start_date", "travel_end_date"]
|
||||||
list_filter = [
|
list_filter = [
|
||||||
"is_active", "school", "year_level", "eligibility_status", "bus_stops__bus", "shuttle", "residential_suburb",
|
"is_active", "school", "year_level", "eligibility_status", "bus_stops__bus", "shuttle", "residential_suburb",
|
||||||
("travel_start_date", DateRangeFilterBuilder(
|
("travel_start_date", DateRangeFilterBuilder(
|
||||||
@@ -195,6 +193,7 @@ class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin
|
|||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None, {
|
(None, {
|
||||||
'fields': [
|
'fields': [
|
||||||
|
"is_active",
|
||||||
"school",
|
"school",
|
||||||
"first_name",
|
"first_name",
|
||||||
"last_name",
|
"last_name",
|
||||||
@@ -229,7 +228,6 @@ class TravellerAdmin(MyImportExportModelAdmin, CloneModelAdmin, admin.ModelAdmin
|
|||||||
"seat_number",
|
"seat_number",
|
||||||
"created_on",
|
"created_on",
|
||||||
"last_edit",
|
"last_edit",
|
||||||
"is_active",
|
|
||||||
]
|
]
|
||||||
}),
|
}),
|
||||||
('Adult Contacts', {
|
('Adult Contacts', {
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
from django.forms import model_to_dict
|
||||||
|
|
||||||
|
from coord.models import *
|
||||||
|
|
||||||
|
|
||||||
|
def get_export_dict():
|
||||||
|
suburbs = []
|
||||||
|
schools = []
|
||||||
|
companies = []
|
||||||
|
travellers = []
|
||||||
|
|
||||||
|
for suburb in Suburb.objects.all():
|
||||||
|
suburbs.append(model_to_dict(suburb))
|
||||||
|
|
||||||
|
for school in School.objects.all():
|
||||||
|
school_dict = model_to_dict(school)
|
||||||
|
school_dict['suburb'] = school.suburb.name
|
||||||
|
schools.append(school_dict)
|
||||||
|
|
||||||
|
for company in Company.objects.all():
|
||||||
|
company_dict = model_to_dict(company)
|
||||||
|
company_dict['suburb'] = company.suburb.name
|
||||||
|
buses = []
|
||||||
|
for bus in Bus.objects.filter(company=company):
|
||||||
|
bus_dict = model_to_dict(bus)
|
||||||
|
bus_dict.pop('company')
|
||||||
|
drivers = []
|
||||||
|
shuttles = []
|
||||||
|
bus_stops = []
|
||||||
|
|
||||||
|
for driver in Driver.objects.filter(bus=bus):
|
||||||
|
driver_dict = model_to_dict(driver)
|
||||||
|
driver_dict.pop('bus')
|
||||||
|
drivers.append(driver_dict)
|
||||||
|
|
||||||
|
for shuttle in Shuttle.objects.filter(bus=bus):
|
||||||
|
shuttle_dict = model_to_dict(shuttle)
|
||||||
|
shuttle_dict.pop('bus')
|
||||||
|
shuttles.append(shuttle_dict)
|
||||||
|
|
||||||
|
for busStop in BusStop.objects.filter(bus=bus):
|
||||||
|
bus_stop_dict = model_to_dict(busStop)
|
||||||
|
bus_stop_dict.pop('bus')
|
||||||
|
bus_stop_dict['am_time'] = busStop.am_time.strftime("%H:%M:%S")
|
||||||
|
bus_stop_dict['pm_time'] = busStop.pm_time.strftime("%H:%M:%S")
|
||||||
|
bus_stops.append(bus_stop_dict)
|
||||||
|
|
||||||
|
bus_dict['drivers'] = drivers
|
||||||
|
bus_dict['shuttles'] = shuttles
|
||||||
|
bus_dict['bus_stops'] = bus_stops
|
||||||
|
buses.append(bus_dict)
|
||||||
|
company_dict['buses'] = buses
|
||||||
|
companies.append(company_dict)
|
||||||
|
|
||||||
|
for traveller in Traveller.objects.all():
|
||||||
|
traveller_dict = model_to_dict(traveller)
|
||||||
|
traveller_dict['school'] = traveller.school.name
|
||||||
|
if traveller.residential_suburb is not None:
|
||||||
|
traveller_dict['residential_suburb'] = traveller.residential_suburb.name
|
||||||
|
if traveller.postal_suburb is not None:
|
||||||
|
traveller_dict['postal_suburb'] = traveller.postal_suburb.name
|
||||||
|
if traveller.dob is not None:
|
||||||
|
traveller_dict['dob'] = traveller.dob.strftime("%Y-%m-%d")
|
||||||
|
traveller_dict.pop('travel_start_date')
|
||||||
|
traveller_dict.pop('travel_end_date')
|
||||||
|
routes = []
|
||||||
|
for route in TravellerRoute.objects.filter(traveller=traveller):
|
||||||
|
route_dict = model_to_dict(route)
|
||||||
|
route_dict.pop('traveller')
|
||||||
|
route_dict['name'] = route.busStop.__str__()
|
||||||
|
if route.travel_start_date is not None:
|
||||||
|
route_dict['travel_start_date'] = route.travel_start_date.strftime("%Y-%m-%d")
|
||||||
|
if route.travel_end_date is not None:
|
||||||
|
route_dict['travel_end_date'] = route.travel_end_date.strftime("%Y-%m-%d")
|
||||||
|
routes.append(route_dict)
|
||||||
|
traveller_dict['bus_stops'] = routes
|
||||||
|
travellers.append(traveller_dict)
|
||||||
|
|
||||||
|
return {'suburbs': suburbs, 'schools': schools, 'companies': companies, 'travellers': travellers}
|
||||||
@@ -234,7 +234,7 @@ class Traveller(models.Model):
|
|||||||
created_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
|
created_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
|
||||||
last_edit = models.DateTimeField(auto_now=True, blank=True, null=True)
|
last_edit = models.DateTimeField(auto_now=True, blank=True, null=True)
|
||||||
is_archived = models.BooleanField(default=False, verbose_name="Archived")
|
is_archived = models.BooleanField(default=False, verbose_name="Archived")
|
||||||
is_active = models.BooleanField(default=True, verbose_name='Active')
|
is_active = models.BooleanField(default=False, verbose_name='Active')
|
||||||
notes = models.TextField(blank=True, verbose_name='Admin Notes')
|
notes = models.TextField(blank=True, verbose_name='Admin Notes')
|
||||||
shuttle = models.ForeignKey(Shuttle, on_delete=models.SET_NULL, blank=True, null=True)
|
shuttle = models.ForeignKey(Shuttle, on_delete=models.SET_NULL, blank=True, null=True)
|
||||||
|
|
||||||
@@ -244,6 +244,10 @@ class Traveller(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.first_name} {self.last_name}"
|
return f"{self.first_name} {self.last_name}"
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
self._update_active_status()
|
||||||
|
super(Traveller, self).save(*args, **kwargs)
|
||||||
|
|
||||||
def _is_active(self):
|
def _is_active(self):
|
||||||
today = datetime.today()
|
today = datetime.today()
|
||||||
today = datetime(today.year, today.month, today.day)
|
today = datetime(today.year, today.month, today.day)
|
||||||
@@ -255,7 +259,7 @@ class Traveller(models.Model):
|
|||||||
end_date = datetime(self.travel_end_date.year, self.travel_end_date.month, self.travel_end_date.day)
|
end_date = datetime(self.travel_end_date.year, self.travel_end_date.month, self.travel_end_date.day)
|
||||||
return end_date >= today
|
return end_date >= today
|
||||||
|
|
||||||
def update_active_status(self):
|
def _update_active_status(self):
|
||||||
new_start_date = None
|
new_start_date = None
|
||||||
new_end_date = None
|
new_end_date = None
|
||||||
|
|
||||||
@@ -270,21 +274,9 @@ class Traveller(models.Model):
|
|||||||
if new_end_date is None or new_end_date < route_end:
|
if new_end_date is None or new_end_date < route_end:
|
||||||
new_end_date = route_end
|
new_end_date = route_end
|
||||||
|
|
||||||
updated = False
|
|
||||||
if self.travel_start_date != new_start_date:
|
|
||||||
self.travel_start_date = new_start_date
|
self.travel_start_date = new_start_date
|
||||||
updated = True
|
|
||||||
if self.travel_end_date != new_end_date:
|
|
||||||
self.travel_end_date = new_end_date
|
self.travel_end_date = new_end_date
|
||||||
updated = True
|
self.is_active = self._is_active()
|
||||||
|
|
||||||
is_active = self._is_active()
|
|
||||||
if self.is_active != is_active:
|
|
||||||
self.is_active = is_active
|
|
||||||
updated = True
|
|
||||||
|
|
||||||
if updated:
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
def fare_paying(self):
|
def fare_paying(self):
|
||||||
if self.eligibility_status != "2":
|
if self.eligibility_status != "2":
|
||||||
@@ -347,7 +339,7 @@ class TravellerRoute(models.Model):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
super(TravellerRoute, self).save(*args, **kwargs)
|
super(TravellerRoute, self).save(*args, **kwargs)
|
||||||
# self.traveller.update_active_status()
|
self.traveller.save()
|
||||||
|
|
||||||
def active_stops(self):
|
def active_stops(self):
|
||||||
stops = 0
|
stops = 0
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
from coord.models import Traveller
|
from .models import Traveller
|
||||||
|
|
||||||
|
|
||||||
def nightly_check_active_status():
|
def nightly_check_active_status():
|
||||||
for traveller in Traveller.objects.all():
|
for traveller in Traveller.objects.all():
|
||||||
traveller.update_active_status()
|
start_date = traveller.travel_start_date
|
||||||
|
end_date = traveller.travel_end_date
|
||||||
|
is_active = traveller.is_active
|
||||||
|
traveller._update_active_status()
|
||||||
|
if start_date != traveller.travel_start_date or end_date != traveller.travel_end_date or is_active != traveller.is_active:
|
||||||
|
traveller.save()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div><a href={% url 'settings:nightly_task' %}>Run nightly task</a></div>
|
<div><a href={% url 'settings:nightly_task' %}>Run nightly task</a></div>
|
||||||
|
<div><a href={% url 'settings:export' %}>Export</a></div>
|
||||||
<div>
|
<div>
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<label for="id_traveller_term_cost">
|
<label for="id_traveller_term_cost">
|
||||||
|
|||||||
@@ -6,5 +6,6 @@ app_name = "settings"
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('rollover', views_settings.rollover, name='rollover'),
|
path('rollover', views_settings.rollover, name='rollover'),
|
||||||
path('nightly_task', views_settings.nightly_task, name='nightly_task'),
|
path('nightly_task', views_settings.nightly_task, name='nightly_task'),
|
||||||
|
path('export', views_settings.export, name='export'),
|
||||||
path('', views_settings.settings, name='index'),
|
path('', views_settings.settings, name='index'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
from django.contrib.admin.views.decorators import staff_member_required
|
from django.contrib.admin.views.decorators import staff_member_required
|
||||||
|
from django.http import HttpResponse
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
|
|
||||||
from coord.scheduled_tasks import nightly_check_active_status
|
from coord.scheduled_tasks import nightly_check_active_status
|
||||||
from coord.utils.rollover import RolloverForm, execute_rollover
|
from coord.utils.rollover import RolloverForm, execute_rollover
|
||||||
|
|
||||||
|
from coord.backup.backup_helpers import get_export_dict
|
||||||
|
|
||||||
|
|
||||||
@staff_member_required
|
@staff_member_required
|
||||||
def settings(request):
|
def settings(request):
|
||||||
@@ -21,7 +27,16 @@ def rollover(request):
|
|||||||
form = RolloverForm()
|
form = RolloverForm()
|
||||||
return render(request, 'admin/rollover_form.html', context={'form': form})
|
return render(request, 'admin/rollover_form.html', context={'form': form})
|
||||||
|
|
||||||
|
|
||||||
@staff_member_required
|
@staff_member_required
|
||||||
def nightly_task(request):
|
def nightly_task(request):
|
||||||
nightly_check_active_status()
|
nightly_check_active_status()
|
||||||
return redirect('settings:index')
|
return redirect('settings:index')
|
||||||
|
|
||||||
|
|
||||||
|
@staff_member_required
|
||||||
|
def export(request):
|
||||||
|
date = datetime.date.today().strftime("%Y-%m-%d")
|
||||||
|
response = HttpResponse(json.dumps(get_export_dict()))
|
||||||
|
response['Content-Disposition'] = f'attachment; filename=busportal_export-{date}.json'
|
||||||
|
return response
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from django.urls import path
|
|||||||
|
|
||||||
from .views import azure_auth_callback, azure_auth_login, azure_auth_logout
|
from .views import azure_auth_callback, azure_auth_login, azure_auth_logout
|
||||||
|
|
||||||
app_name = "azure_auth"
|
app_name = "auth"
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("login", azure_auth_login, name="login"),
|
path("login", azure_auth_login, name="login"),
|
||||||
path("logout", azure_auth_logout, name="logout"),
|
path("logout", azure_auth_logout, name="logout"),
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user