71 lines
3.0 KiB
Python
71 lines
3.0 KiB
Python
"""CRUD для очереди исключений и сохранения решений оператора."""
|
|
import json
|
|
import uuid
|
|
|
|
from db.connection import execute, query
|
|
|
|
|
|
def add_exception(batch_id, dossier_id, document_id, service_item_id,
|
|
severity, stage, title, source_quote="", options=None):
|
|
"""Добавить конкретную нерешённую задачу и вернуть её запись."""
|
|
exception_id = str(uuid.uuid4())
|
|
options_json = json.dumps(options or [], ensure_ascii=False, default=str)
|
|
execute(
|
|
"""INSERT INTO exceptions_queue
|
|
(id, batch_id, dossier_id, document_id, service_item_id, severity,
|
|
stage, title, source_quote, options_json)
|
|
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
|
(exception_id, batch_id, dossier_id, document_id, service_item_id,
|
|
severity, stage, title, source_quote or "", options_json),
|
|
)
|
|
return get_exception(exception_id)
|
|
|
|
|
|
def get_exception(exception_id):
|
|
"""Получить исключение по ID и декодировать варианты решения."""
|
|
rows = query("SELECT * FROM exceptions_queue WHERE id = %s", (exception_id,))
|
|
if not rows:
|
|
return None
|
|
result = dict(rows[0])
|
|
try:
|
|
result["options"] = json.loads(result.get("options_json") or "[]")
|
|
except (TypeError, json.JSONDecodeError):
|
|
result["options"] = []
|
|
try:
|
|
result["resolution"] = json.loads(result.get("resolution_json") or "null")
|
|
except (TypeError, json.JSONDecodeError):
|
|
result["resolution"] = None
|
|
return result
|
|
|
|
|
|
def list_exceptions(batch_id=None, dossier_id=None, status=None):
|
|
"""Список исключений с необязательными фильтрами batch/dossier/status."""
|
|
clauses = []
|
|
params = []
|
|
for field, value in (("batch_id", batch_id), ("dossier_id", dossier_id),
|
|
("status", status)):
|
|
if value is not None:
|
|
clauses.append(f"{field} = %s")
|
|
params.append(value)
|
|
where = f" WHERE {' AND '.join(clauses)}" if clauses else ""
|
|
rows = query(
|
|
f"SELECT id FROM exceptions_queue{where} ORDER BY created_at, id",
|
|
params,
|
|
)
|
|
return [get_exception(row["id"]) for row in rows]
|
|
|
|
|
|
def resolve_exception(exception_id, resolution):
|
|
"""Сохранить решение без удаления исходной причины и цитаты.
|
|
|
|
Пересчёт зависимых данных выполняет сервисный слой; CRUD отвечает только
|
|
за аудируемую фиксацию решения человека.
|
|
"""
|
|
resolution_json = json.dumps(resolution, ensure_ascii=False, default=str)
|
|
changed = execute(
|
|
"""UPDATE exceptions_queue
|
|
SET resolution_json = %s, status = 'RESOLVED', resolved_at = datetime('now')
|
|
WHERE id = %s AND status = 'OPEN'""",
|
|
(resolution_json, exception_id),
|
|
)
|
|
return get_exception(exception_id) if changed else None |