64 lines
2.1 KiB
Python

# backend/api/v1/calendar/utils.py
from __future__ import annotations
import datetime as dt
import hashlib
from typing import Optional, Tuple
from django.db.models import Max, Q
from django.utils import timezone
from django.utils.dateparse import parse_date, parse_datetime
MAX_WINDOW_DAYS = 400
CACHE_TTL = 60
RESPONSE_HEADERS = {"Cache-Control": f"private, max-age={CACHE_TTL}"}
def parse_to_date(value: Optional[str]) -> Optional[dt.date]:
if not value:
return None
dtime = parse_datetime(value)
return dtime.date() if dtime else parse_date(value)
def get_range(request) -> Tuple[Optional[dt.date], Optional[dt.date]]:
s = request.query_params.get("start") or request.query_params.get("from")
e = request.query_params.get("end") or request.query_params.get("to")
if not (s and e):
return None, None
start = parse_to_date(s)
end = parse_to_date(e)
if not (start and end):
return None, None
if end < start:
start, end = end, start
if (end - start).days > MAX_WINDOW_DAYS:
end = start + dt.timedelta(days=MAX_WINDOW_DAYS)
return start, end
def etag_for(payload_key: str, last_modified: Optional[dt.datetime], count: int) -> str:
src = f"{payload_key}:{int(last_modified.timestamp()) if last_modified else 0}:{count}"
return hashlib.sha1(src.encode()).hexdigest()
def last_modified(qs, model) -> Optional[dt.datetime]:
field_names = {f.name for f in model._meta.get_fields() if hasattr(f, "name")}
field = "updated_at" if "updated_at" in field_names else "created_at"
return qs.aggregate(m=Max(field)).get("m")
def is_hr(user) -> bool:
return user.is_active and (
user.groups.filter(name="HR").exists()
or user.has_perm("requests_app.can_view_all_requests")
or user.has_perm("requests_app.can_process_requests")
)
def can_view_department(user, dept_id: int) -> bool:
if is_hr(user):
return True
if user.headed_departments.filter(pk=dept_id).exists():
return True
return user.departments_links.filter(department_id=dept_id, is_active=True).exists()