Servis: polja Tražene nadogradnje i Napomena klijentu (auto-snimanje)

This commit is contained in:
2026-06-22 19:39:49 +02:00
parent 818500ed8f
commit 4987f68af1
10 changed files with 130 additions and 44 deletions
+1
View File
@@ -360,6 +360,7 @@ func main() {
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}/predracun", h.StampaPredracuna)
r.With(doz("servis.izmeni")).Post("/servis/{id}/status", h.PromeniStatus) 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", h.AzurirajGaranciju)
r.With(doz("servis.izmeni")).Post("/servis/{id}/napomena-klijentu", h.SacuvajNapomenuKlijentu)
r.With(doz("servis.izmeni")).Post("/servis/{id}/delovi", h.DodajDeloNalogu) r.With(doz("servis.izmeni")).Post("/servis/{id}/delovi", h.DodajDeloNalogu)
r.With(doz("servis.izmeni")).Post("/servis/{id}/delovi/{deo_id}/obrisi", h.ObrisiDeloNaloga) r.With(doz("servis.izmeni")).Post("/servis/{id}/delovi/{deo_id}/obrisi", h.ObrisiDeloNaloga)
r.With(doz("servis.izmeni")).Post("/servis/{id}/radovi", h.DodajRadNalogu) r.With(doz("servis.izmeni")).Post("/servis/{id}/radovi", h.DodajRadNalogu)
+1
View File
@@ -192,6 +192,7 @@ type ServisRepository interface {
Izmeni(ctx context.Context, n *model.ServisniNalog) error Izmeni(ctx context.Context, n *model.ServisniNalog) error
AzurirajStatus(ctx context.Context, id int64, status string) error AzurirajStatus(ctx context.Context, id int64, status string) error
AzurirajGaranciju(ctx context.Context, id int64, garancijaDo *time.Time) error AzurirajGaranciju(ctx context.Context, id int64, garancijaDo *time.Time) error
AzurirajNapomenuKlijentu(ctx context.Context, id int64, tekst string) error
Obrisi(ctx context.Context, id int64, korisnikID *int64) error Obrisi(ctx context.Context, id int64, korisnikID *int64) error
SledeciBroj(ctx context.Context) (string, error) SledeciBroj(ctx context.Context) (string, error)
} }
+26 -14
View File
@@ -56,9 +56,9 @@ func (r *ServisRepo) Lista(ctx context.Context, pretraga, status string) ([]mode
upit := ` upit := `
SELECT SELECT
sn.id, sn.klijent_id, sn.tehnicar_id, sn.broj_naloga, sn.uredjaj, sn.serijski_broj, sn.id, sn.klijent_id, sn.tehnicar_id, sn.broj_naloga, sn.uredjaj, sn.serijski_broj,
sn.opis_kvara, sn.status, sn.cena_od, sn.cena_do, sn.cena_konacna, sn.opis_kvara, sn.trazene_nadogradnje, sn.status, sn.cena_od, sn.cena_do, sn.cena_konacna,
sn.avans, sn.napomena, sn.garancija_do, sn.datum_prijema, sn.datum_zavrsetka, sn.avans, sn.napomena, sn.garancija_do, sn.datum_prijema, sn.datum_zavrsetka,
sn.ostecenja, sn.pin_uredjaja, sn.pribor, sn.javni_token, sn.ostecenja, sn.pin_uredjaja, sn.pribor, sn.napomena_klijentu, sn.javni_token,
COALESCE(kp.naziv, '') AS klijent_naziv COALESCE(kp.naziv, '') AS klijent_naziv
FROM servisni_nalozi sn FROM servisni_nalozi sn
LEFT JOIN klijent_prikaz kp ON kp.id = sn.klijent_id LEFT JOIN klijent_prikaz kp ON kp.id = sn.klijent_id
@@ -103,9 +103,9 @@ func (r *ServisRepo) DohvatiID(ctx context.Context, id int64) (*model.ServisniNa
red := r.db.QueryRowContext(ctx, ` red := r.db.QueryRowContext(ctx, `
SELECT SELECT
id, klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj, id, klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj,
opis_kvara, status, cena_od, cena_do, cena_konacna, opis_kvara, trazene_nadogradnje, status, cena_od, cena_do, cena_konacna,
avans, napomena, garancija_do, datum_prijema, datum_zavrsetka, avans, napomena, garancija_do, datum_prijema, datum_zavrsetka,
ostecenja, pin_uredjaja, pribor, javni_token ostecenja, pin_uredjaja, pribor, napomena_klijentu, javni_token
FROM servisni_nalozi WHERE id = ?`, id) FROM servisni_nalozi WHERE id = ?`, id)
var n model.ServisniNalog var n model.ServisniNalog
@@ -126,12 +126,12 @@ func (r *ServisRepo) Kreiraj(ctx context.Context, n *model.ServisniNalog) (int64
rezultat, err := r.db.ExecContext(ctx, ` rezultat, err := r.db.ExecContext(ctx, `
INSERT INTO servisni_nalozi INSERT INTO servisni_nalozi
(klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj, opis_kvara, (klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj, opis_kvara, trazene_nadogradnje,
status, cena_od, cena_do, cena_konacna, avans, napomena, garancija_do, datum_zavrsetka, status, cena_od, cena_do, cena_konacna, avans, napomena, garancija_do, datum_zavrsetka,
ostecenja, pin_uredjaja, pribor, datum_prijema, javni_token) ostecenja, pin_uredjaja, pribor, datum_prijema, javni_token)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
nullInt64(n.KlijentID), nullInt64(n.TehnicarID), n.BrojNaloga, n.Uredjaj, nullInt64(n.KlijentID), nullInt64(n.TehnicarID), n.BrojNaloga, n.Uredjaj,
nullString(n.SerijskiBroj), n.OpisKvara, n.Status, nullString(n.SerijskiBroj), n.OpisKvara, nullString(n.TrazeneNadogradnje), n.Status,
nullFloat64(n.CenaOd), nullFloat64(n.CenaDo), nullFloat64(n.CenaKonacna), nullFloat64(n.CenaOd), nullFloat64(n.CenaDo), nullFloat64(n.CenaKonacna),
nullFloat64(n.Avans), nullString(n.Napomena), nullFloat64(n.Avans), nullString(n.Napomena),
nullTime(n.GarancijaDo), nullTime(n.DatumZavrsetka), nullTime(n.GarancijaDo), nullTime(n.DatumZavrsetka),
@@ -155,9 +155,9 @@ func (r *ServisRepo) DohvatiJavniToken(ctx context.Context, token string) (*mode
red := r.db.QueryRowContext(ctx, ` red := r.db.QueryRowContext(ctx, `
SELECT SELECT
id, klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj, id, klijent_id, tehnicar_id, broj_naloga, uredjaj, serijski_broj,
opis_kvara, status, cena_od, cena_do, cena_konacna, opis_kvara, trazene_nadogradnje, status, cena_od, cena_do, cena_konacna,
avans, napomena, garancija_do, datum_prijema, datum_zavrsetka, avans, napomena, garancija_do, datum_prijema, datum_zavrsetka,
ostecenja, pin_uredjaja, pribor, javni_token ostecenja, pin_uredjaja, pribor, napomena_klijentu, javni_token
FROM servisni_nalozi WHERE javni_token = ?`, token) FROM servisni_nalozi WHERE javni_token = ?`, token)
var n model.ServisniNalog var n model.ServisniNalog
@@ -171,12 +171,12 @@ func (r *ServisRepo) DohvatiJavniToken(ctx context.Context, token string) (*mode
func (r *ServisRepo) Izmeni(ctx context.Context, n *model.ServisniNalog) error { func (r *ServisRepo) Izmeni(ctx context.Context, n *model.ServisniNalog) error {
_, err := r.db.ExecContext(ctx, ` _, err := r.db.ExecContext(ctx, `
UPDATE servisni_nalozi SET UPDATE servisni_nalozi SET
klijent_id = ?, tehnicar_id = ?, uredjaj = ?, serijski_broj = ?, opis_kvara = ?, klijent_id = ?, tehnicar_id = ?, uredjaj = ?, serijski_broj = ?, opis_kvara = ?, trazene_nadogradnje = ?,
status = ?, cena_od = ?, cena_do = ?, cena_konacna = ?, status = ?, cena_od = ?, cena_do = ?, cena_konacna = ?,
avans = ?, napomena = ?, garancija_do = ?, datum_zavrsetka = ?, avans = ?, napomena = ?, garancija_do = ?, datum_zavrsetka = ?,
ostecenja = ?, pin_uredjaja = ?, pribor = ? ostecenja = ?, pin_uredjaja = ?, pribor = ?
WHERE id = ?`, WHERE id = ?`,
nullInt64(n.KlijentID), nullInt64(n.TehnicarID), n.Uredjaj, nullString(n.SerijskiBroj), n.OpisKvara, nullInt64(n.KlijentID), nullInt64(n.TehnicarID), n.Uredjaj, nullString(n.SerijskiBroj), n.OpisKvara, nullString(n.TrazeneNadogradnje),
n.Status, nullFloat64(n.CenaOd), nullFloat64(n.CenaDo), nullFloat64(n.CenaKonacna), n.Status, nullFloat64(n.CenaOd), nullFloat64(n.CenaDo), nullFloat64(n.CenaKonacna),
nullFloat64(n.Avans), nullString(n.Napomena), nullTime(n.GarancijaDo), nullTime(n.DatumZavrsetka), nullFloat64(n.Avans), nullString(n.Napomena), nullTime(n.GarancijaDo), nullTime(n.DatumZavrsetka),
nullString(n.Ostecenja), nullString(n.PinUredjaja), nullString(n.Pribor), nullString(n.Ostecenja), nullString(n.PinUredjaja), nullString(n.Pribor),
@@ -229,6 +229,17 @@ func (r *ServisRepo) AzurirajGaranciju(ctx context.Context, id int64, garancijaD
return nil return nil
} }
// AzurirajNapomenuKlijentu postavlja tekst napomene namenjene klijentu na nalogu
func (r *ServisRepo) AzurirajNapomenuKlijentu(ctx context.Context, id int64, tekst string) error {
_, err := r.db.ExecContext(ctx,
"UPDATE servisni_nalozi SET napomena_klijentu = ? WHERE id = ?", tekst, id,
)
if err != nil {
return fmt.Errorf("ntech: ServisRepo.AzurirajNapomenuKlijentu: %w", err)
}
return nil
}
// Obrisi briše servisni nalog po ID-u // Obrisi briše servisni nalog po ID-u
// Obrisi briše servisni nalog i vraća ugrađene delove na stanje u magacinu (u transakciji) // Obrisi briše servisni nalog i vraća ugrađene delove na stanje u magacinu (u transakciji)
func (r *ServisRepo) Obrisi(ctx context.Context, id int64, korisnikID *int64) error { func (r *ServisRepo) Obrisi(ctx context.Context, id int64, korisnikID *int64) error {
@@ -310,15 +321,15 @@ func (r *ServisRepo) Obrisi(ctx context.Context, id int64, korisnikID *int64) er
// klijentNaziv je opcioni pokazivač, nil kada se čita bez JOIN-a // klijentNaziv je opcioni pokazivač, nil kada se čita bez JOIN-a
func scanNalog(scan func(...any) error, n *model.ServisniNalog, klijentNaziv *string) error { func scanNalog(scan func(...any) error, n *model.ServisniNalog, klijentNaziv *string) error {
var klijentID, tehnicarID sql.NullInt64 var klijentID, tehnicarID sql.NullInt64
var serijskiBroj, napomena, ostecenja, pinUredjaja, pribor, javniToken sql.NullString var serijskiBroj, napomena, ostecenja, pinUredjaja, pribor, napomenaKlijentu, javniToken sql.NullString
var cenaOd, cenaDo, cenaKonacna, avans sql.NullFloat64 var cenaOd, cenaDo, cenaKonacna, avans sql.NullFloat64
var garancijaDo, datumZavrsetka sql.NullTime var garancijaDo, datumZavrsetka sql.NullTime
args := []any{ args := []any{
&n.ID, &klijentID, &tehnicarID, &n.BrojNaloga, &n.Uredjaj, &serijskiBroj, &n.ID, &klijentID, &tehnicarID, &n.BrojNaloga, &n.Uredjaj, &serijskiBroj,
&n.OpisKvara, &n.Status, &cenaOd, &cenaDo, &cenaKonacna, &n.OpisKvara, &n.TrazeneNadogradnje, &n.Status, &cenaOd, &cenaDo, &cenaKonacna,
&avans, &napomena, &garancijaDo, &n.DatumPrijema, &datumZavrsetka, &avans, &napomena, &garancijaDo, &n.DatumPrijema, &datumZavrsetka,
&ostecenja, &pinUredjaja, &pribor, &javniToken, &ostecenja, &pinUredjaja, &pribor, &napomenaKlijentu, &javniToken,
} }
if klijentNaziv != nil { if klijentNaziv != nil {
@@ -342,6 +353,7 @@ func scanNalog(scan func(...any) error, n *model.ServisniNalog, klijentNaziv *st
n.Ostecenja = ostecenja.String n.Ostecenja = ostecenja.String
n.PinUredjaja = pinUredjaja.String n.PinUredjaja = pinUredjaja.String
n.Pribor = pribor.String n.Pribor = pribor.String
n.NapomenaKlijentu = napomenaKlijentu.String
if cenaOd.Valid { if cenaOd.Valid {
v := cenaOd.Float64 v := cenaOd.Float64
n.CenaOd = &v n.CenaOd = &v
+34 -10
View File
@@ -772,16 +772,17 @@ func parseFormuNaloga(r *http.Request) (model.ServisniNalog, string) {
} }
nalog := model.ServisniNalog{ nalog := model.ServisniNalog{
BrojNaloga: strings.TrimSpace(r.FormValue("broj_naloga")), BrojNaloga: strings.TrimSpace(r.FormValue("broj_naloga")),
Uredjaj: uredjaj, Uredjaj: uredjaj,
SerijskiBroj: strings.TrimSpace(r.FormValue("serijski_broj")), SerijskiBroj: strings.TrimSpace(r.FormValue("serijski_broj")),
OpisKvara: opisKvara, OpisKvara: opisKvara,
Status: r.FormValue("status"), TrazeneNadogradnje: strings.TrimSpace(r.FormValue("trazene_nadogradnje")),
Napomena: strings.TrimSpace(r.FormValue("napomena")), Status: r.FormValue("status"),
Ostecenja: strings.TrimSpace(r.FormValue("ostecenja")), Napomena: strings.TrimSpace(r.FormValue("napomena")),
PinUredjaja: strings.TrimSpace(r.FormValue("pin_uredjaja")), Ostecenja: strings.TrimSpace(r.FormValue("ostecenja")),
Pribor: strings.TrimSpace(r.FormValue("pribor")), PinUredjaja: strings.TrimSpace(r.FormValue("pin_uredjaja")),
DatumPrijema: time.Now(), Pribor: strings.TrimSpace(r.FormValue("pribor")),
DatumPrijema: time.Now(),
} }
// datum prijema — korisnik može da unese drugi datum (npr. retroaktivno) // datum prijema — korisnik može da unese drugi datum (npr. retroaktivno)
@@ -1364,6 +1365,29 @@ func (h *Handler) AzurirajGaranciju(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/servis/"+strconv.FormatInt(id, 10), http.StatusSeeOther) http.Redirect(w, r, "/servis/"+strconv.FormatInt(id, 10), http.StatusSeeOther)
} }
// SacuvajNapomenuKlijentu ažurira napomenu namenjenu klijentu na nalogu
func (h *Handler) SacuvajNapomenuKlijentu(w http.ResponseWriter, r *http.Request) {
if _, ok := h.zahtevajDozvolu(w, r, "servis.izmeni"); !ok {
return
}
id, err := parseID(chi.URLParam(r, "id"))
if err != nil {
http.Error(w, "Neispravan ID naloga", http.StatusBadRequest)
return
}
if err := r.ParseForm(); err != nil {
http.Error(w, "Greška pri čitanju forme", http.StatusBadRequest)
return
}
tekst := strings.TrimSpace(r.FormValue("napomena_klijentu"))
if err := h.ServisRepo.AzurirajNapomenuKlijentu(r.Context(), id, tekst); err != nil {
slog.Error("greška pri ažuriranju napomene klijentu", "id", id, "error", err)
http.Error(w, "Greška pri ažuriranju napomene", http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/servis/"+strconv.FormatInt(id, 10), http.StatusSeeOther)
}
// PodaciJavnogStatusa su podaci za javnu status stranicu servisnog naloga // PodaciJavnogStatusa su podaci za javnu status stranicu servisnog naloga
type PodaciJavnogStatusa struct { type PodaciJavnogStatusa struct {
Nalog model.ServisniNalog Nalog model.ServisniNalog
+22 -20
View File
@@ -25,26 +25,28 @@ var SviStatusi = []string{
// ServisniNalog predstavlja jedan servisni nalog // ServisniNalog predstavlja jedan servisni nalog
type ServisniNalog struct { type ServisniNalog struct {
ID int64 ID int64
KlijentID *int64 KlijentID *int64
TehnicarID *int64 TehnicarID *int64
BrojNaloga string BrojNaloga string
Uredjaj string Uredjaj string
SerijskiBroj string SerijskiBroj string
OpisKvara string OpisKvara string
Status string TrazeneNadogradnje string
CenaOd *float64 Status string
CenaDo *float64 CenaOd *float64
CenaKonacna *float64 CenaDo *float64
Avans *float64 CenaKonacna *float64
Napomena string Avans *float64
GarancijaDo *time.Time Napomena string
DatumPrijema time.Time GarancijaDo *time.Time
DatumZavrsetka *time.Time DatumPrijema time.Time
Ostecenja string DatumZavrsetka *time.Time
PinUredjaja string Ostecenja string
Pribor string PinUredjaja string
JavniToken string Pribor string
NapomenaKlijentu string
JavniToken string
} }
// ServisniDeo predstavlja jedan artikal ugrađen u servisni nalog // ServisniDeo predstavlja jedan artikal ugrađen u servisni nalog
@@ -0,0 +1,3 @@
-- tražene nadogradnje: ono što klijent želi da se dogradi/poboljša,
-- odvojeno od opis_kvara (ono što ne radi)
ALTER TABLE servisni_nalozi ADD COLUMN trazene_nadogradnje TEXT NOT NULL DEFAULT '';
@@ -0,0 +1,3 @@
-- napomena klijentu: poruka koju serviser ostavlja klijentu (vidljiva na nalogu),
-- odvojeno od interne napomene
ALTER TABLE servisni_nalozi ADD COLUMN napomena_klijentu TEXT NOT NULL DEFAULT '';
@@ -135,6 +135,12 @@
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:6px;">Opis kvara</div> <div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:6px;">Opis kvara</div>
<div style="font-size:14px;color:var(--tekst-glavni);line-height:1.6;white-space:pre-wrap;">{{.Nalog.OpisKvara}}</div> <div style="font-size:14px;color:var(--tekst-glavni);line-height:1.6;white-space:pre-wrap;">{{.Nalog.OpisKvara}}</div>
</div> </div>
{{if .Nalog.TrazeneNadogradnje}}
<div>
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:6px;">Tražene nadogradnje</div>
<div style="font-size:14px;color:var(--tekst-glavni);line-height:1.6;white-space:pre-wrap;">{{.Nalog.TrazeneNadogradnje}}</div>
</div>
{{end}}
{{if or .Nalog.Ostecenja .Nalog.PinUredjaja .Nalog.Pribor}} {{if or .Nalog.Ostecenja .Nalog.PinUredjaja .Nalog.Pribor}}
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));gap:16px;"> <div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));gap:16px;">
{{if .Nalog.Ostecenja}} {{if .Nalog.Ostecenja}}
@@ -166,6 +172,28 @@
</div> </div>
</div> </div>
<!-- napomena klijentu -->
<div class="kartica detalji-kartica animiraj" id="napomena-klijentu-kartica">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);flex-wrap:wrap;gap:10px;">
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Napomena klijentu</span>
</div>
{{if index .Dozvole "servis.izmeni"}}
<!-- forma se sama snima kad textarea izgubi fokus (bez dugmeta); data-refresh osvežava samo ovu karticu -->
<form method="POST" action="/servis/{{.Nalog.ID}}/napomena-klijentu" data-refresh="#napomena-klijentu-kartica">
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
<textarea name="napomena_klijentu" rows="3"
placeholder="Poruka koju ostavljate klijentu uz nalog..."
style="width:100%;resize:vertical;"
data-poc="{{.Nalog.NapomenaKlijentu}}"
onblur="if(this.value!==this.dataset.poc){this.dataset.poc=this.value;(this.form.requestSubmit?this.form.requestSubmit():this.form.submit());}">{{.Nalog.NapomenaKlijentu}}</textarea>
</form>
{{else}}
<div style="font-size:13px;color:var(--tekst-sporedni);line-height:1.6;white-space:pre-wrap;">
{{if .Nalog.NapomenaKlijentu}}{{.Nalog.NapomenaKlijentu}}{{else}}<span style="color:var(--tekst-sporedni);font-style:italic;">Nema napomene.</span>{{end}}
</div>
{{end}}
</div>
<!-- radovi (usluge) --> <!-- radovi (usluge) -->
<div class="kartica detalji-kartica animiraj"> <div class="kartica detalji-kartica animiraj">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);flex-wrap:wrap;gap:10px;"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);flex-wrap:wrap;gap:10px;">
+6
View File
@@ -65,6 +65,12 @@
placeholder="Opišite problem koji je klijent prijavio..." placeholder="Opišite problem koji je klijent prijavio..."
style="width:100%;resize:vertical;">{{.Nalog.OpisKvara}}</textarea> style="width:100%;resize:vertical;">{{.Nalog.OpisKvara}}</textarea>
</div> </div>
<div>
<label class="polje-labela">Tražene nadogradnje</label>
<textarea name="trazene_nadogradnje" rows="2"
placeholder="Šta klijent želi da se dogradi/poboljša (npr. veći SSD, dodatni RAM)..."
style="width:100%;resize:vertical;">{{.Nalog.TrazeneNadogradnje}}</textarea>
</div>
<div class="forma-grid-2" style="display:grid;grid-template-columns:1fr 1fr;gap:12px;"> <div class="forma-grid-2" style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div> <div>
<label class="polje-labela">Oštećenja pri prijemu</label> <label class="polje-labela">Oštećenja pri prijemu</label>
@@ -152,6 +152,12 @@
<div class="polje-labela">Opis kvara</div> <div class="polje-labela">Opis kvara</div>
<div class="polje-tekst">{{if .Nalog.OpisKvara}}{{.Nalog.OpisKvara}}{{else}}<span class="prazno"></span>{{end}}</div> <div class="polje-tekst">{{if .Nalog.OpisKvara}}{{.Nalog.OpisKvara}}{{else}}<span class="prazno"></span>{{end}}</div>
</div> </div>
{{if .Nalog.TrazeneNadogradnje}}
<div style="margin-bottom:10px;">
<div class="polje-labela">Tražene nadogradnje</div>
<div class="polje-tekst">{{.Nalog.TrazeneNadogradnje}}</div>
</div>
{{end}}
{{if or .Nalog.Ostecenja .Nalog.Pribor}} {{if or .Nalog.Ostecenja .Nalog.Pribor}}
<div class="podaci-grid-2"> <div class="podaci-grid-2">
{{if .Nalog.Ostecenja}} {{if .Nalog.Ostecenja}}