85 lines
2.9 KiB
Python
Executable File
85 lines
2.9 KiB
Python
Executable File
from django.db import models
|
|
from django.db.models import Q
|
|
from django.urls import reverse
|
|
|
|
from app.base.forms.fields import DateField
|
|
from app.base.models.course import Course
|
|
from app.base.models.booking import Booking
|
|
|
|
from datetime import datetime
|
|
from typing import TYPE_CHECKING
|
|
if TYPE_CHECKING:
|
|
from app.base.models import Account, Note, CourseVisit, TraitMapping
|
|
|
|
|
|
class Person(models.Model):
|
|
uuid = models.CharField('Karten-ID', max_length=200, blank=True)
|
|
|
|
first_name = models.CharField('Vorname', max_length=200)
|
|
last_name = models.CharField('Nachname', max_length=200)
|
|
email = models.EmailField('Email', blank=True, null=True)
|
|
phone = models.CharField('Telefon', max_length=200, blank=True, null=True)
|
|
birth_date = DateField('Geburtsdatum')
|
|
zip_code = models.CharField('PLZ', max_length=10)
|
|
city = models.CharField('Stadt', max_length=200)
|
|
street = models.CharField('Straße', max_length=200)
|
|
house_nr = models.CharField('Hausnummer', max_length=10)
|
|
|
|
identified = models.BooleanField('Ausweis vorgezeigt', default=False)
|
|
agreed_to_terms_of_service = models.BooleanField(
|
|
'Nutzungsbedingungen zugestimmt', default=False)
|
|
|
|
# related_name
|
|
account: 'models.OneToOneField[Account]'
|
|
note: 'models.OneToOneField[Note]'
|
|
courses: 'models.QuerySet[CourseVisit]'
|
|
instructed: 'models.QuerySet[CourseVisit]'
|
|
traits: 'models.QuerySet[TraitMapping]'
|
|
|
|
class Meta:
|
|
verbose_name = 'Werkstattnutzer:in'
|
|
verbose_name_plural = 'Werkstattnutzer:innen'
|
|
# ordering = ('first_name', 'last_name')
|
|
# indexes = [
|
|
# models.Index(fields=['first_name', 'last_name']),
|
|
# models.Index(Latest,fields=["first_name"],name="first_name_idx"),
|
|
# ]
|
|
|
|
def get_absolute_url(self):
|
|
return reverse('person:detail', kwargs={'pk': self.pk})
|
|
|
|
def __str__(self):
|
|
return f'{self.first_name} {self.last_name}'
|
|
|
|
@property
|
|
def display_name(self):
|
|
return f'{self.first_name} {self.last_name}'
|
|
|
|
@property
|
|
def address(self):
|
|
return f'{self.street} {self.house_nr}, {self.zip_code} {self.city}'
|
|
|
|
@property
|
|
def missing_courses(self):
|
|
mandatory_courses = Course.objects.filter(mandatory=True)
|
|
completed = set(self.courses.values_list('course', flat=True))
|
|
return [x for x in mandatory_courses if x.pk not in completed]
|
|
|
|
@property
|
|
def attributes(self):
|
|
return self.traits_at_date(datetime.now()).values_list(
|
|
'pk', 'trait__key', 'trait__label')
|
|
|
|
def traits_at_date(self, date: datetime):
|
|
return self.traits.filter(
|
|
Q(valid_from__lte=date),
|
|
Q(valid_until__gte=date) | Q(valid_until=None))
|
|
|
|
def last_check_in(self) -> 'datetime|None':
|
|
obj = Booking.latest_checkin_query(self).first()
|
|
return obj['begin_time'] if obj else None
|
|
|
|
@property
|
|
def current_checkin(self):
|
|
return Booking.currently_open_checkin(self)
|