75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
from datetime import date, timedelta
|
|
from typing import Optional
|
|
from uuid import uuid4
|
|
|
|
from django.db import models, IntegrityError
|
|
from django.utils import timezone
|
|
|
|
import library
|
|
|
|
|
|
class PersonQuerySet(models.QuerySet):
|
|
"""
|
|
Manager for people.
|
|
|
|
"""
|
|
|
|
def employees(self) -> models.QuerySet:
|
|
"""Get only employees."""
|
|
return self.filter(role=Person.Role.EMPLOYEE)
|
|
|
|
def clients(self) -> models.QuerySet:
|
|
"""Get only clients."""
|
|
return self.filter(role=Person.Role.CLIENT)
|
|
|
|
|
|
class Person(models.Model):
|
|
"""
|
|
Base class for people, employees and clients.
|
|
|
|
"""
|
|
|
|
class Role(models.IntegerChoices):
|
|
EMPLOYEE = 0, "employee"
|
|
CLIENT = 1, "client"
|
|
|
|
role = models.PositiveSmallIntegerField(default=0, choices=Role.choices, db_index=True, verbose_name="role")
|
|
user = models.OneToOneField("auth.User", on_delete=models.SET_NULL, null=True, blank=True, related_name="person")
|
|
uuid = models.UUIDField(default=uuid4, db_index=True, verbose_name="UUID")
|
|
first_name = models.CharField(max_length=64, blank=False, verbose_name="first name")
|
|
last_name = models.CharField(max_length=64, blank=False, verbose_name="last name")
|
|
birth_date = models.DateField(default=date(2000, 1, 1), verbose_name="birth date")
|
|
creation_date = models.DateTimeField(auto_now_add=True, verbose_name="creation date")
|
|
picture = models.ImageField(max_length=256, null=True, blank=True, upload_to="pictures", verbose_name="picture")
|
|
objects = PersonQuerySet.as_manager()
|
|
|
|
class Meta:
|
|
verbose_name = "person"
|
|
verbose_name_plural = "people"
|
|
|
|
def __str__(self):
|
|
return f"{self.get_full_name()} ({self.get_role_display()})"
|
|
|
|
def get_full_name(self):
|
|
return f"{self.first_name} {self.last_name}"
|
|
|
|
def borrow(self, book: "library.models.Book", duration: int = 7) -> Optional["library.models.Loan"]:
|
|
"""
|
|
Borrow a book.
|
|
|
|
Args:
|
|
book: book instance to borrow
|
|
duration: expected duration of loan in days
|
|
|
|
Returns:
|
|
If the book can be borrowed, return the new `Loan` object.
|
|
If not, return `None`.
|
|
|
|
"""
|
|
try:
|
|
deadline = timezone.now() + timedelta(days=duration)
|
|
loan = self.loans.create(person=self, book=book, expected_return=deadline)
|
|
return loan
|
|
except IntegrityError:
|
|
return None
|