Dashboard UI: davatelj dropdown + dynamic years + KORISNIK truncate + PDF link
This commit is contained in:
+131
-42
@@ -405,66 +405,76 @@ def api_kpi():
|
||||
|
||||
|
||||
@app.get("/api/dashboard/top-primatelji")
|
||||
def dashboard_top_primatelji(godina: int = 2025, limit: int = 50):
|
||||
"""Top primatelji javnih potreba — svi klubovi sa primljenim potporama.
|
||||
godina<=0 znači sve godine. Napomena 'doc_id=N' joinira pgz_sport.dokumenti za PDF link."""
|
||||
def dashboard_top_primatelji(godina: int = 2025, davatelj: str = None, limit: int = 100):
|
||||
"""Top primatelji javnih potreba s davatelj filter + PDF link na godišnjak."""
|
||||
where = []
|
||||
params = []
|
||||
if godina and godina > 0:
|
||||
where_god = "WHERE pn.godina = %s"
|
||||
params = (godina, limit)
|
||||
else:
|
||||
where_god = "WHERE TRUE"
|
||||
params = (limit,)
|
||||
|
||||
where.append("pn.godina = %s")
|
||||
params.append(godina)
|
||||
if davatelj and davatelj != 'all':
|
||||
where.append("pn.davatelj = %s")
|
||||
params.append(davatelj)
|
||||
where_sql = "WHERE " + " AND ".join(where) if where else ""
|
||||
|
||||
rows = fetch(f"""
|
||||
WITH pn_e AS (
|
||||
SELECT
|
||||
pn.id,
|
||||
pn.naziv_kluba,
|
||||
pn.klub_id,
|
||||
pn.iznos,
|
||||
pn.napomena,
|
||||
pn.godina,
|
||||
NULLIF((regexp_match(COALESCE(pn.napomena, ''), 'doc_id=(\\d+)'))[1], '')::int AS doc_id
|
||||
FROM pgz_sport.potpore_nositelji pn
|
||||
{where_god}
|
||||
)
|
||||
SELECT
|
||||
pn.id,
|
||||
pn.naziv_kluba,
|
||||
pn.klub_id,
|
||||
pn.iznos,
|
||||
COALESCE(LEFT(pn.napomena, 60), '') AS napomena_short,
|
||||
pn.napomena,
|
||||
pn.godina,
|
||||
COALESCE(pn.davatelj, 'RSS (Riječki sportski savez)') AS davatelj,
|
||||
COALESCE(pn.vrsta, 'Javne potrebe') AS vrsta,
|
||||
COALESCE(k.sport, 'n/a') AS sport,
|
||||
COALESCE(s.naziv, '') AS savez_naziv,
|
||||
COALESCE(k.razina, '') AS razina,
|
||||
COALESCE(k.grad, '') AS grad,
|
||||
CASE
|
||||
WHEN pn.napomena ILIKE '%%županijski%%' OR pn.napomena ILIKE '%%PGZ%%' OR pn.napomena ILIKE '%%PGŽ%%' THEN 'Županijski sportski savez PGŽ'
|
||||
WHEN pn.napomena ILIKE '%%riječki%%' OR pn.napomena ILIKE '%%RSS%%' THEN 'Riječki sportski savez'
|
||||
WHEN pn.napomena ILIKE '%%grad rijeka%%' THEN 'Grad Rijeka'
|
||||
ELSE 'Riječki sportski savez'
|
||||
END AS davatelj_naziv,
|
||||
CASE
|
||||
WHEN pn.napomena ILIKE '%%JPS%%' OR pn.napomena ILIKE '%%javn%%' THEN 'Javne potrebe u sportu'
|
||||
WHEN pn.napomena ILIKE '%%manifestacij%%' THEN 'Manifestacija'
|
||||
WHEN pn.napomena ILIKE '%%objekt%%' THEN 'Sportski objekti'
|
||||
ELSE 'Javne potrebe'
|
||||
END AS vrsta,
|
||||
COALESCE(d.pdf_url, d.url, d.izvor_url) AS pdf_url,
|
||||
d.title AS doc_title
|
||||
FROM pn_e pn
|
||||
d.id AS doc_id,
|
||||
COALESCE(d.pdf_url, d.izvor_url, '/sport/api/v2/dokumenti/godisnjak/' || pn.godina::text) AS pdf_url,
|
||||
COALESCE(d.title, 'Godišnjak ' || pn.godina::text) AS doc_title
|
||||
FROM pgz_sport.potpore_nositelji pn
|
||||
LEFT JOIN pgz_sport.klubovi k ON k.id = pn.klub_id
|
||||
LEFT JOIN pgz_sport.savezi s ON s.id = k.savez_id
|
||||
LEFT JOIN pgz_sport.dokumenti d ON d.id = pn.doc_id
|
||||
ORDER BY pn.iznos DESC NULLS LAST
|
||||
LEFT JOIN pgz_sport.dokumenti d ON d.vrsta='godisnjak' AND d.godina = pn.godina
|
||||
{where_sql}
|
||||
ORDER BY pn.iznos DESC NULLS LAST, pn.naziv_kluba
|
||||
LIMIT %s
|
||||
""", params)
|
||||
|
||||
""", tuple(params) + (limit,))
|
||||
|
||||
# Stats summary
|
||||
stats = fetch(f"""
|
||||
SELECT
|
||||
count(*) AS total_records,
|
||||
sum(iznos)::numeric(12,2) AS total_amount,
|
||||
count(DISTINCT naziv_kluba) AS unique_klubova,
|
||||
count(DISTINCT davatelj) AS unique_davatelji
|
||||
FROM pgz_sport.potpore_nositelji pn
|
||||
{where_sql}
|
||||
""", tuple(params))
|
||||
|
||||
# Available years (always)
|
||||
years = fetch("""
|
||||
SELECT godina, count(*) AS broj, sum(iznos)::numeric(12,2) AS suma
|
||||
FROM pgz_sport.potpore_nositelji
|
||||
GROUP BY godina ORDER BY godina DESC
|
||||
""")
|
||||
|
||||
# Available davatelji (always)
|
||||
davatelji = fetch("""
|
||||
SELECT DISTINCT COALESCE(davatelj, 'Nepoznato') AS davatelj
|
||||
FROM pgz_sport.potpore_nositelji ORDER BY 1
|
||||
""")
|
||||
|
||||
return {
|
||||
"godina": godina,
|
||||
"count": len(rows),
|
||||
"davatelj": davatelj or "all",
|
||||
"rows": rows,
|
||||
"ukupno": sum((r.get("iznos") or 0) for r in rows),
|
||||
"summary": stats[0] if stats else {},
|
||||
"available_years": years,
|
||||
"available_davatelji": [d["davatelj"] for d in davatelji],
|
||||
}
|
||||
|
||||
|
||||
@@ -1813,6 +1823,8 @@ def serve_crm():
|
||||
@app.get("/crm-v2/")
|
||||
@app.get("/crm_v2")
|
||||
@app.get("/crm_v2/")
|
||||
@app.get("/crm/v2")
|
||||
@app.get("/crm")
|
||||
def serve_crm_v2():
|
||||
p = HTML_DIR / "crm_v2.html"
|
||||
if p.exists():
|
||||
@@ -2386,6 +2398,83 @@ def dokument_detail(doc_id: int):
|
||||
if not rows: return {"error": "not_found"}
|
||||
return rows[0]
|
||||
|
||||
|
||||
@app.get("/favicon.ico")
|
||||
def serve_favicon():
|
||||
from fastapi.responses import FileResponse
|
||||
return FileResponse("/opt/pgz-sport/static/favicon.ico", media_type="image/x-icon")
|
||||
|
||||
@app.get("/api/v2/klubovi/financirani")
|
||||
def klubovi_financirani(sport: str = None, davatelj: str = None, godina: int = None, limit: int = 1000):
|
||||
"""Klubovi koji su primili novac od PGŽ/RSS/Grad Rijeka. davatelj: pgz|rss|grad_rijeka|any"""
|
||||
where = []
|
||||
params = []
|
||||
if sport:
|
||||
where.append("k.sport = %s")
|
||||
params.append(sport)
|
||||
if davatelj == 'pgz':
|
||||
where.append("k.prima_pgz = true")
|
||||
elif davatelj == 'rss':
|
||||
where.append("k.prima_rss = true")
|
||||
elif davatelj == 'grad_rijeka':
|
||||
where.append("k.prima_grad_rijeka = true")
|
||||
elif davatelj == 'any':
|
||||
where.append("(k.prima_pgz OR k.prima_rss OR k.prima_grad_rijeka)")
|
||||
|
||||
where_sql = "WHERE " + " AND ".join(where) if where else ""
|
||||
rows = fetch(f"""
|
||||
SELECT k.id, k.naziv, k.sport, k.razina, k.oib, k.grad, k.adresa,
|
||||
k.prima_pgz, k.prima_rss, k.prima_grad_rijeka, k.u_godisnjaku,
|
||||
k.broj_potpora, k.ukupno_potpora,
|
||||
(SELECT count(*) FROM pgz_sport.clanovi WHERE klub_id = k.id) AS sportasa
|
||||
FROM pgz_sport.v_klubovi_financiranje k
|
||||
{where_sql}
|
||||
ORDER BY k.ukupno_potpora DESC NULLS LAST, k.naziv
|
||||
LIMIT %s
|
||||
""", tuple(params) + (limit,))
|
||||
return {"count": len(rows), "rows": rows, "filter": {"sport": sport, "davatelj": davatelj}}
|
||||
|
||||
|
||||
@app.get("/api/v2/sportasi/filtered")
|
||||
def sportasi_filtered(sport: str = None, klub_id: int = None, kategorija: str = None,
|
||||
godina_rod_od: int = None, godina_rod_do: int = None,
|
||||
q: str = None, limit: int = 500):
|
||||
"""Sportaši s range filter za godinu rođenja + kategorije."""
|
||||
where = ["c.aktivan = true"]
|
||||
params = []
|
||||
if sport:
|
||||
where.append("(c.sport = %s OR k.sport = %s)")
|
||||
params.extend([sport, sport])
|
||||
if klub_id:
|
||||
where.append("c.klub_id = %s")
|
||||
params.append(klub_id)
|
||||
if kategorija:
|
||||
where.append("(c.kategorija = %s OR EXISTS (SELECT 1 FROM pgz_sport.clan_kategorije ck WHERE ck.clan_id = c.id AND ck.kategorija = %s))")
|
||||
params.extend([kategorija, kategorija])
|
||||
if godina_rod_od:
|
||||
where.append("(EXTRACT(YEAR FROM c.datum_rodenja) >= %s OR c.godina_rodenja >= %s)")
|
||||
params.extend([godina_rod_od, godina_rod_od])
|
||||
if godina_rod_do:
|
||||
where.append("(EXTRACT(YEAR FROM c.datum_rodenja) <= %s OR c.godina_rodenja <= %s)")
|
||||
params.extend([godina_rod_do, godina_rod_do])
|
||||
if q:
|
||||
where.append("(c.ime ILIKE %s OR c.prezime ILIKE %s)")
|
||||
params.extend([f"%{q}%", f"%{q}%"])
|
||||
|
||||
where_sql = "WHERE " + " AND ".join(where)
|
||||
rows = fetch(f"""
|
||||
SELECT c.id, c.ime, c.prezime, c.spol, c.datum_rodenja, c.godina_rodenja,
|
||||
c.kategorija, c.pozicija, c.sport, c.klub_id, k.naziv AS klub_naziv,
|
||||
c.hns_igrac_id, c.source, c.source_url
|
||||
FROM pgz_sport.clanovi c
|
||||
LEFT JOIN pgz_sport.klubovi k ON k.id = c.klub_id
|
||||
{where_sql}
|
||||
ORDER BY c.prezime, c.ime
|
||||
LIMIT %s
|
||||
""", tuple(params) + (limit,))
|
||||
return {"count": len(rows), "rows": rows}
|
||||
|
||||
|
||||
@app.get("/")
|
||||
def root(request: Request):
|
||||
host = request.headers.get("host", "")
|
||||
|
||||
Reference in New Issue
Block a user