42 lines
1.6 KiB
Python
42 lines
1.6 KiB
Python
import re
|
||
from decimal import Decimal
|
||
|
||
from fastapi import APIRouter, File, UploadFile
|
||
from pydantic import BaseModel
|
||
|
||
router = APIRouter(prefix="/ocr", tags=["ocr"])
|
||
|
||
|
||
class ReceiptSuggestion(BaseModel):
|
||
total_cost: Decimal | None = None
|
||
liters: Decimal | None = None
|
||
price_per_liter: Decimal | None = None
|
||
station: str | None = None
|
||
confidence: float
|
||
message: str
|
||
|
||
|
||
@router.post("/fuel-receipt", response_model=ReceiptSuggestion)
|
||
async def scan_fuel_receipt(file: UploadFile = File(...)) -> ReceiptSuggestion:
|
||
content = await file.read()
|
||
text = content.decode("utf-8", errors="ignore")
|
||
numbers = [Decimal(item.replace(",", ".")) for item in re.findall(r"\d+[,.]\d+|\d+", text)]
|
||
total = max(numbers) if numbers else None
|
||
liters = next((item for item in numbers if Decimal("5") <= item <= Decimal("120")), None)
|
||
price = None
|
||
if total and liters and liters:
|
||
price = (total / liters).quantize(Decimal("0.01"))
|
||
|
||
return ReceiptSuggestion(
|
||
total_cost=total,
|
||
liters=liters,
|
||
price_per_liter=price,
|
||
station=None,
|
||
confidence=0.35 if numbers else 0,
|
||
message=(
|
||
"OCR-модуль готов к подключению движка распознавания. Сейчас извлекаю числа из текстового слоя/имени файла."
|
||
if numbers
|
||
else "Не удалось распознать чек. Можно заполнить поля вручную, а OCR-движок подключить отдельным сервисом."
|
||
),
|
||
)
|