Created new models to replicate out of and split coord app
Moved helpers and views to their respective new apps
This commit is contained in:
@@ -1,3 +1,294 @@
|
||||
from datetime import datetime
|
||||
|
||||
import phonenumbers
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
from common.models import Suburb
|
||||
|
||||
|
||||
class School(models.Model):
|
||||
name = models.CharField(max_length=30, unique=True)
|
||||
shortName = models.CharField(max_length=10, unique=True)
|
||||
address = models.CharField(max_length=50)
|
||||
suburb = models.ForeignKey(Suburb, on_delete=models.CASCADE)
|
||||
email = models.CharField(max_length=50, blank=True)
|
||||
phone = models.CharField(max_length=15, blank=True)
|
||||
principal_name = models.CharField(max_length=50, blank=True)
|
||||
principal_phone = models.CharField(max_length=15, blank=True)
|
||||
notes = models.TextField(blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Traveller(models.Model):
|
||||
YEAR = [
|
||||
("PS", "PreSchool"),
|
||||
("00", "Year 00"),
|
||||
("01", "Year 01"),
|
||||
("02", "Year 02"),
|
||||
("03", "Year 03"),
|
||||
("04", "Year 04"),
|
||||
("05", "Year 05"),
|
||||
("06", "Year 06"),
|
||||
("07", "Year 07"),
|
||||
("08", "Year 08"),
|
||||
("09", "Year 09"),
|
||||
("10", "Year 10"),
|
||||
("11", "Year 11"),
|
||||
("12", "Year 12"),
|
||||
("AL", "Adult Learner"),
|
||||
]
|
||||
|
||||
ELIGIBILITY_STATUS = [
|
||||
("1", "Eligible"),
|
||||
("2", "Ineligible"),
|
||||
("3", "<4.8 Exemption"),
|
||||
("4", "Eligible waitlisted"),
|
||||
("5", "Ineligible waitlisted"),
|
||||
("6", "Kinder Exemption"),
|
||||
("7", "Tafe/Post Secondary Exemption"),
|
||||
("8", "Other Exemption"),
|
||||
]
|
||||
|
||||
school = models.ForeignKey(School, on_delete=models.PROTECT)
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
dob = models.DateField(blank=True, null=True)
|
||||
year_level = models.CharField(max_length=2, choices=YEAR)
|
||||
bus_stops = models.ManyToManyField("transport.BusStop", through='TravellerRoute', blank=True)
|
||||
distance_to_school = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||
address = models.CharField(max_length=100, default="")
|
||||
|
||||
travel_start_date = models.DateField(blank=True, null=True)
|
||||
travel_end_date = models.DateField(blank=True, null=True)
|
||||
eligibility_status = models.CharField(max_length=1, choices=ELIGIBILITY_STATUS)
|
||||
assessment_date = models.DateField(blank=True, null=True)
|
||||
fee_per_term = models.DecimalField(decimal_places=2, max_digits=5, blank=True, null=True)
|
||||
term_1_paid = models.BooleanField(default=False)
|
||||
term_2_paid = models.BooleanField(default=False)
|
||||
term_3_paid = models.BooleanField(default=False)
|
||||
term_4_paid = models.BooleanField(default=False)
|
||||
application_form_completed = models.BooleanField()
|
||||
parent_notified = models.BooleanField()
|
||||
seat_number = models.CharField(max_length=5, blank=True)
|
||||
|
||||
created_on = models.DateTimeField(auto_now_add=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_active = models.BooleanField(default=False, verbose_name='Active')
|
||||
notes = models.TextField(blank=True, verbose_name='Admin Notes')
|
||||
shuttle = models.ForeignKey("transport.Shuttle", on_delete=models.SET_NULL, blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["last_name", "first_name"]
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self._update_active_status()
|
||||
self._repopulate_address()
|
||||
super(Traveller, self).save(*args, **kwargs)
|
||||
|
||||
def _is_active(self, date=None):
|
||||
if date is None:
|
||||
today = datetime.today()
|
||||
date = datetime(today.year, today.month, today.day)
|
||||
|
||||
if not self.travel_start_date or datetime(self.travel_start_date.year, self.travel_start_date.month, self.travel_start_date.day) > date:
|
||||
return False
|
||||
if not self.travel_end_date:
|
||||
return True
|
||||
|
||||
end_date = datetime(self.travel_end_date.year, self.travel_end_date.month, self.travel_end_date.day)
|
||||
return end_date >= date
|
||||
|
||||
def _update_active_status(self):
|
||||
new_start_date = None
|
||||
new_end_date = None
|
||||
|
||||
for travellerRoute in TravellerRoute.objects.filter(traveller=self.id):
|
||||
route_start = travellerRoute.travel_start_date
|
||||
route_end = travellerRoute.travel_end_date
|
||||
if route_start is not None:
|
||||
if new_start_date is None or new_start_date > route_start:
|
||||
new_start_date = route_start
|
||||
if route_end is not None:
|
||||
if new_end_date is None or new_end_date < route_end:
|
||||
new_end_date = route_end
|
||||
|
||||
self.travel_start_date = new_start_date
|
||||
self.travel_end_date = new_end_date
|
||||
self.is_active = self._is_active()
|
||||
|
||||
def fare_paying(self):
|
||||
if self.eligibility_status != "2":
|
||||
return
|
||||
cost_setting = 0
|
||||
|
||||
if not cost_setting.exists():
|
||||
return "TERM_TRAVEL_COST not configured"
|
||||
|
||||
cost = int(cost_setting.get().value)
|
||||
|
||||
stops = 0
|
||||
for stop in TravellerRoute.objects.filter(traveller=self.id):
|
||||
stops += stop.active_stops()
|
||||
if stops > 1:
|
||||
stops = 1
|
||||
return f"${round(cost*stops)}"
|
||||
|
||||
def _repopulate_address(self):
|
||||
families = self.get_families()
|
||||
if families.count() == 0:
|
||||
self.address = ""
|
||||
elif families.count() == 1:
|
||||
family = families.first()
|
||||
self.address = f"{family.residential_address} {family.residential_suburb}"
|
||||
else:
|
||||
self.address = "Multiple"
|
||||
|
||||
def get_families(self):
|
||||
return Family.objects.filter(traveller__id__exact=self.id)
|
||||
|
||||
|
||||
class Family(models.Model):
|
||||
RELATIONS = [
|
||||
("1", "Parent"),
|
||||
("2", "Step-Parent"),
|
||||
("3", "Foster Parent"),
|
||||
("4", "Host Family"),
|
||||
("5", "Sibling"),
|
||||
("6", "Grandparent"),
|
||||
("7", "Aunt/Uncle"),
|
||||
("8", "Cousin"),
|
||||
("9", "Carer"),
|
||||
("10", "Case Worker"),
|
||||
("11", "Friend/Other"),
|
||||
]
|
||||
|
||||
traveller = models.ForeignKey(Traveller, on_delete=models.CASCADE)
|
||||
residential_address = models.CharField(max_length=50, blank=True)
|
||||
residential_suburb = models.ForeignKey(Suburb, on_delete=models.PROTECT, blank=True, null=True,
|
||||
related_name='family_residential_suburb')
|
||||
postal_address = models.CharField(max_length=50, blank=True)
|
||||
postal_suburb = models.ForeignKey(Suburb, on_delete=models.PROTECT, blank=True, null=True,
|
||||
related_name='family_postal_suburb')
|
||||
parent_A_firstname = models.CharField(max_length=50, blank=True)
|
||||
parent_A_lastname = models.CharField(max_length=50, blank=True)
|
||||
parent_A_phone = models.CharField(max_length=15, blank=True)
|
||||
parent_A_email = models.CharField(max_length=50, blank=True)
|
||||
parent_B_firstname = models.CharField(max_length=50, blank=True)
|
||||
parent_B_lastname = models.CharField(max_length=50, blank=True)
|
||||
parent_B_phone = models.CharField(max_length=15, blank=True)
|
||||
parent_B_email = models.CharField(max_length=50, blank=True)
|
||||
emergency_contact_A_firstname = models.CharField(max_length=50, blank=True)
|
||||
emergency_contact_A_lastname = models.CharField(max_length=50, blank=True)
|
||||
emergency_contact_A_phone = models.CharField(max_length=15, blank=True)
|
||||
emergency_contact_A_relation = models.CharField(max_length=50, choices=RELATIONS, blank=True)
|
||||
emergency_contact_B_firstname = models.CharField(max_length=50, blank=True)
|
||||
emergency_contact_B_lastname = models.CharField(max_length=50, blank=True)
|
||||
emergency_contact_B_phone = models.CharField(max_length=15, blank=True)
|
||||
emergency_contact_B_relation = models.CharField(max_length=50, choices=RELATIONS, blank=True)
|
||||
created_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
|
||||
last_edit = models.DateTimeField(auto_now=True, blank=True, null=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = "Families"
|
||||
|
||||
def __str__(self):
|
||||
return self.parent_names()
|
||||
|
||||
def clean(self):
|
||||
valid_numbers, failed_numbers = self.get_parsed_numbers(True, True)
|
||||
if len(failed_numbers) > 0:
|
||||
raise ValidationError(f"Phone number {failed_numbers[0]} not valid")
|
||||
|
||||
def parent_names(self):
|
||||
a_name = self.parent_A_firstname
|
||||
b_name = self.parent_B_firstname
|
||||
if a_name:
|
||||
if b_name:
|
||||
return f"{a_name} and {b_name}"
|
||||
return a_name
|
||||
elif b_name:
|
||||
return b_name
|
||||
return ""
|
||||
|
||||
def get_parsed_numbers(self, parents=False, emergency=False):
|
||||
numbers = []
|
||||
if parents:
|
||||
if self.parent_A_phone:
|
||||
numbers.append(self.parent_A_phone)
|
||||
if self.parent_B_phone:
|
||||
numbers.append(self.parent_B_phone)
|
||||
if emergency:
|
||||
if self.emergency_contact_A_phone:
|
||||
numbers.append(self.emergency_contact_A_phone)
|
||||
if self.emergency_contact_B_phone:
|
||||
numbers.append(self.emergency_contact_B_phone)
|
||||
valid_numbers = []
|
||||
failed_numbers = []
|
||||
for number in numbers:
|
||||
try:
|
||||
num = phonenumbers.parse(number, "AU")
|
||||
if phonenumbers.is_valid_number(num):
|
||||
valid_numbers.append(f"+{num.country_code}{num.national_number}")
|
||||
else:
|
||||
failed_numbers.append(number)
|
||||
except:
|
||||
failed_numbers.append(number)
|
||||
|
||||
return valid_numbers, failed_numbers
|
||||
|
||||
|
||||
class TravellerRoute(models.Model):
|
||||
traveller = models.ForeignKey(Traveller, on_delete=models.CASCADE)
|
||||
busStop = models.ForeignKey("transport.BusStop", on_delete=models.CASCADE)
|
||||
travel_start_date = models.DateField(blank=True, null=True)
|
||||
travel_end_date = models.DateField(blank=True, null=True)
|
||||
mon_am = models.BooleanField(default=True)
|
||||
mon_pm = models.BooleanField(default=True)
|
||||
tue_am = models.BooleanField(default=True)
|
||||
tue_pm = models.BooleanField(default=True)
|
||||
wen_am = models.BooleanField(default=True)
|
||||
wen_pm = models.BooleanField(default=True)
|
||||
thu_am = models.BooleanField(default=True)
|
||||
thu_pm = models.BooleanField(default=True)
|
||||
fri_am = models.BooleanField(default=True)
|
||||
fri_pm = models.BooleanField(default=True)
|
||||
notes = models.TextField(blank=True, verbose_name="Driver Notes")
|
||||
created_on = models.DateTimeField(auto_now_add=True, blank=True, null=True)
|
||||
last_edit = models.DateTimeField(auto_now=True, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.busStop}"
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super(TravellerRoute, self).save(*args, **kwargs)
|
||||
self.traveller.save()
|
||||
|
||||
def active_stops(self):
|
||||
stops = 0
|
||||
if self.mon_am:
|
||||
stops += 1
|
||||
if self.mon_pm:
|
||||
stops += 1
|
||||
if self.tue_am:
|
||||
stops += 1
|
||||
if self.tue_pm:
|
||||
stops += 1
|
||||
if self.wen_am:
|
||||
stops += 1
|
||||
if self.wen_pm:
|
||||
stops += 1
|
||||
if self.thu_am:
|
||||
stops += 1
|
||||
if self.thu_pm:
|
||||
stops += 1
|
||||
if self.fri_am:
|
||||
stops += 1
|
||||
if self.fri_pm:
|
||||
stops += 1
|
||||
return stops * 0.1
|
||||
|
||||
Reference in New Issue
Block a user