Fiskalni pazar: ispravan Content-Disposition header i data-full-reload na formama
This commit is contained in:
+1
-1
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -76,13 +76,13 @@
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap;padding-top:12px;border-top:0.5px solid var(--ivica);">
|
||||
<a href="/fiskal/pazar" class="btn-sekundarno" style="font-size:13px;padding:8px 16px;">Osveži</a>
|
||||
|
||||
<form method="POST" action="/fiskal/pazar/izvestaj" style="display:inline;">
|
||||
<form method="POST" action="/fiskal/pazar/izvestaj" style="display:inline;" data-full-reload>
|
||||
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
|
||||
<button type="submit" class="btn-sekundarno" style="font-size:13px;padding:8px 16px;">Preuzmi dnevni izveštaj</button>
|
||||
</form>
|
||||
|
||||
{{if index .Dozvole "fiskal.zakljucenje"}}
|
||||
<form method="POST" action="/fiskal/pazar/zakljuci" style="display:inline;"
|
||||
<form method="POST" action="/fiskal/pazar/zakljuci" style="display:inline;" data-full-reload
|
||||
onsubmit="return confirm('Zaključiti dan? Ovo trajno svodi brojače prometa na nulu — radnja se ne može poništiti.')">
|
||||
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
|
||||
<button type="submit" style="padding:8px 16px;background:#dc2626;border:none;border-radius:8px;color:#fff;font-size:13px;font-weight:500;cursor:pointer;">Zaključi dan</button>
|
||||
|
||||
Reference in New Issue
Block a user