"""ЕТТН-чеки Checkbox: запрос создания (массово), просмотр, отмена.""" from __future__ import annotations import uuid from fastapi import APIRouter, Depends, HTTPException, Request, status from sqlalchemy import select from app.api.deps import ( CashierUser, CheckboxClientDep, SessionDep, TaskQueueDep, require_any, ) from app.db.models.receipt import Receipt from app.schemas.receipts import ReceiptCreateRequest, ReceiptCreateResponse, ReceiptOut from app.services import receipts as receipts_service from app.services.checkbox.client import CheckboxError router = APIRouter(prefix="/receipts", tags=["receipts"], dependencies=[Depends(require_any)]) @router.post("", response_model=ReceiptCreateResponse, status_code=status.HTTP_202_ACCEPTED) async def create_receipts( payload: ReceiptCreateRequest, request: Request, session: SessionDep, queue: TaskQueueDep, actor: CashierUser, ) -> ReceiptCreateResponse: result = await receipts_service.request_receipts( session, [(item.order_id, item.prepayment_kopecks) for item in payload.items], user=actor, request=request, ) await session.commit() # После commit: worker должен увидеть строку `pending`. for receipt in result.created: await queue.enqueue("create_ettn_receipt", str(receipt.id)) return ReceiptCreateResponse( created=[ReceiptOut.from_receipt(receipt) for receipt in result.created], errors=result.errors, ) @router.get("", response_model=list[ReceiptOut]) async def list_receipts(session: SessionDep, order_id: str | None = None) -> list[ReceiptOut]: query = select(Receipt).order_by(Receipt.created_at.desc()).limit(500) if order_id is not None: query = query.where(Receipt.order_id == order_id) return [ReceiptOut.from_receipt(receipt) for receipt in await session.scalars(query)] @router.get("/{receipt_id}", response_model=ReceiptOut) async def get_receipt(receipt_id: uuid.UUID, session: SessionDep) -> ReceiptOut: receipt = await session.get(Receipt, receipt_id) if receipt is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Чек не найден") return ReceiptOut.from_receipt(receipt) @router.post("/{receipt_id}/cancel", response_model=ReceiptOut) async def cancel_receipt( receipt_id: uuid.UUID, request: Request, session: SessionDep, checkbox: CheckboxClientDep, actor: CashierUser, ) -> ReceiptOut: try: receipt = await receipts_service.cancel_receipt( session, checkbox, receipt_id, user=actor, request=request ) except receipts_service.ReceiptStateError as exc: raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc except CheckboxError as exc: raise HTTPException( status_code=status.HTTP_502_BAD_GATEWAY, detail=f"Checkbox: {exc}" ) from exc if receipt is None: raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Чек не найден") return ReceiptOut.from_receipt(receipt)