58 lines
2.2 KiB
Python
58 lines
2.2 KiB
Python
|
|
"""Идентичность: acting (X-Acting-Emp-Id) и target (emp_id)."""
|
|||
|
|
|
|||
|
|
from __future__ import annotations
|
|||
|
|
|
|||
|
|
from typing import Annotated
|
|||
|
|
|
|||
|
|
from fastapi import Header, HTTPException
|
|||
|
|
|
|||
|
|
from app.emp_schema import EMP_TABLE_CANONICAL
|
|||
|
|
from app.main import _column_lookup, _quote_ident, _table_columns, resolve_emp_table
|
|||
|
|
|
|||
|
|
|
|||
|
|
def _biz_error(status: int, code: str, message: str) -> HTTPException:
|
|||
|
|
return HTTPException(status_code=status, detail={"code": code, "message": message})
|
|||
|
|
|
|||
|
|
|
|||
|
|
def parse_acting_emp_id(
|
|||
|
|
x_acting_emp_id: Annotated[str | None, Header(alias="X-Acting-Emp-Id")] = None,
|
|||
|
|
) -> int:
|
|||
|
|
if not x_acting_emp_id or not str(x_acting_emp_id).strip():
|
|||
|
|
raise _biz_error(400, "missing_acting_emp", "Требуется заголовок X-Acting-Emp-Id")
|
|||
|
|
try:
|
|||
|
|
v = int(str(x_acting_emp_id).strip())
|
|||
|
|
except ValueError as e:
|
|||
|
|
raise _biz_error(
|
|||
|
|
400, "invalid_acting_emp", "X-Acting-Emp-Id должен быть целым числом"
|
|||
|
|
) from e
|
|||
|
|
if v <= 0:
|
|||
|
|
raise _biz_error(400, "invalid_acting_emp", "X-Acting-Emp-Id должен быть > 0")
|
|||
|
|
return v
|
|||
|
|
|
|||
|
|
|
|||
|
|
def resolve_target_emp_id(acting_emp_id: int, emp_id: int | None) -> int:
|
|||
|
|
return int(emp_id) if emp_id is not None else acting_emp_id
|
|||
|
|
|
|||
|
|
|
|||
|
|
def ensure_emp_exists(cur, db: str, emp_id: int, *, kind: str = "target") -> None:
|
|||
|
|
table = resolve_emp_table(cur, db)
|
|||
|
|
cols = _table_columns(cur, db, table)
|
|||
|
|
lut = _column_lookup(cols)
|
|||
|
|
prefix = EMP_TABLE_CANONICAL.lower()
|
|||
|
|
id_col = lut.get(f"{prefix}_id") or lut.get("id")
|
|||
|
|
removed_col = lut.get(f"{prefix}_removed") or lut.get("removed")
|
|||
|
|
if not id_col:
|
|||
|
|
raise _biz_error(500, "db_error", "Не найдена колонка id в таблице сотрудников")
|
|||
|
|
|
|||
|
|
cond = f"{_quote_ident(id_col)} = %s"
|
|||
|
|
params: list = [emp_id]
|
|||
|
|
if removed_col:
|
|||
|
|
cond += f" AND {_quote_ident(removed_col)} = 0"
|
|||
|
|
cur.execute(
|
|||
|
|
f"SELECT 1 AS ok FROM {_quote_ident(table)} WHERE {cond} LIMIT 1",
|
|||
|
|
params,
|
|||
|
|
)
|
|||
|
|
if not cur.fetchone():
|
|||
|
|
code = "acting_emp_not_found" if kind == "acting" else "target_emp_not_found"
|
|||
|
|
raise _biz_error(404, code, f"Сотрудник {emp_id} не найден")
|