"""Закрепление оборудования за отделами: кто какое оборудование видит. Администратор и модератор видят всё. Сотрудник без отдела — тоже всё. Сотрудник отдела видит оборудование своего отдела и вложенных в него отделов, а также оборудование, не закреплённое ни за каким отделом. Так крановый электрик не получает списков, карты и уведомлений по станкам, если станки закреплены за другим отделом.""" 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"