b0250b2917
Šifre artikala: - Kôd kategorije kao prefiks auto-šifre (PREFIKS-NNNN), otporno na brisanje (max+1) - Tip artikla (proizvod/usluga/trošak) i jedinica mere - Arhiviranje artikala umesto brisanja kad su već u prometu Magacin: - Paginacija 50 po stranici - Klikabilna šifra (vodi na karticu), opisniji placeholder pretrage - Ispravka: pretraga više ne okida animaciju redova (globalni htmx listener umesto hx-on atributa koji se ne okida u ovoj htmx verziji) - Dugmad akcija ne prelamaju tekst; uklonjen content-visibility (secanje pri skrolu) Servis: predračun (nova stranica i ruta)
334 lines
17 KiB
HTML
334 lines
17 KiB
HTML
{{template "base" .}}
|
|
|
|
{{define "naslov"}}Detalji naloga — NTech{{end}}
|
|
|
|
{{define "dodatni-css"}}
|
|
<style>
|
|
.detalji-kartica:nth-child(1) { animation-delay: 0.04s; }
|
|
.detalji-kartica:nth-child(2) { animation-delay: 0.12s; }
|
|
.detalji-kartica:nth-child(3) { animation-delay: 0.20s; }
|
|
.detalji-kartica:nth-child(4) { animation-delay: 0.28s; }
|
|
.detalji-kartica:nth-child(5) { animation-delay: 0.36s; }
|
|
</style>
|
|
{{end}}
|
|
|
|
{{define "status-badge-detalji"}}
|
|
{{if eq . "Primljeno"}}<span class="status-badge status-primljeno">{{.}}</span>
|
|
{{else if eq . "U dijagnostici"}}<span class="status-badge status-dijagnostika">{{.}}</span>
|
|
{{else if eq . "Čeka delove"}}<span class="status-badge status-ceka">{{.}}</span>
|
|
{{else if eq . "U popravci"}}<span class="status-badge status-popravka">{{.}}</span>
|
|
{{else if eq . "Završeno"}}<span class="status-badge status-zavrseno">{{.}}</span>
|
|
{{else if eq . "Preuzeto"}}<span class="status-badge status-preuzeto">{{.}}</span>
|
|
{{else}}<span class="status-badge status-primljeno">{{.}}</span>
|
|
{{end}}
|
|
{{end}}
|
|
|
|
{{define "sadrzaj"}}
|
|
<div class="kolona" style="gap:16px;">
|
|
|
|
{{if .Sacuvano}}
|
|
<div class="poruka-uspeh poruka-animacija">Nalog je uspešno sačuvan.</div>
|
|
{{end}}
|
|
|
|
<!-- nazad dugme -->
|
|
<a href="/servis" class="nazad-link">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
|
|
Nazad na servis
|
|
</a>
|
|
|
|
<!-- zaglavlje naloga -->
|
|
<div class="kartica detalji-kartica animiraj">
|
|
<div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:12px;margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
|
|
<div class="kolona" style="gap:8px;">
|
|
<span style="font-size:20px;font-weight:600;color:var(--tekst-glavni);font-family:monospace;">
|
|
{{.Nalog.BrojNaloga}}
|
|
</span>
|
|
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">
|
|
{{template "status-badge-detalji" .Nalog.Status}}
|
|
<form method="post" action="/servis/{{.Nalog.ID}}/status" style="display:flex;align-items:center;gap:6px;">
|
|
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
|
|
<select name="status" style="font-size:13px;padding:4px 8px;border-radius:6px;border:0.5px solid var(--ivica);background:var(--kartica-pozadina);color:var(--tekst-glavni);cursor:pointer;">
|
|
{{range .SviStatusi}}
|
|
<option value="{{.}}"{{if eq . $.Nalog.Status}} selected{{end}}>{{.}}</option>
|
|
{{end}}
|
|
</select>
|
|
<button type="submit" class="btn-sekundarno" style="font-size:13px;padding:4px 12px;">Promeni</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div style="display:flex;gap:8px;flex-wrap:wrap;">
|
|
{{if not (or (eq .Nalog.Status "Završeno") (eq .Nalog.Status "Preuzeto"))}}
|
|
<a href="/servis/{{.Nalog.ID}}/stampa" target="_blank" class="btn-sekundarno">
|
|
Radni nalog
|
|
</a>
|
|
<a href="/servis/{{.Nalog.ID}}/predracun" target="_blank" class="btn-sekundarno">
|
|
Predračun
|
|
</a>
|
|
{{end}}
|
|
{{if or (eq .Nalog.Status "Završeno") (eq .Nalog.Status "Preuzeto")}}
|
|
<a href="/servis/{{.Nalog.ID}}/otpremnica" target="_blank" class="btn-sekundarno">
|
|
Otpremnica
|
|
</a>
|
|
{{end}}
|
|
<a href="/servis/izmeni/{{.Nalog.ID}}" class="btn-primarno">
|
|
Izmeni nalog
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(140px, 1fr));gap:16px;">
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Datum prijema</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);">{{.Nalog.DatumPrijema.Format "02.01.2006. u 15:04"}}</div>
|
|
</div>
|
|
{{if .Nalog.DatumZavrsetka}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Datum završetka</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);">{{.Nalog.DatumZavrsetka.Format "02.01.2006."}}</div>
|
|
</div>
|
|
{{end}}
|
|
{{if .Nalog.GarancijaDo}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Garancija do</div>
|
|
<div style="font-size:14px;color:#16a34a;font-weight:500;">{{.Nalog.GarancijaDo.Format "02.01.2006."}}</div>
|
|
</div>
|
|
{{end}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Klijent</div>
|
|
<div style="font-size:14px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{if .KlijentNaziv}}{{.KlijentNaziv}}{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
{{if .TehnicarNaziv}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Tehničar</div>
|
|
<div style="font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{.TehnicarNaziv}}</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- podaci o uređaju -->
|
|
<div class="kartica detalji-kartica animiraj">
|
|
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
|
|
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Uređaj</span>
|
|
</div>
|
|
<div class="kolona" style="gap:14px;">
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));gap:16px;">
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Naziv uređaja</div>
|
|
<div style="font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{.Nalog.Uredjaj}}</div>
|
|
</div>
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Serijski broj</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);">
|
|
{{if .Nalog.SerijskiBroj}}{{.Nalog.SerijskiBroj}}{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<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>
|
|
{{if or .Nalog.Ostecenja .Nalog.PinUredjaja .Nalog.Pribor}}
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));gap:16px;">
|
|
{{if .Nalog.Ostecenja}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Oštećenja pri prijemu</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);">{{.Nalog.Ostecenja}}</div>
|
|
</div>
|
|
{{end}}
|
|
{{if .Nalog.PinUredjaja}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">PIN / lozinka uređaja</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);font-family:monospace;">{{.Nalog.PinUredjaja}}</div>
|
|
</div>
|
|
{{end}}
|
|
{{if .Nalog.Pribor}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Pribor i oprema</div>
|
|
<div style="font-size:14px;color:var(--tekst-glavni);">{{.Nalog.Pribor}}</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
{{if .Nalog.Napomena}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:6px;">Napomena</div>
|
|
<div style="font-size:13px;color:var(--tekst-sporedni);line-height:1.6;white-space:pre-wrap;">{{.Nalog.Napomena}}</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- cene -->
|
|
<div class="kartica detalji-kartica animiraj">
|
|
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
|
|
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Cene</span>
|
|
</div>
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fit, minmax(130px, 1fr));gap:16px;">
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Procena od</div>
|
|
<div style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{if .Nalog.CenaOd}}{{.Nalog.CenaOdStr}} din{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Procena do</div>
|
|
<div style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{if .Nalog.CenaDo}}{{.Nalog.CenaDoStr}} din{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Cena rada</div>
|
|
<div style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{if .Nalog.CenaKonacna}}{{.Nalog.CenaKonacnaStr}} din{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
{{if gt .UkupnoDelovi 0.0}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Ugrađeni delovi</div>
|
|
<div style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{printf "%.2f" .UkupnoDelovi}} din
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
{{if .Nalog.CenaKonacna}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Ukupno</div>
|
|
<div style="font-size:20px;font-weight:600;color:var(--sb-akcent);">
|
|
{{printf "%.2f" .UkupnoSve}} din
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Avans</div>
|
|
<div style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">
|
|
{{if .Nalog.Avans}}{{.Nalog.AvansStr}} din{{else}}—{{end}}
|
|
</div>
|
|
</div>
|
|
{{if .Nalog.CenaKonacna}}
|
|
<div>
|
|
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Za naplatu</div>
|
|
<div style="font-size:20px;font-weight:600;color:#16a34a;">
|
|
{{printf "%.2f" .PreostaloSve}} din
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ugrađeni delovi -->
|
|
<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;">
|
|
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Ugrađeni delovi</span>
|
|
</div>
|
|
|
|
<!-- forma za dodavanje dela -->
|
|
{{if index .Dozvole "servis.izmeni"}}
|
|
<form method="POST" action="/servis/{{.Nalog.ID}}/delovi" style="margin-bottom:16px;">
|
|
<input type="hidden" name="csrf_token" value="{{.CsrfToken}}">
|
|
<div style="display:grid;grid-template-columns:1fr 80px 120px auto;gap:10px;align-items:flex-end;">
|
|
<div>
|
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Artikal</label>
|
|
<select name="artikal_id" style="width:100%;" required>
|
|
<option value="">— odaberi —</option>
|
|
{{range .Artikli}}
|
|
<option value="{{.ID}}" data-cena="{{.ProdajnaCena}}">{{.Naziv}} ({{.Kolicina}} kom)</option>
|
|
{{end}}
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Kol.</label>
|
|
<input type="number" name="kolicina" min="1" value="1" style="width:100%;" required>
|
|
</div>
|
|
<div>
|
|
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Cena/kom (din)</label>
|
|
<input type="number" name="cena_komada" min="0" step="0.01" value="0" style="width:100%;" required>
|
|
</div>
|
|
<div>
|
|
<button type="submit" class="btn-primarno" style="font-size:13px;padding:8px 14px;white-space:nowrap;">+ Dodaj</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
{{end}}
|
|
|
|
<!-- lista delova -->
|
|
{{if .ServisniDelovi}}
|
|
<table class="tabela">
|
|
<thead>
|
|
<tr style="border-bottom:0.5px solid var(--ivica);">
|
|
<th style="padding:8px 10px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Artikal</th>
|
|
<th style="padding:8px 10px;text-align:center;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:80px;">Kol.</th>
|
|
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:130px;">Cena/kom</th>
|
|
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:130px;">Ukupno</th>
|
|
<th style="width:50px;"></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .ServisniDelovi}}
|
|
<tr style="border-bottom:0.5px solid var(--ivica);">
|
|
<td style="padding:9px 10px;font-size:14px;color:var(--tekst-glavni);">{{.ArtikalNaziv}}</td>
|
|
<td style="padding:9px 10px;text-align:center;font-size:14px;color:var(--tekst-glavni);">{{.Kolicina}}</td>
|
|
<td style="padding:9px 10px;text-align:right;font-size:14px;color:var(--tekst-glavni);">{{printf "%.2f" .CenaKomada}} din</td>
|
|
<td style="padding:9px 10px;text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">{{printf "%.2f" .Ukupno}} din</td>
|
|
<td style="padding:9px 10px;text-align:center;">
|
|
{{if index $.Dozvole "servis.izmeni"}}
|
|
<form method="POST" action="/servis/{{$.Nalog.ID}}/delovi/{{.ID}}/obrisi" style="display:inline;">
|
|
<input type="hidden" name="csrf_token" value="{{$.CsrfToken}}">
|
|
<button type="submit"
|
|
data-potvrda="Ukloniti deo '{{.ArtikalNaziv}}'?"
|
|
style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:16px;padding:2px 6px;border-radius:4px;">
|
|
×
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
{{else}}
|
|
<div style="font-size:13px;color:var(--tekst-sporedni);text-align:center;padding:16px 0;">
|
|
Nema ugrađenih delova za ovaj nalog.
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- zona za brisanje -->
|
|
<div class="kartica detalji-kartica animiraj" style="border-color:#dc262633;">
|
|
<div style="display:flex;align-items:flex-start;gap:12px;flex-wrap:wrap;">
|
|
<div style="flex:1;min-width:200px;">
|
|
<div style="font-size:14px;font-weight:500;color:#dc2626;margin-bottom:4px;">Brisanje naloga</div>
|
|
<div class="pomocni-tekst">
|
|
Brisanje je trajno. Nalog i svi vezani podaci biće trajno uklonjeni.
|
|
</div>
|
|
</div>
|
|
<form method="POST" action="/servis/obrisi/{{.Nalog.ID}}">
|
|
<button type="submit" class="btn-opasno"
|
|
data-potvrda="Da li ste sigurni da želite da obrišete nalog {{.Nalog.BrojNaloga}}?">
|
|
Obriši nalog
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<script>
|
|
(function() {
|
|
var sel = document.querySelector('select[name="artikal_id"]');
|
|
var cenaInput = document.querySelector('input[name="cena_komada"]');
|
|
if (!sel || !cenaInput) return;
|
|
sel.addEventListener('change', function() {
|
|
var opt = sel.options[sel.selectedIndex];
|
|
var cena = parseFloat(opt.dataset.cena);
|
|
if (!isNaN(cena) && cena > 0) {
|
|
cenaInput.value = cena.toFixed(2);
|
|
} else {
|
|
cenaInput.value = '0';
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
{{end}}
|