Files

51 lines
2.3 KiB
Python

"""Закрепление оборудования за отделами: кто какое оборудование видит.
Администратор и модератор видят всё. Сотрудник без отдела — тоже всё. Сотрудник отдела видит оборудование своего отдела
и вложенных в него отделов, а также оборудование, не закреплённое ни за каким отделом. Так крановый электрик
не получает списков, карты и уведомлений по станкам, если станки закреплены за другим отделом."""
from sqlalchemy import or_, select
from sqlalchemy.orm import Session
from . import settings_store as ss
from .models import Department, Equipment, User
def dept_tree(db: Session, root: int) -> set[int]:
"""Отдел и все вложенные в него отделы."""
children: dict[int | None, list[int]] = {}
for i, p in db.execute(select(Department.id, Department.parent_id)):
children.setdefault(p, []).append(i)
out, stack = set(), [root]
while stack:
x = stack.pop()
if x in out:
continue
out.add(x)
stack.extend(children.get(x, []))
return out
def sees_all(u: User) -> bool:
return bool(u.is_admin or u.is_moderator or not u.department_id)
def equipment_filter(db: Session, u: User):
"""Условие SQL для выборки оборудования пользователя или None — без ограничений."""
if sees_all(u):
return None
return or_(Equipment.department_id.is_(None), Equipment.department_id.in_(dept_tree(db, u.department_id)))
def equipment_ids(db: Session, u: User) -> set[int] | None:
"""id видимого оборудования или None — видит всё."""
cond = equipment_filter(db, u)
return None if cond is None else set(db.scalars(select(Equipment.id).where(cond)))
def user_sees(db: Session, u: User, eq: Equipment) -> bool:
return sees_all(u) or eq.department_id is None or eq.department_id in dept_tree(db, u.department_id)
def crane_map_enabled(db: Session) -> bool:
return ss.get(db, "crane_map") == "1"