Игорь Надеин 6fb2cdcea0 feat: enhance Employee model and integrate Telegram/WhatsApp bot
- Add birth_date, created_at/updated_at to Employee; remove username field
- Introduce EmployeeAction for tracking HR events and is_actually_active/status properties
- Create BotSubscriber model (OneToOne relation) for TG/WA binding
- Implement Aiogram-based Telegram bot:
  • request contact to bind by phone or @username
  • department selection keyboard from DEPARTMENTS dict
  • async ORM via sync_to_async, custom filters for bound & active employees
- Update profile view & template:
  • show “Bind Telegram/WhatsApp” button only when not already bound
  • preview avatar on upload
- Remove registration tokens in favor of contact-based auth
- Clean up templates, forms and add avatar validation mixin
2025-07-30 08:15:53 +03:00

57 lines
2.4 KiB
Python

# calendar_app/views.py
from rest_framework import generics
from django.utils.dateparse import parse_datetime, parse_date
from django.db.models import Q
from .models import CompanyEvent
from .serializers import CompanyEventSerializer
class CompanyEventListAPI(generics.ListAPIView):
serializer_class = CompanyEventSerializer
def get_queryset(self):
qs = CompanyEvent.objects.all()
start_str = self.request.query_params.get('start')
end_str = self.request.query_params.get('end')
if start_str and end_str:
# сначала пытаемся распарсить как datetime, иначе как date
dt_start = parse_datetime(start_str) or parse_date(start_str)
dt_end = parse_datetime(end_str) or parse_date(end_str)
# если получилось datetime, приводим к date
if hasattr(dt_start, 'date'):
start = dt_start.date()
else:
start = dt_start
if hasattr(dt_end, 'date'):
end = dt_end.date()
else:
end = dt_end
# если всё ещё нет корректных дат — вернём пустой qs
if not start or not end:
return CompanyEvent.objects.none()
# 1) одноразовые события внутри диапазона
one_time_q = Q(recurrence=CompanyEvent.ONE_TIME,
date__range=(start, end))
# 2) ежегодные события, чья (month, day) лежит в интервале [start, end]
annual_ids = []
for ev in CompanyEvent.objects.filter(recurrence=CompanyEvent.ANNUAL):
md = (ev.date.month, ev.date.day)
# простой кейс: диапазон в рамках одного года
if start.year == end.year:
if (start.month, start.day) <= md <= (end.month, end.day):
annual_ids.append(ev.pk)
else:
# диапазон пересёк границу года
if md >= (start.month, start.day) or md <= (end.month, end.day):
annual_ids.append(ev.pk)
annual_q = Q(pk__in=annual_ids)
return qs.filter(one_time_q | annual_q)
# если start/end не заданы — вернём всё
return qs