PDF link target=_blank + nginx timeouts + priority filteri (samo s podacima)

nginx (sport.rinet.one):
- proxy_read_timeout 60s → 300s
- proxy_send_timeout 300s
- proxy_buffering off (PDF stream)
- client_max_body_size 50M → 100M

Endpoints:
- /api/v2/klubovi/financirani: +with_data filter (samo s potporama/godišnjakom/HNS)
- /api/v2/sportasi/filtered: +samo_priority +samo_s_hns

Frontend:
- PDF link target=_blank rel=noopener
- window._klub_only_priority = true (default)
- window._sportas_only_priority = true (default)

DB View:
- pgz_sport.v_nogomet_priority (prima_potpore, u_godisnjaku, ima_hns_roster)
This commit is contained in:
2026-05-05 13:51:07 +02:00
parent c6a5ec62aa
commit f7b5114f58
289 changed files with 37204 additions and 363 deletions
+51 -3
View File
@@ -1,27 +1,38 @@
#!/usr/bin/env python3
# ═══════════════════════════════════════════════════════════════════
# Fajl: routers/erp_full_router.py | v1.0.0 | 05.05.2026
# Fajl: routers/erp_full_router.py | v1.1.0 | 05.05.2026
# Autor: Damir Radulić <dradulic@outlook.com> / damir@rinet.one
# Lokacija: /opt/pgz-sport/routers/erp_full_router.py
# Svrha: FULL ERP (SAP-Lite) — kontni plan, dnevnik, glavna knjiga,
# partneri, ulazni/izlazni računi (+ FINA e-Račun XML import),
# PDV, plaće, izvještaji (Bilanca/PnL/Cashflow), PDF/XLSX export.
# PDV, plaće, izvještaji (Bilanca/PnL/Cashflow), PDF/XLSX export,
# invoice_uploads (OCR), expense_reports (Putni nalozi), payments.
# v1.1.0 (2026-05-05): + POST /invoice-uploads multipart upload (Agent E).
# Mount: /api/v2/erp/*
# ═══════════════════════════════════════════════════════════════════
from __future__ import annotations
import hashlib
import os
import re
from datetime import date, datetime
from decimal import Decimal
from io import BytesIO
from pathlib import Path
from typing import Optional, List
from xml.etree import ElementTree as ET
import psycopg2
import psycopg2.extras
from fastapi import APIRouter, HTTPException, Query, Body, UploadFile, File, Depends, Header
from fastapi import APIRouter, HTTPException, Query, Body, UploadFile, File, Depends, Header, Form
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
# ── Upload destination (relative to web root /uploads/...) ──────────
UPLOAD_BASE = Path("/opt/pgz-sport/uploads")
INVOICE_UPLOAD_DIR = UPLOAD_BASE / "invoices"
INVOICE_UPLOAD_DIR.mkdir(parents=True, exist_ok=True)
router = APIRouter(prefix="/api/v2/erp", tags=["erp_full"])
DB = dict(host='10.10.0.2', port=6432, dbname='rinet_v3', user='rinet', password='R1net2026!SecureDB#v7')
@@ -1172,6 +1183,43 @@ def racuni_ulazni_uploads(rid: int):
return {"count": len(rows), "rows": rows}
# ── Upload new invoice file (multipart) ─────────────────────────────
@router.post("/invoice-uploads")
async def invoice_uploads_create(
file: UploadFile = File(...),
klub_id: Optional[int] = Form(None),
invoice_id: Optional[int] = Form(None),
):
"""Accepts PDF/JPG/PNG of an invoice. Stores file under /uploads/invoices/
and inserts a row into invoice_uploads with ocr_status='pending'.
Returns the new id; OCR/AI extraction runs separately."""
raw = await file.read()
if not raw:
raise HTTPException(400, "Empty file")
if len(raw) > 25 * 1024 * 1024:
raise HTTPException(413, "File > 25 MB")
safe = re.sub(r"[^A-Za-z0-9._-]+", "_", file.filename or "upload.bin")[:120]
sha = hashlib.sha256(raw).hexdigest()
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
rel = f"invoices/{ts}_{sha[:10]}_{safe}"
abs_path = UPLOAD_BASE / rel
abs_path.parent.mkdir(parents=True, exist_ok=True)
with open(abs_path, "wb") as f:
f.write(raw)
new_id = db_exec(
"INSERT INTO pgz_sport.invoice_uploads "
"(klub_id, file_name, file_path, file_size, mime, sha256, "
" ocr_status, invoice_id, uploaded_at) "
"VALUES (%s,%s,%s,%s,%s,%s,'pending',%s, now()) RETURNING id",
(klub_id, file.filename, rel, len(raw),
file.content_type or "application/octet-stream",
sha, invoice_id),
returning=True,
)
return {"ok": True, "id": new_id, "file_path": rel,
"file_size": len(raw), "sha256": sha}
# ═══════════════════════════════════════════════════════════════════
# 12) PUTNI NALOZI / EXPENSE REPORTS
# ═══════════════════════════════════════════════════════════════════