134 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# backend/calendar_app/models.py
from django.contrib.auth import get_user_model
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
User = get_user_model()
class Recurrence(models.TextChoices):
ONE_TIME = "one_time", _("Одноразовое")
ANNUAL = "annual", _("Ежегодно")
class CompanyEvent(models.Model):
title = models.CharField(_("Название"), max_length=200)
description = models.TextField(_("Описание"), blank=True)
date = models.DateField(_("Дата события"))
recurrence = models.CharField(
_("Повторение"),
max_length=20,
choices=Recurrence.choices,
default=Recurrence.ONE_TIME,
)
color = models.CharField(
_("Цвет (hex)"), max_length=7, blank=True, help_text="#RRGGBB"
)
location = models.CharField(_("Локация"), max_length=200, blank=True)
created_by = models.ForeignKey(
User,
verbose_name=_("Создал"),
on_delete=models.SET_NULL, # ← ожидаемое поведение при удалении автора
null=True,
blank=True,
related_name="company_events_created",
)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _("Событие компании")
verbose_name_plural = _("События компании")
ordering = ["recurrence", "date"]
indexes = [
models.Index(fields=["date"]),
models.Index(
fields=["recurrence", "date"]
), # ← для сортировок по Meta.ordering
]
def __str__(self):
return f"{self.title} — {self.date:%d.%m.%Y}"
def get_absolute_url(self):
return reverse("calendar_app:company_calendar")
class DepartmentEvent(models.Model):
department = models.ForeignKey(
"employees.Department", # ← строковая ссылка без импорта
on_delete=models.CASCADE,
related_name="events",
verbose_name=_("Отдел"),
)
title = models.CharField(_("Название"), max_length=200)
description = models.TextField(_("Описание"), blank=True)
start_date = models.DateField(_("Дата начала"))
end_date = models.DateField(_("Дата окончания"), null=True, blank=True)
all_day = models.BooleanField(_("Весь день"), default=True)
recurrence = models.CharField(
_("Повторение"),
max_length=20,
choices=Recurrence.choices,
default=Recurrence.ONE_TIME,
)
color = models.CharField(
_("Цвет (hex)"), max_length=7, blank=True, help_text="#RRGGBB"
)
location = models.CharField(_("Локация"), max_length=200, blank=True)
created_by = models.ForeignKey(
User,
verbose_name=_("Создал"),
on_delete=models.SET_NULL, # ← автор может быть удалён
null=True,
blank=True,
related_name="department_events_created",
)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = _("Событие отдела")
verbose_name_plural = _("События отделов")
ordering = ["department", "start_date"]
indexes = [
models.Index(fields=["department", "start_date"]),
models.Index(
fields=["department", "recurrence", "start_date"]
), # ← фильтр/сорт по отделу+типу
models.Index(fields=["start_date", "end_date"]),
]
constraints = [
models.CheckConstraint(
name="dept_event_date_range_valid",
check=(
models.Q(end_date__isnull=True)
| models.Q(start_date__isnull=True)
| models.Q(start_date__lte=models.F("end_date"))
),
),
]
permissions = [
("manage_department_events", "Can create/update/delete department events"),
]
def __str__(self):
if self.end_date:
return f"{self.department}: {self.title} ({self.start_date:%d.%m.%Y}–{self.end_date:%d.%m.%Y})"
return f"{self.department}: {self.title} ({self.start_date:%d.%m.%Y})"
def clean(self):
# UX-валидация до попытки сохранить в БД
if self.end_date and self.start_date and self.end_date < self.start_date:
from django.core.exceptions import ValidationError
raise ValidationError(
{"end_date": _("Дата окончания не может быть раньше даты начала.")}
)
def get_absolute_url(self):
return reverse("calendar_app:department_calendar", args=[self.department_id])