mirror of
https://github.com/TronoSfera/Law.git
synced 2026-05-18 10:03:45 +03:00
233 lines
8.8 KiB
Python
233 lines
8.8 KiB
Python
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
from fastapi import HTTPException
|
||
from sqlalchemy.orm import Session
|
||
|
||
from app.models.request import Request
|
||
from app.models.request_data_requirement import RequestDataRequirement
|
||
from app.models.topic_data_template import TopicDataTemplate
|
||
from app.schemas.admin import RequestDataRequirementCreate, RequestDataRequirementPatch
|
||
from app.services.request_status import actor_admin_uuid
|
||
|
||
from .permissions import ensure_lawyer_can_manage_request_or_403, request_uuid_or_400
|
||
|
||
|
||
def request_data_requirement_row(row: RequestDataRequirement) -> dict[str, Any]:
|
||
return {
|
||
"id": str(row.id),
|
||
"request_id": str(row.request_id),
|
||
"topic_template_id": str(row.topic_template_id) if row.topic_template_id else None,
|
||
"key": row.key,
|
||
"label": row.label,
|
||
"description": row.description,
|
||
"required": bool(row.required),
|
||
"created_by_admin_id": str(row.created_by_admin_id) if row.created_by_admin_id else None,
|
||
"created_at": row.created_at.isoformat() if row.created_at else None,
|
||
"updated_at": row.updated_at.isoformat() if row.updated_at else None,
|
||
}
|
||
|
||
|
||
def get_request_data_template_service(request_id: str, db: Session, admin: dict) -> dict[str, Any]:
|
||
request_uuid = request_uuid_or_400(request_id)
|
||
req = db.get(Request, request_uuid)
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
||
ensure_lawyer_can_manage_request_or_403(admin, req)
|
||
|
||
topic_items = (
|
||
db.query(TopicDataTemplate)
|
||
.filter(
|
||
TopicDataTemplate.topic_code == str(req.topic_code or ""),
|
||
TopicDataTemplate.enabled.is_(True),
|
||
)
|
||
.order_by(TopicDataTemplate.sort_order.asc(), TopicDataTemplate.key.asc())
|
||
.all()
|
||
)
|
||
request_items = (
|
||
db.query(RequestDataRequirement)
|
||
.filter(RequestDataRequirement.request_id == req.id)
|
||
.order_by(RequestDataRequirement.created_at.asc(), RequestDataRequirement.key.asc())
|
||
.all()
|
||
)
|
||
return {
|
||
"request_id": str(req.id),
|
||
"topic_code": req.topic_code,
|
||
"topic_items": [
|
||
{
|
||
"id": str(row.id),
|
||
"key": row.key,
|
||
"label": row.label,
|
||
"description": row.description,
|
||
"required": bool(row.required),
|
||
"sort_order": row.sort_order,
|
||
}
|
||
for row in topic_items
|
||
],
|
||
"request_items": [request_data_requirement_row(row) for row in request_items],
|
||
}
|
||
|
||
|
||
def sync_request_data_template_from_topic_service(request_id: str, db: Session, admin: dict) -> dict[str, Any]:
|
||
request_uuid = request_uuid_or_400(request_id)
|
||
req = db.get(Request, request_uuid)
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
||
ensure_lawyer_can_manage_request_or_403(admin, req)
|
||
topic_code = str(req.topic_code or "").strip()
|
||
if not topic_code:
|
||
return {"status": "ok", "created": 0, "request_id": str(req.id)}
|
||
|
||
topic_items = (
|
||
db.query(TopicDataTemplate)
|
||
.filter(
|
||
TopicDataTemplate.topic_code == topic_code,
|
||
TopicDataTemplate.enabled.is_(True),
|
||
)
|
||
.order_by(TopicDataTemplate.sort_order.asc(), TopicDataTemplate.key.asc())
|
||
.all()
|
||
)
|
||
existing_keys = {
|
||
str(key).strip()
|
||
for (key,) in db.query(RequestDataRequirement.key).filter(RequestDataRequirement.request_id == req.id).all()
|
||
if key
|
||
}
|
||
responsible = str(admin.get("email") or "").strip() or "Администратор системы"
|
||
actor_id = actor_admin_uuid(admin)
|
||
|
||
created = 0
|
||
for template in topic_items:
|
||
key = str(template.key or "").strip()
|
||
if not key or key in existing_keys:
|
||
continue
|
||
db.add(
|
||
RequestDataRequirement(
|
||
request_id=req.id,
|
||
topic_template_id=template.id,
|
||
key=key,
|
||
label=template.label,
|
||
description=template.description,
|
||
required=bool(template.required),
|
||
created_by_admin_id=actor_id,
|
||
responsible=responsible,
|
||
)
|
||
)
|
||
existing_keys.add(key)
|
||
created += 1
|
||
|
||
db.commit()
|
||
return {"status": "ok", "created": created, "request_id": str(req.id)}
|
||
|
||
|
||
def create_request_data_requirement_service(
|
||
request_id: str,
|
||
payload: RequestDataRequirementCreate,
|
||
db: Session,
|
||
admin: dict,
|
||
) -> dict[str, Any]:
|
||
request_uuid = request_uuid_or_400(request_id)
|
||
req = db.get(Request, request_uuid)
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
||
ensure_lawyer_can_manage_request_or_403(admin, req)
|
||
|
||
key = str(payload.key or "").strip()
|
||
label = str(payload.label or "").strip()
|
||
if not key:
|
||
raise HTTPException(status_code=400, detail='Поле "key" обязательно')
|
||
if not label:
|
||
raise HTTPException(status_code=400, detail='Поле "label" обязательно')
|
||
|
||
exists = (
|
||
db.query(RequestDataRequirement.id)
|
||
.filter(RequestDataRequirement.request_id == req.id, RequestDataRequirement.key == key)
|
||
.first()
|
||
)
|
||
if exists is not None:
|
||
raise HTTPException(status_code=400, detail="Элемент с таким key уже существует в шаблоне заявки")
|
||
|
||
row = RequestDataRequirement(
|
||
request_id=req.id,
|
||
topic_template_id=None,
|
||
key=key,
|
||
label=label,
|
||
description=payload.description,
|
||
required=bool(payload.required),
|
||
created_by_admin_id=actor_admin_uuid(admin),
|
||
responsible=str(admin.get("email") or "").strip() or "Администратор системы",
|
||
)
|
||
db.add(row)
|
||
db.commit()
|
||
db.refresh(row)
|
||
return request_data_requirement_row(row)
|
||
|
||
|
||
def update_request_data_requirement_service(
|
||
request_id: str,
|
||
item_id: str,
|
||
payload: RequestDataRequirementPatch,
|
||
db: Session,
|
||
admin: dict,
|
||
) -> dict[str, Any]:
|
||
request_uuid = request_uuid_or_400(request_id)
|
||
req = db.get(Request, request_uuid)
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
||
ensure_lawyer_can_manage_request_or_403(admin, req)
|
||
|
||
item_uuid = request_uuid_or_400(item_id)
|
||
row = db.get(RequestDataRequirement, item_uuid)
|
||
if row is None or row.request_id != req.id:
|
||
raise HTTPException(status_code=404, detail="Элемент шаблона заявки не найден")
|
||
|
||
changes = payload.model_dump(exclude_unset=True)
|
||
if not changes:
|
||
raise HTTPException(status_code=400, detail="Нет полей для обновления")
|
||
if "key" in changes:
|
||
key = str(changes.get("key") or "").strip()
|
||
if not key:
|
||
raise HTTPException(status_code=400, detail='Поле "key" не может быть пустым')
|
||
duplicate = (
|
||
db.query(RequestDataRequirement.id)
|
||
.filter(
|
||
RequestDataRequirement.request_id == req.id,
|
||
RequestDataRequirement.key == key,
|
||
RequestDataRequirement.id != row.id,
|
||
)
|
||
.first()
|
||
)
|
||
if duplicate is not None:
|
||
raise HTTPException(status_code=400, detail="Элемент с таким key уже существует в шаблоне заявки")
|
||
row.key = key
|
||
if "label" in changes:
|
||
label = str(changes.get("label") or "").strip()
|
||
if not label:
|
||
raise HTTPException(status_code=400, detail='Поле "label" не может быть пустым')
|
||
row.label = label
|
||
if "description" in changes:
|
||
row.description = changes.get("description")
|
||
if "required" in changes:
|
||
row.required = bool(changes.get("required"))
|
||
row.responsible = str(admin.get("email") or "").strip() or "Администратор системы"
|
||
|
||
db.add(row)
|
||
db.commit()
|
||
db.refresh(row)
|
||
return request_data_requirement_row(row)
|
||
|
||
|
||
def delete_request_data_requirement_service(request_id: str, item_id: str, db: Session, admin: dict) -> dict[str, Any]:
|
||
request_uuid = request_uuid_or_400(request_id)
|
||
req = db.get(Request, request_uuid)
|
||
if req is None:
|
||
raise HTTPException(status_code=404, detail="Заявка не найдена")
|
||
ensure_lawyer_can_manage_request_or_403(admin, req)
|
||
|
||
item_uuid = request_uuid_or_400(item_id)
|
||
row = db.get(RequestDataRequirement, item_uuid)
|
||
if row is None or row.request_id != req.id:
|
||
raise HTTPException(status_code=404, detail="Элемент шаблона заявки не найден")
|
||
db.delete(row)
|
||
db.commit()
|
||
return {"status": "удалено", "id": str(row.id)}
|