64 lines
2.1 KiB
Python
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() |