From d39df48a56116c797c67b26982ae32af3d8e4518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Markovi=C4=87?= Date: Wed, 1 Jul 2026 11:21:46 +0200 Subject: [PATCH] =?UTF-8?q?Servis:=20oznaka=20naloga=20bez=20izdatog=20fis?= =?UTF-8?q?kalnog=20ra=C4=8Duna=20u=20arhivi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/db/repository.go | 1 + internal/db/sqlite/fiskal.go | 22 ++++++++++++++++++++++ internal/handler/servis.go | 23 +++++++++++++++++------ web/templates/stranice/servis_arhiva.html | 8 +++++++- 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/internal/db/repository.go b/internal/db/repository.go index 1dfd77e..596bea0 100644 --- a/internal/db/repository.go +++ b/internal/db/repository.go @@ -384,6 +384,7 @@ type FiskalRepository interface { DohvatiPoProdaji(ctx context.Context, prodajaID int64) (*model.FiskalniRacun, error) DohvatiPoServisu(ctx context.Context, servisID int64) (*model.FiskalniRacun, error) OznačiKaoStorniran(ctx context.Context, id int64) error + ServisiBezFiskalnog(ctx context.Context) (map[int64]bool, error) } // ServisniLogRepository definiše operacije nad log-om događaja servisnog naloga. diff --git a/internal/db/sqlite/fiskal.go b/internal/db/sqlite/fiskal.go index acf7da9..2646f25 100644 --- a/internal/db/sqlite/fiskal.go +++ b/internal/db/sqlite/fiskal.go @@ -115,6 +115,28 @@ func (r *FiskalRepo) DohvatiPoServisu(ctx context.Context, servisID int64) (*mod return fr, nil } +// ServisiBezFiskalnog vraća skup ID-eva servisnih naloga koji su u statusu "Preuzeto" +// a nemaju fiskalni račun (za oznaku u listi naloga). +func (r *FiskalRepo) ServisiBezFiskalnog(ctx context.Context) (map[int64]bool, error) { + rows, err := r.db.QueryContext(ctx, ` + SELECT sn.id FROM servisni_nalozi sn + LEFT JOIN fiskalni_racuni fr ON fr.servis_id = sn.id AND fr.storniran = 0 + WHERE sn.status = 'Preuzeto' AND fr.id IS NULL`) + if err != nil { + return nil, err + } + defer rows.Close() + out := make(map[int64]bool) + for rows.Next() { + var id int64 + if err := rows.Scan(&id); err != nil { + return nil, err + } + out[id] = true + } + return out, rows.Err() +} + // OznačiKaoStorniran postavlja storniran=1 za fiskalni račun sa datim ID-jem. func (r *FiskalRepo) OznačiKaoStorniran(ctx context.Context, id int64) error { _, err := r.db.ExecContext(ctx, "UPDATE fiskalni_racuni SET storniran = 1 WHERE id = ?", id) diff --git a/internal/handler/servis.go b/internal/handler/servis.go index 3603d88..38b9c97 100644 --- a/internal/handler/servis.go +++ b/internal/handler/servis.go @@ -29,12 +29,13 @@ import ( // PodaciServisa su podaci za stranicu sa listom servisnih naloga type PodaciServisa struct { model.PodaciStranice - Nalozi []model.ServisniNalogSaKlijentom - Pretraga string - FilterStatus string - SviStatusi []string - Sacuvano bool - Obrisan bool + Nalozi []model.ServisniNalogSaKlijentom + Pretraga string + FilterStatus string + SviStatusi []string + Sacuvano bool + Obrisan bool + NemaFiskalnog map[int64]bool // ID-evi naloga sa statusom Preuzeto koji nemaju fiskalni račun } // PodaciFormeNaloga su podaci za formu novog/izmenjenog servisnog naloga @@ -106,6 +107,10 @@ func (h *Handler) Servis(w http.ResponseWriter, r *http.Request) { ps := h.popuniPodaciStranice(r, podesavanja) ps.Stranica = "servis" ps.NaslovStranice = "Servis" + var nemaFiskalnog map[int64]bool + if h.modulUkljucen(r.Context(), config.ModulFiskalizacija) { + nemaFiskalnog, _ = h.FiskalRepo.ServisiBezFiskalnog(r.Context()) + } podaci := PodaciServisa{ PodaciStranice: ps, Nalozi: nalozi, @@ -114,6 +119,7 @@ func (h *Handler) Servis(w http.ResponseWriter, r *http.Request) { SviStatusi: model.SviStatusi, Sacuvano: r.URL.Query().Get("sacuvano") == "1", Obrisan: r.URL.Query().Get("obrisan") == "1", + NemaFiskalnog: nemaFiskalnog, } h.renderujTemplate(w, "servis", podaci) @@ -138,11 +144,16 @@ func (h *Handler) ArhivaServisa(w http.ResponseWriter, r *http.Request) { ps := h.popuniPodaciStranice(r, podesavanja) ps.Stranica = "servis" ps.NaslovStranice = "Arhiva servisa" + var nemaFiskalnog map[int64]bool + if h.modulUkljucen(r.Context(), config.ModulFiskalizacija) { + nemaFiskalnog, _ = h.FiskalRepo.ServisiBezFiskalnog(r.Context()) + } podaci := PodaciServisa{ PodaciStranice: ps, Nalozi: nalozi, Pretraga: pretraga, SviStatusi: model.SviStatusi, + NemaFiskalnog: nemaFiskalnog, } h.renderujTemplate(w, "servis_arhiva", podaci) diff --git a/web/templates/stranice/servis_arhiva.html b/web/templates/stranice/servis_arhiva.html index 88c4c38..8694916 100644 --- a/web/templates/stranice/servis_arhiva.html +++ b/web/templates/stranice/servis_arhiva.html @@ -48,6 +48,9 @@ style="font-size:14px;font-weight:500;color:var(--sb-akcent);text-decoration:none;font-family:monospace;"> {{.BrojNaloga}} + {{if index $.NemaFiskalnog .ID}} + ! + {{end}} {{if .KlijentNaziv}}{{.KlijentNaziv}}{{else}}—{{end}} @@ -81,7 +84,10 @@
-
{{.BrojNaloga}}
+
+ {{.BrojNaloga}} + {{if index $.NemaFiskalnog .ID}}!{{end}} +
{{.Uredjaj}}
{{template "status-badge" .Status}}