svthalia/concrexit

View on GitHub
website/documents/models.py

Summary

Maintainability
A
0 mins
Test Coverage
from django.core.validators import FileExtensionValidator, MinValueValidator
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _


class Document(models.Model):
    """Describes a base document."""

    class Meta:
        verbose_name = _("Document")
        verbose_name_plural = _("Documents")

    DOCUMENT_CATEGORIES = (
        ("annual", _("Annual document")),
        ("association", _("Association document")),
        ("event", _("Event document")),
        ("minutes", _("Minutes")),
        ("misc", _("Miscellaneous document")),
    )

    name = models.CharField(verbose_name=_("name"), max_length=200)

    created = models.DateTimeField(
        verbose_name=_("created"),
        auto_now_add=True,
    )

    last_updated = models.DateTimeField(verbose_name=_("last updated"), auto_now=True)

    category = models.CharField(
        max_length=40,
        choices=DOCUMENT_CATEGORIES,
        verbose_name=_("category"),
        default="misc",
    )

    file = models.FileField(
        verbose_name=_("file"),
        upload_to="documents/",
        validators=[FileExtensionValidator(["txt", "pdf", "jpg", "jpeg", "png"])],
    )

    members_only = models.BooleanField(verbose_name=_("members only"), default=True)

    def get_absolute_url(self):
        return reverse("documents:document", kwargs={"pk": self.pk})

    def __str__(self):
        return f"{self.name} ({self.created.date()})"


class AnnualDocument(Document):
    """Describes an annual document."""

    class Meta:
        verbose_name = _("Annual document")
        verbose_name_plural = _("Annual documents")
        unique_together = ("subcategory", "year")

    SUBCATEGORIES = (
        ("report", _("Annual report")),
        ("financial", _("Financial report")),
        ("policy", _("Policy document")),
    )

    subcategory = models.CharField(
        max_length=40,
        choices=SUBCATEGORIES,
        verbose_name=_("category"),
        default="report",
    )

    year = models.IntegerField(
        verbose_name=_("year"),
        validators=[MinValueValidator(1990)],
    )

    def save(self, **kwargs):
        self.category = "annual"
        if self.subcategory == "report":
            self.name = f"Annual report {self.year}"
        elif self.subcategory == "financial":
            self.name = f"Financial report {self.year}"
        else:
            self.name = f"Policy document {self.year}"
        super().save(**kwargs)


class AssociationDocumentManager(models.Manager):
    """Custom manager to filter for association documents."""

    def get_queryset(self):
        return super().get_queryset().filter(category="association")


class AssociationDocument(Document):
    """Describes an association document."""

    class Meta:
        verbose_name = _("Miscellaneous association document")
        verbose_name_plural = _("Miscellaneous association documents")
        proxy = True

    objects = AssociationDocumentManager()

    def save(self, **kwargs):
        self.category = "association"
        super().save(**kwargs)


class MiscellaneousDocumentManager(models.Manager):
    """Custom manager to filter for misc documents."""

    def get_queryset(self):
        return super().get_queryset().filter(category="misc")


class MiscellaneousDocument(Document):
    """Describes a miscellaneous document."""

    class Meta:
        ordering = ["-created"]
        verbose_name = _("Miscellaneous document")
        verbose_name_plural = _("Miscellaneous documents")
        proxy = True

    objects = MiscellaneousDocumentManager()

    def save(self, **kwargs):
        self.category = "misc"
        super().save(**kwargs)


class GeneralMeeting(models.Model):
    """Describes a general meeting."""

    class Meta:
        verbose_name = _("General meeting")
        verbose_name_plural = _("General meetings")
        ordering = ["datetime"]

    documents = models.ManyToManyField(
        Document,
        verbose_name=_("documents"),
        blank=True,
    )

    datetime = models.DateTimeField(
        verbose_name=_("datetime"),
    )

    location = models.CharField(verbose_name=_("location"), max_length=200)

    def __str__(self):
        return timezone.localtime(self.datetime).strftime("%Y-%m-%d")


class Minutes(Document):
    """Describes a minutes document."""

    class Meta:
        verbose_name = _("Minutes")
        verbose_name_plural = _("Minutes")

    meeting = models.OneToOneField(
        GeneralMeeting, blank=True, null=True, on_delete=models.CASCADE
    )

    def save(self, **kwargs):
        self.category = "minutes"
        self.name = f"Minutes {self.meeting.datetime.date()}"
        super().save(**kwargs)