from __future__ import annotations import uuid from typing import Any from datetime import datetime from sqlalchemy.orm import Session from app.models.attachment import Attachment from app.models.message import Message from app.models.request import Request from app.models.status_history import StatusHistory def actor_admin_uuid(admin: dict[str, Any] | None) -> uuid.UUID | None: if not admin: return None raw = str(admin.get("sub") or "").strip() if not raw: return None try: return uuid.UUID(raw) except ValueError: return None def freeze_request_messages_and_attachments(db: Session, request_id: uuid.UUID) -> None: db.query(Message).filter(Message.request_id == request_id, Message.immutable.is_(False)).update( {"immutable": True}, synchronize_session=False, ) db.query(Attachment).filter(Attachment.request_id == request_id, Attachment.immutable.is_(False)).update( {"immutable": True}, synchronize_session=False, ) def register_status_history( db: Session, request: Request, from_status: str, to_status: str, *, admin: dict[str, Any] | None = None, comment: str | None = None, important_date_at: datetime | None = None, responsible: str = "Администратор системы", ) -> None: db.add( StatusHistory( request_id=request.id, from_status=str(from_status or "").strip() or None, to_status=str(to_status or "").strip(), changed_by_admin_id=actor_admin_uuid(admin), comment=comment, important_date_at=important_date_at, responsible=responsible, ) ) def apply_status_change_effects( db: Session, request: Request, *, from_status: str, to_status: str, admin: dict[str, Any] | None = None, comment: str | None = None, important_date_at: datetime | None = None, responsible: str = "Администратор системы", ) -> None: old_code = str(from_status or "").strip() new_code = str(to_status or "").strip() if not new_code or old_code == new_code: return freeze_request_messages_and_attachments(db, request.id) register_status_history( db, request, old_code, new_code, admin=admin, comment=comment, important_date_at=important_date_at, responsible=responsible, )