diff --git a/cmd/ntech/main.go b/cmd/ntech/main.go
index 8d637d8..61e22ed 100644
--- a/cmd/ntech/main.go
+++ b/cmd/ntech/main.go
@@ -364,6 +364,7 @@ func main() {
r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "servis.pregled")).Get("/servis/{id}/revers", h.StampaReversa)
r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "servis.pregled")).Get("/servis/{id}/predracun", h.StampaPredracuna)
r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "servis.pregled")).Get("/servis/{id}/nalepnica", h.StampaNalepnice)
+ r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "servis.pregled")).Get("/servis/{id}/garantni-list", h.StampaGarantnog)
r.With(doz("servis.izmeni")).Post("/servis/{id}/status", h.PromeniStatus)
r.With(doz("servis.izmeni")).Post("/servis/{id}/garancija", h.AzurirajGaranciju)
r.With(doz("servis.izmeni")).Post("/servis/{id}/garancija-dana", h.AzurirajGarancijaDana)
diff --git a/internal/handler/kes.go b/internal/handler/kes.go
index a57354e..ba07b86 100644
--- a/internal/handler/kes.go
+++ b/internal/handler/kes.go
@@ -43,7 +43,7 @@ var saSidebar = []string{
// standalone su šabloni bez base layouta
var standaloneIme = []string{
- "prijava", "setup", "totp_provera", "prodaja_stampa", "servis_radni_nalog", "servis_otpremnica", "servis_revers", "servis_predracun", "servis_nalepnica", "servis_status_javni",
+ "prijava", "setup", "totp_provera", "prodaja_stampa", "servis_radni_nalog", "servis_otpremnica", "servis_revers", "servis_predracun", "servis_nalepnica", "servis_status_javni", "servis_garantni_list",
}
// sablonskeFunkcije su pomoćne funkcije dostupne u svim šablonima.
diff --git a/internal/handler/servis.go b/internal/handler/servis.go
index 8f7803e..0a9598a 100644
--- a/internal/handler/servis.go
+++ b/internal/handler/servis.go
@@ -1438,6 +1438,18 @@ func (h *Handler) StampaOtpremnice(w http.ResponseWriter, r *http.Request) {
qrKodOtpr = base64.StdEncoding.EncodeToString(png)
}
+ // GarancijaDo se računa od završetka, ne od prijema
+ if nalog.GarancijaDana == nil || *nalog.GarancijaDana <= 0 {
+ nalog.GarancijaDo = nil
+ } else {
+ baza := time.Now()
+ if nalog.DatumZavrsetka != nil {
+ baza = *nalog.DatumZavrsetka
+ }
+ t := baza.AddDate(0, 0, *nalog.GarancijaDana)
+ nalog.GarancijaDo = &t
+ }
+
h.renderujStandalone(w, "servis_otpremnica", PodaciOtpremnice{
Nalog: *nalog,
ServisniDelovi: delovi,
@@ -1459,6 +1471,113 @@ func (h *Handler) StampaOtpremnice(w http.ResponseWriter, r *http.Request) {
})
}
+// PodaciGarantnog su podaci za garantni list koji se predaje klijentu pri preuzimanju.
+type PodaciGarantnog struct {
+ Nalog model.ServisniNalog
+ GarancijaDo *time.Time // izračunato od DatumZavrsetka + GarancijaDana
+ GarancijaTekst string // npr. "60 dana"
+ Radovi []model.ServisniRad
+ ServisniDelovi []model.ServisniDeoSaArtiklom
+ Klijent *model.Klijent
+ KlijentNaziv string
+ TehnicarNaziv string
+ Uslovi string
+ NazivFirme string
+ LogoPutanja string
+ Podnazlov string
+ Adresa string
+ Telefon string
+ PIB string
+ MaticniBroj string
+ Barkod string
+}
+
+// StampaGarantnog renderuje garantni list (dostupno od statusa Završeno, samo ako ima garancija)
+func (h *Handler) StampaGarantnog(w http.ResponseWriter, r *http.Request) {
+ id, err := parseID(chi.URLParam(r, "id"))
+ if err != nil {
+ http.Error(w, "Neispravan ID naloga", http.StatusBadRequest)
+ return
+ }
+
+ nalog, err := h.ServisRepo.DohvatiID(r.Context(), id)
+ if err != nil {
+ http.Error(w, "Nalog nije pronađen", http.StatusNotFound)
+ return
+ }
+
+ if nalog.GarancijaDana == nil || *nalog.GarancijaDana <= 0 {
+ http.Error(w, "Nalog nema definisanu garanciju", http.StatusBadRequest)
+ return
+ }
+
+ podesavanja, err := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
+ if err != nil {
+ http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
+ return
+ }
+
+ radovi, err := h.ServisniRadoviRepo.DohvatiZaNalog(r.Context(), id)
+ if err != nil {
+ http.Error(w, "Greška pri učitavanju radova", http.StatusInternalServerError)
+ return
+ }
+
+ delovi, err := h.deloviSaPotrazivanima(r.Context(), id)
+ if err != nil {
+ http.Error(w, "Greška pri učitavanju delova", http.StatusInternalServerError)
+ return
+ }
+
+ var klijent *model.Klijent
+ klijentNaziv := ""
+ if nalog.KlijentID != nil {
+ k, err := h.KlijentiRepo.DohvatiID(r.Context(), *nalog.KlijentID)
+ if err == nil {
+ klijent = k
+ if k.NazivFirme != "" {
+ klijentNaziv = k.NazivFirme
+ } else {
+ klijentNaziv = strings.TrimSpace(k.Ime + " " + k.Prezime)
+ }
+ }
+ }
+
+ tehnicarNaziv := ""
+ if nalog.TehnicarID != nil {
+ tehnicar, err := h.KorisniciRepo.DohvatiPoID(r.Context(), *nalog.TehnicarID)
+ if err == nil {
+ tehnicarNaziv = tehnicar.KorisnickoIme
+ }
+ }
+
+ baza := time.Now()
+ if nalog.DatumZavrsetka != nil {
+ baza = *nalog.DatumZavrsetka
+ }
+ garanDo := baza.AddDate(0, 0, *nalog.GarancijaDana)
+
+ h.renderujStandalone(w, "servis_garantni_list", PodaciGarantnog{
+ Nalog: *nalog,
+ GarancijaDo: &garanDo,
+ GarancijaTekst: garancijaUTekst(*nalog.GarancijaDana),
+ Radovi: radovi,
+ ServisniDelovi: delovi,
+ Klijent: klijent,
+ KlijentNaziv: klijentNaziv,
+ TehnicarNaziv: tehnicarNaziv,
+ Uslovi: vrednostIliDefault(podesavanja, "servis_uslovi", podrazumevaniUsloviServisa),
+ NazivFirme: podesavanja["naziv_firme"],
+ LogoPutanja: logoZaDokument(podesavanja),
+ Podnazlov: podesavanja["podnazlov"],
+ Adresa: podesavanja["adresa"],
+ Telefon: podesavanja["telefon"],
+ PIB: podesavanja["pib"],
+ MaticniBroj: podesavanja["maticni_broj"],
+ Barkod: barkodNaloga(nalog.BrojNaloga),
+ })
+}
+
// PodaciReversa su podaci za revers — potvrdu o prijemu uređaja na servis.
// Dokument se izdaje pri prijemu, pa nema cena.
type PodaciReversa struct {
diff --git a/web/templates/stranice/servis_detalji.html b/web/templates/stranice/servis_detalji.html
index e2e0d4f..fc9f34a 100644
--- a/web/templates/stranice/servis_detalji.html
+++ b/web/templates/stranice/servis_detalji.html
@@ -149,6 +149,11 @@
Otpremnica
+ {{if not .BezGarancije}}
+
+ Garantni list
+
+ {{end}}
{{end}}
{{/* Nalepnica je primarna pri prijemu (lepi se na uređaj); reprint dok traje; ne u „Završeno" */}}
{{if eq .Nalog.Status "Primljeno"}}
diff --git a/web/templates/stranice/servis_garantni_list.html b/web/templates/stranice/servis_garantni_list.html
new file mode 100644
index 0000000..0e19059
--- /dev/null
+++ b/web/templates/stranice/servis_garantni_list.html
@@ -0,0 +1,240 @@
+
+
+
+
+
+ Garantni list — {{.Nalog.BrojNaloga}}
+
+
+
+
+
+
+
+
+
+ {{if .LogoPutanja}}
+

+ {{else}}
+
{{if .NazivFirme}}{{.NazivFirme}}{{else}}— naziv firme —{{end}}
+ {{end}}
+
+ {{if .Podnazlov}}{{.Podnazlov}}
{{end}}
+ {{if .Adresa}}{{.Adresa}}
{{end}}
+ {{if .Telefon}}Tel: {{telefon .Telefon}}
{{end}}
+ {{if .PIB}}PIB: {{.PIB}}{{end}}{{if .MaticniBroj}}{{if .PIB}} · {{end}}MB: {{.MaticniBroj}}{{end}}
+
+
+
+
+ {{if .Barkod}}

{{end}}
+
Garantni list
+
{{.Nalog.BrojNaloga}}
+ {{if .Nalog.DatumZavrsetka}}
+
Datum završetka: {{.Nalog.DatumZavrsetka.Format "02.01.2006."}}
+ {{end}}
+ {{if .TehnicarNaziv}}
+
Serviser: {{.TehnicarNaziv}}
+ {{end}}
+
+
+
+
Klijent
+ {{if .KlijentNaziv}}
+
{{.KlijentNaziv}}
+
+ {{if .Klijent}}
+ {{if .Klijent.Telefon}}Tel: {{telefon .Klijent.Telefon}}
{{end}}
+ {{if .Klijent.Email}}{{.Klijent.Email}}
{{end}}
+ {{if .Klijent.Mesto}}{{.Klijent.Mesto}}{{end}}
+ {{end}}
+
+ {{else}}
+
— klijent nije naveden —
+ {{end}}
+
+
+
+
+
+
+
Garancija na izvršeni servis
+
Trajanje: {{.GarancijaTekst}}
+
+
+
Važi do:
+
{{.GarancijaDo.Format "02.01.2006."}}
+
+
+
+
+
+
Uređaj
+
+
+
Naziv uređaja
+
{{if .Nalog.Uredjaj}}{{.Nalog.Uredjaj}}{{else}}—{{end}}
+
+
+
Serijski broj
+
{{if .Nalog.SerijskiBroj}}{{.Nalog.SerijskiBroj}}{{else}}—{{end}}
+
+
+
Datum prijema
+
{{.Nalog.DatumPrijema.Format "02.01.2006."}}
+
+
+
+
+
+
+
Urađeni radovi
+ {{if .Radovi}}
+
+
+
+ | Opis rada |
+ Kol. |
+ Cena |
+ Ukupno |
+
+
+
+ {{range .Radovi}}
+
+ | {{.Naziv}} |
+ {{printf "%.0f" .Kolicina}} |
+ {{dinari .CenaKomada}} |
+ {{dinari .Ukupno}} |
+
+ {{end}}
+
+
+ {{else}}
+
Nisu evidentirani posebni radovi.
+ {{end}}
+
+
+
+
+
Zamenjeni delovi / materijal
+ {{if .ServisniDelovi}}
+
+
+
+ | Naziv |
+ Šifra |
+ Kol. |
+ Cena |
+ Ukupno |
+
+
+
+ {{range .ServisniDelovi}}
+ {{if not .Predlozeno}}
+
+ | {{.ArtikalNaziv}} |
+ {{.ArtikalSifra}} |
+ {{.Kolicina}} |
+ {{dinari .CenaKomada}} |
+ {{dinari .Ukupno}} |
+
+ {{end}}
+ {{end}}
+
+
+ {{else}}
+
Nisu evidentirani zamenjeni delovi.
+ {{end}}
+
+
+
+ {{if .Nalog.NapomenaKlijentu}}
+
+
Napomena
+
{{.Nalog.NapomenaKlijentu}}
+
+ {{end}}
+
+
+ {{if .Uslovi}}
+
+
Uslovi garancije
+
{{.Uslovi}}
+
+ {{end}}
+
+
+
+
+
Garantni list važi uz predočenje ovog dokumenta i originalnog reversa.
+
+
+
+
+