From 576d963f28c7070e99eb385c24b80516e86406c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Markovi=C4=87?= Date: Thu, 2 Jul 2026 20:19:20 +0200 Subject: [PATCH] Fiskalni pazar: ispravan Content-Disposition header i data-full-reload na formama --- cmd/ntech/main.go | 2 +- internal/handler/fiskal_pazar.go | 19 ++++++++++++++++++- web/templates/stranice/fiskal_pazar.html | 4 ++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/cmd/ntech/main.go b/cmd/ntech/main.go index d530a42..f033fd2 100644 --- a/cmd/ntech/main.go +++ b/cmd/ntech/main.go @@ -292,7 +292,7 @@ func main() { r.Get("/podesavanja/fiskalizacija/be-status", h.BeStatus) r.Post("/podesavanja/fiskalizacija/be-reset-audit", h.BeResetAudit) r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "fiskal.pazar")).Get("/fiskal/pazar", h.FiskalniPazar) - r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "fiskal.pazar")).Post("/fiskal/pazar/izvestaj", h.FiskalniIzvestaj) + r.With(doz("fiskal.pazar")).Post("/fiskal/pazar/izvestaj", h.FiskalniIzvestaj) r.With(doz("fiskal.zakljucenje")).Post("/fiskal/pazar/zakljuci", h.ZakljuciFiskalniDan) r.Get("/admin/podesavanja/kalkulacija-pdv", h.PdvStope) r.With(doz("podesavanja.izmeni")).Post("/podesavanja/pdv-stope/dodaj", h.DodajPdvStopu) diff --git a/internal/handler/fiskal_pazar.go b/internal/handler/fiskal_pazar.go index 5ed226a..6781fec 100644 --- a/internal/handler/fiskal_pazar.go +++ b/internal/handler/fiskal_pazar.go @@ -4,7 +4,9 @@ import ( "encoding/base64" "fmt" "net/http" + "net/url" "strings" + "unicode" ntechsqlite "ntech/internal/db/sqlite" "ntech/internal/fiskal" @@ -12,6 +14,21 @@ import ( "ntech/internal/model" ) +// contentDispositionZaFajl gradi Content-Disposition header za dati naziv fajla. +// HTTP header vrednosti moraju biti ASCII — naziv sa slovima kao što su Š/Č/Ž +// (npr. iz PFR-a: "DNEVNI IZVEŠTAJ - ...pdf") bi inače napravio nevalidan header +// koji pregledač ne može da parsira. RFC 6266 filename* nosi pravo UTF-8 ime, +// dok filename (ASCII) služi kao fallback za starije klijente. +func contentDispositionZaFajl(ime string) string { + ascii := strings.Map(func(r rune) rune { + if r > unicode.MaxASCII { + return '_' + } + return r + }, ime) + return fmt.Sprintf(`attachment; filename="%s"; filename*=UTF-8''%s`, ascii, url.PathEscape(ime)) +} + // PodaciFiskalniPazar su podaci za stranicu dnevnog fiskalnog preseka (pazara). type PodaciFiskalniPazar struct { model.PodaciStranice @@ -115,6 +132,6 @@ func (h *Handler) FiskalniIzvestaj(w http.ResponseWriter, r *http.Request) { imeFajla = "dnevni-izvestaj.pdf" } w.Header().Set("Content-Type", "application/pdf") - w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"`, imeFajla)) + w.Header().Set("Content-Disposition", contentDispositionZaFajl(imeFajla)) w.Write(sadrzaj) } diff --git a/web/templates/stranice/fiskal_pazar.html b/web/templates/stranice/fiskal_pazar.html index 978f013..a2c916f 100644 --- a/web/templates/stranice/fiskal_pazar.html +++ b/web/templates/stranice/fiskal_pazar.html @@ -76,13 +76,13 @@
Osveži -
+
{{if index .Dozvole "fiskal.zakljucenje"}} -