- PDV uslovi (Moduli.pdv) na: predračun, otpremnica, garantni list, prodaja_stampa - Modal za preuzimanje: jedna cena (sa/bez PDV), ne duplo - Javna status stranica: PDV uslovi za cene, predlog, checkbox-ove - Svi print templejti: viewport=device-width+min-width, bez responsive - JavniToken generisan za postojeće naloge bez tokena (QR popravka) - UkupnoSaPdv() metode na ServisniRad i ServisniDeoSaArtiklom - UkupnoBezPdv() na StavkaProdaje
244 lines
13 KiB
HTML
244 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="sr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Predračun — {{.Nalog.BrojNaloga}}</title>
|
|
<style>
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif; font-size: 13px; color: #111; background: #fff; min-width: 780px; }
|
|
|
|
.strana { max-width: 780px; margin: 0 auto; padding: 32px 40px; }
|
|
|
|
.zaglavlje { display: flex; align-items: stretch; margin-bottom: 18px; gap: 12px; }
|
|
.zg-okvir { flex: 1; padding: 12px 14px; border: 1.5px solid #bbb; border-radius: 12px; }
|
|
.firma-naziv { font-size: 18px; font-weight: 700; }
|
|
.firma-info { font-size: 11px; color: #555; margin-top: 3px; line-height: 1.5; }
|
|
.dok-tip { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 1px; color: #555; margin-bottom: 4px; }
|
|
.dok-broj { font-size: 18px; font-weight: 700; font-family: monospace; }
|
|
.dok-datum { font-size: 12px; color: #555; margin-top: 4px; }
|
|
|
|
.strane-blok { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 20px; }
|
|
.strana-kartica { padding: 12px 14px; border: 0.5px solid #ddd; border-radius: 6px; }
|
|
.strana-tip { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; color: #888; margin-bottom: 6px; }
|
|
.strana-naziv { font-size: 14px; font-weight: 600; }
|
|
.strana-info { font-size: 12px; color: #555; margin-top: 3px; line-height: 1.6; }
|
|
|
|
.odeljak { margin-bottom: 18px; }
|
|
.odeljak-naslov { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px; color: #555; margin-bottom: 8px; padding-bottom: 4px; border-bottom: 0.5px solid #ccc; }
|
|
.polje-tekst { font-size: 13px; line-height: 1.6; white-space: pre-wrap; }
|
|
.prazno { color: #aaa; font-style: italic; }
|
|
|
|
.tabela { width: 100%; border-collapse: collapse; margin-top: 6px; }
|
|
.tabela th { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; color: #555; padding: 6px 8px; border-bottom: 1.5px solid #111; text-align: left; }
|
|
.tabela th.desno { text-align: right; }
|
|
.tabela td { padding: 7px 8px; border-bottom: 0.5px solid #ddd; font-size: 13px; vertical-align: middle; }
|
|
.tabela td.desno { text-align: right; }
|
|
.tabela .ukupno-red td { font-weight: 600; border-top: 1.5px solid #111; border-bottom: none; background: #fafafa; }
|
|
|
|
.rekap { margin-top: 14px; margin-left: auto; width: 320px; }
|
|
.rekap-red { display: flex; justify-content: space-between; padding: 5px 0; font-size: 13px; }
|
|
.rekap-ukupno { display: flex; justify-content: space-between; align-items: center; padding: 10px 14px; border: 1.5px solid #111; border-radius: 6px; margin-top: 8px; }
|
|
.rekap-ukupno-labela { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.4px; }
|
|
.rekap-ukupno-iznos { font-size: 20px; font-weight: 700; }
|
|
|
|
.klauzula-blok { margin-top: 18px; padding: 10px 14px; background: #fffbeb; border-left: 3px solid #f59e0b; font-size: 12px; color: #92400e; line-height: 1.6; white-space: pre-wrap; }
|
|
.vazi-do { margin-top: 12px; font-size: 12px; color: #555; }
|
|
|
|
.potpisi { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; margin-top: 36px; padding-top: 16px; border-top: 0.5px solid #ccc; }
|
|
.potpis-linija { border-top: 1px solid #888; margin-top: 44px; padding-top: 6px; font-size: 11px; color: #555; text-align: center; }
|
|
|
|
@media print {
|
|
body { font-size: 12px; }
|
|
.strana { padding: 32px 40px; max-width: 780px; }
|
|
.dugme-stampa { display: none !important; }
|
|
@page { size: A4; margin: 12mm 14mm; }
|
|
.tabela tr { break-inside: avoid; }
|
|
.tabela .ukupno-red { break-before: avoid; }
|
|
.tabela .ukupno-red td { break-before: avoid; }
|
|
.tabela thead { display: table-header-group; }
|
|
.zavrsni-blok { break-inside: avoid; }
|
|
/* red tabele se ne sme prelomiti preko granice stranice */
|
|
.tabela tr { break-inside: avoid; }
|
|
/* „Ukupno radovi/delovi" se ne sme odvojiti od stavki iznad — bez preloma pre njega */
|
|
.tabela .ukupno-red { break-before: avoid; }
|
|
.tabela .ukupno-red td { break-before: avoid; }
|
|
/* zaglavlje tabele se ponavlja na svakoj stranici */
|
|
.tabela thead { display: table-header-group; }
|
|
/* od „Ukupno (procena)" do potpisa sve ostaje na jednoj strani */
|
|
.zavrsni-blok { break-inside: avoid; }
|
|
}
|
|
.dugme-stampa { position: fixed; bottom: 24px; right: 24px; background: #111; color: #fff; border: none; padding: 12px 22px; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
|
|
.dugme-stampa:hover { background: #333; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="strana">
|
|
|
|
<!-- zaglavlje -->
|
|
<div class="zaglavlje">
|
|
<!-- LEVO: firma — logo na vrhu, tekst ispod -->
|
|
<div class="zg-okvir">
|
|
{{if .LogoPutanja}}
|
|
<img src="{{.LogoPutanja}}" alt="Logo" style="max-height:54px;max-width:100%;object-fit:contain;display:block;margin-bottom:8px;">
|
|
{{else}}
|
|
<div class="firma-naziv">{{if .NazivFirme}}{{.NazivFirme}}{{else}}— naziv firme —{{end}}</div>
|
|
{{end}}
|
|
<div class="firma-info">
|
|
{{if .Podnazlov}}{{.Podnazlov}}<br>{{end}}
|
|
{{if .Adresa}}{{.Adresa}}<br>{{end}}
|
|
{{if .Telefon}}Tel: {{telefon .Telefon}}<br>{{end}}
|
|
{{if .PIB}}PIB: {{.PIB}}{{end}}{{if .MaticniBroj}}{{if .PIB}} · {{end}}MB: {{.MaticniBroj}}{{end}}
|
|
</div>
|
|
</div>
|
|
<!-- SREDINA: datumi (levo) + QR (skroz desno) -->
|
|
<div class="zg-okvir" style="flex:1.3;">
|
|
<div style="display:flex;justify-content:space-between;align-items:flex-start;gap:10px;">
|
|
<div>
|
|
<div class="dok-tip">Predračun (procena)</div>
|
|
<div class="dok-broj">{{.Nalog.BrojNaloga}}</div>
|
|
<div class="dok-datum">Datum: {{.DatumIzdavanja.Format "02.01.2006."}}</div>
|
|
<div class="dok-datum">Važi do: {{.VaziDo.Format "02.01.2006."}}</div>
|
|
</div>
|
|
{{if .QRKod}}<img src="data:image/png;base64,{{.QRKod}}" width="92" height="92" alt="QR {{.Nalog.BrojNaloga}}" style="image-rendering:pixelated;border:1px solid #ddd;border-radius:4px;flex-shrink:0;">{{end}}
|
|
</div>
|
|
</div>
|
|
<!-- DESNO: klijent -->
|
|
<div class="zg-okvir">
|
|
<div class="strana-tip">Klijent</div>
|
|
{{if .KlijentNaziv}}
|
|
<div class="strana-naziv">{{.KlijentNaziv}}</div>
|
|
<div class="strana-info">
|
|
{{if .Klijent}}
|
|
{{if .Klijent.Telefon}}Tel: {{telefon .Klijent.Telefon}}<br>{{end}}
|
|
{{if .Klijent.Email}}{{.Klijent.Email}}<br>{{end}}
|
|
{{if .Klijent.Mesto}}{{.Klijent.Mesto}}<br>{{end}}
|
|
{{if .Klijent.PIB}}PIB: {{.Klijent.PIB}}{{end}}
|
|
{{end}}
|
|
</div>
|
|
{{else}}
|
|
<div class="strana-naziv prazno">— klijent nije naveden —</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- uređaj i traženo -->
|
|
<div class="odeljak">
|
|
<div class="odeljak-naslov">Uređaj i traženi radovi</div>
|
|
<div style="margin-bottom:6px;"><strong>Uređaj:</strong> {{if .Nalog.Uredjaj}}{{.Nalog.Uredjaj}}{{else}}<span class="prazno">—</span>{{end}}{{if .Nalog.SerijskiBroj}} · S/N: {{.Nalog.SerijskiBroj}}{{end}}</div>
|
|
<div class="polje-tekst"><strong>Zahtev klijenta:</strong> {{if .Nalog.OpisKvara}}{{.Nalog.OpisKvara}}{{else}}<span class="prazno">—</span>{{end}}</div>
|
|
{{if .Nalog.TrazeneNadogradnje}}
|
|
<div class="polje-tekst" style="margin-top:6px;"><strong>Tražene nadogradnje:</strong> {{.Nalog.TrazeneNadogradnje}}</div>
|
|
{{end}}
|
|
{{if .Nalog.NapomenaKlijentu}}
|
|
<div class="polje-tekst" style="margin-top:6px;"><strong>Napomena klijentu:</strong> {{.Nalog.NapomenaKlijentu}}</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
<!-- utvrđen kvar (rezultat dijagnostike) -->
|
|
{{if .Nalog.NalazDijagnostike}}
|
|
<div class="odeljak">
|
|
<div class="odeljak-naslov">Utvrđen kvar</div>
|
|
<div class="polje-tekst">{{.Nalog.NalazDijagnostike}}</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- radovi -->
|
|
{{if .Radovi}}
|
|
<div class="odeljak">
|
|
<div class="odeljak-naslov">Radovi</div>
|
|
<table class="tabela">
|
|
<thead>
|
|
<tr>
|
|
<th>Usluga</th>
|
|
<th class="desno" style="width:70px;">Kol.</th>
|
|
<th class="desno" style="width:120px;">Cena{{if index .Moduli "pdv"}} sa PDV{{end}}</th>
|
|
<th class="desno" style="width:120px;">Ukupno{{if index .Moduli "pdv"}} sa PDV{{end}}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .Radovi}}
|
|
<tr>
|
|
<td>{{.Naziv}}</td>
|
|
<td class="desno">{{.Kolicina}}</td>
|
|
<td class="desno">{{if index $.Moduli "pdv"}}{{dinari .CenaSaPdv}}{{else}}{{dinari .CenaKomada}}{{end}} din</td>
|
|
<td class="desno">{{if index $.Moduli "pdv"}}{{dinari .UkupnoSaPdv}}{{else}}{{dinari .Ukupno}}{{end}} din</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- delovi -->
|
|
{{if .ServisniDelovi}}
|
|
<div class="odeljak">
|
|
<div class="odeljak-naslov">Delovi i materijal</div>
|
|
<table class="tabela">
|
|
<thead>
|
|
<tr>
|
|
<th>Artikal</th>
|
|
<th class="desno" style="width:70px;">Kol.</th>
|
|
<th class="desno" style="width:120px;">Cena/kom{{if index .Moduli "pdv"}} sa PDV{{end}}</th>
|
|
<th class="desno" style="width:120px;">Ukupno{{if index .Moduli "pdv"}} sa PDV{{end}}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{{range .ServisniDelovi}}
|
|
<tr>
|
|
<td>{{.ArtikalNaziv}}</td>
|
|
<td class="desno">{{.Kolicina}}</td>
|
|
<td class="desno">{{if index $.Moduli "pdv"}}{{dinari .CenaSaPdv}}{{else}}{{dinari .CenaKomada}}{{end}} din</td>
|
|
<td class="desno">{{if index $.Moduli "pdv"}}{{dinari .UkupnoSaPdv}}{{else}}{{dinari .Ukupno}}{{end}} din</td>
|
|
</tr>
|
|
{{end}}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{if and (not .Radovi) (not .ServisniDelovi)}}
|
|
<div class="odeljak">
|
|
<div class="polje-tekst prazno">Na nalog još nisu uneti radovi ni delovi — dodaj ih u detaljima naloga da bi se prikazali na predračunu.</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
<!-- završni blok: od rekapitulacije do potpisa — pri štampi ostaje u jednom komadu -->
|
|
<div class="zavrsni-blok">
|
|
|
|
<!-- rekapitulacija: ponavlja sume po sekciji (korisno kad tabele pređu na prethodnu stranu) -->
|
|
<div class="rekap">
|
|
{{if .Radovi}}<div class="rekap-red" style="font-weight:600;"><span>Ukupno radovi</span><span>{{if index .Moduli "pdv"}}{{dinari .UkupnoRadSaPdv}}{{else}}{{dinari .UkupnoRad}}{{end}} din</span></div>{{end}}
|
|
{{if .ServisniDelovi}}<div class="rekap-red" style="font-weight:600;"><span>Ukupno delovi</span><span>{{if index .Moduli "pdv"}}{{dinari .UkupnoDeloviSaPdv}}{{else}}{{dinari .UkupnoDelovi}}{{end}} din</span></div>{{end}}
|
|
<div class="rekap-ukupno">
|
|
<div class="rekap-ukupno-labela">Ukupno (procena):</div>
|
|
<div class="rekap-ukupno-iznos">{{if index .Moduli "pdv"}}{{dinari .UkupnoSveSaPdv}}{{else}}{{dinari .UkupnoSve}}{{end}} din</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- klauzula -->
|
|
{{if .Klauzula}}
|
|
<div class="klauzula-blok">{{.Klauzula}}</div>
|
|
{{end}}
|
|
|
|
<div class="vazi-do">Predračun važi do <strong>{{.VaziDo.Format "02.01.2006."}}</strong>.</div>
|
|
|
|
<!-- potpisi -->
|
|
<div class="potpisi">
|
|
<div>
|
|
<div class="potpis-linija">Saglasan sa procenom (klijent)</div>
|
|
</div>
|
|
<div>
|
|
<div class="potpis-linija">Izdao{{if .TehnicarNaziv}} — {{.TehnicarNaziv}}{{end}} (servis)</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div><!-- /zavrsni-blok -->
|
|
|
|
</div>
|
|
|
|
<button class="dugme-stampa" onclick="window.print()">Štampaj</button>
|
|
|
|
</body>
|
|
</html>
|