Files
GoNtech/web/templates/stranice/nabavka_forma.html
T
Dasko 100915d453 feat(nabavka): dvosmerna marža↔prodajna + poštovanje statusa PDV obveznika
- ručni unos prodajne cene preračunava maržu (izracunajMarzu): obrnuta formula
  marža = (prodajna / (nabavna × (1+pdv/100)) − 1) × 100
- kalkulacija poštuje da li je firma PDV obveznik: ako nije, prodajna se ne
  uvećava za PDV (pdvStopa = 0); PodaciFormeNabavke.PdvObveznik → JS _ntechPdvObveznik
- proširena kolona „Marža %" da se vidi cela vrednost
2026-06-14 17:16:24 +02:00

425 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{template "base" .}}
{{define "naslov"}}Nova nabavka — NTech{{end}}
{{define "dodatni-css"}}
<style>
@keyframes modalIn { from { opacity: 0; transform: translateY(-16px) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }
.forma-kartica:nth-child(1) { animation-delay: 0.04s; }
.forma-kartica:nth-child(2) { animation-delay: 0.12s; }
.modal-sadrzaj { animation: modalIn 0.25s ease forwards; }
/* centriranje preko klase (ne inline) — x-show menja inline display, pa bi obrisao flex i modal bi pao u ćošak */
.modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 50; display: flex; align-items: center; justify-content: center; padding: 16px; }
</style>
{{end}}
{{define "sadrzaj"}}
<!-- lista artikala kao JSON — bezbedno serijalizovana na serveru -->
<script>var _ntechArtikli = {{.ArtikliJSON}}; var _ntechMarza = {{.Marza}}; var _ntechPdvObveznik = {{.PdvObveznik}};</script>
<div style="width:100%;" x-data="nabavkaForma">
<!-- nazad dugme -->
<a href="/nabavke" 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 nabavke
</a>
<form method="POST" action="/nabavke/nova">
{{if .Greska}}
<div class="poruka-greska greska-animacija">{{.Greska}}</div>
{{end}}
<!-- zaglavlje nabavke -->
<div class="kartica forma-kartica animiraj" style="margin-bottom:16px;">
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
<span style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">Nova nabavka</span>
</div>
<div class="kolona" style="gap:14px;">
<div>
<div style="display:flex;justify-content:space-between;align-items:center;">
<label class="polje-labela">Dobavljač</label>
<button type="button" @click="otvoriModalDobavljac()"
style="padding:6px 14px;background:var(--kartica);color:var(--tekst-sporedni);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;cursor:pointer;margin-bottom:6px;transition:background 0.2s;"
onmouseover="this.style.background='var(--pozadina)'" onmouseout="this.style.background='var(--kartica)'">
+ Novi dobavljač
</button>
</div>
<select name="dobavljac_id" x-ref="selDobavljac" style="width:100%;">
<option value="">— bez dobavljača —</option>
{{range .Dobavljaci}}
<option value="{{.ID}}">{{.Naziv}}</option>
{{end}}
</select>
</div>
<div>
<label class="polje-labela">Napomena</label>
<textarea name="napomena" rows="2"
placeholder="Interna napomena o nabavci..."
style="width:100%;resize:vertical;"></textarea>
</div>
</div>
</div>
<!-- stavke -->
<div class="kartica forma-kartica animiraj" style="margin-bottom:16px;">
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
<span style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">Stavke</span>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button type="button" @click="otvoriModal()"
style="padding:6px 14px;background:var(--kartica);color:var(--tekst-sporedni);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;cursor:pointer;transition:background 0.2s;"
onmouseover="this.style.background='var(--pozadina)'" onmouseout="this.style.background='var(--kartica)'">
+ Novi artikal
</button>
<button type="button" @click="dodajStavku()" class="btn-primarno" style="font-size:13px;padding:6px 14px;">
+ Dodaj stavku
</button>
</div>
</div>
<!-- desktop tabela stavki -->
<div class="stavke-tabela-wrapper" style="overflow-x:auto;">
<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:90px;">Količina</th>
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:130px;">Cena/kom (din)</th>
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:120px;">Marža %</th>
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:130px;">Prodajna/kom (din)</th>
<th style="padding:8px 10px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);width:110px;">Ukupno</th>
<th style="width:40px;"></th>
</tr>
</thead>
<tbody>
<template x-for="(stavka, i) in stavke" :key="i">
<tr style="border-bottom:0.5px solid var(--ivica);">
<td style="padding:8px 10px;">
<select :name="'artikal_id[]'" x-model="stavka.artikal_id"
@change="izaberiArtikal(stavka)" :disabled="isMobile" style="width:100%;">
<option value="">— odaberi artikal —</option>
<template x-for="a in artikliOpcije" :key="a.id">
<option :value="a.id" x-text="a.naziv"></option>
</template>
</select>
</td>
<td style="padding:8px 10px;">
<input type="number" :name="'kolicina[]'" x-model="stavka.kolicina"
@input="preracunajSve()"
min="1" :disabled="isMobile" style="width:100%;text-align:center;">
</td>
<td style="padding:8px 10px;">
<input type="number" :name="'cena_po_komadu[]'" x-model="stavka.cena"
@input="preracunajSve()"
min="0" step="0.01" :disabled="isMobile" style="width:100%;text-align:right;">
</td>
<td style="padding:8px 10px;">
<input type="number" :name="'marza[]'" x-model="stavka.marza"
@input="izracunajProdajnu(stavka)"
min="0" step="0.01" :disabled="isMobile" style="width:100%;text-align:right;">
</td>
<td style="padding:8px 10px;">
<input type="number" :name="'prodajna[]'" x-model="stavka.prodajna"
@input="izracunajMarzu(stavka)"
min="0" step="0.01" :disabled="isMobile" style="width:100%;text-align:right;">
</td>
<td style="padding:8px 10px;text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">
<span x-text="ukupnoStavke(stavka) + ' din'"></span>
</td>
<td style="padding:8px 10px;text-align:center;">
<button type="button" @click="ukloniStavku(i)"
x-show="stavke.length > 1"
style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:18px;line-height:1;padding:2px 6px;border-radius:4px;transition:background 0.15s;"
onmouseover="this.style.background='rgba(220,38,38,0.08)'"
onmouseout="this.style.background='none'"
title="Ukloni stavku">×</button>
</td>
</tr>
</template>
</tbody>
<tfoot>
<tr style="border-top:0.5px solid var(--ivica);">
<td colspan="5" style="padding:10px 10px;text-align:right;font-size:13px;color:var(--tekst-sporedni);font-weight:500;">Ukupno:</td>
<td style="padding:10px 10px;text-align:right;font-size:15px;font-weight:600;color:var(--tekst-glavni);">
<span x-text="ukupnoSvega() + ' din'"></span>
</td>
<td></td>
</tr>
</tfoot>
</table>
</div>
<!-- mobilne kartice stavki -->
<div class="stavke-kartice" style="display:none;flex-direction:column;gap:10px;">
<template x-for="(stavka, i) in stavke" :key="i">
<div style="border:0.5px solid var(--ivica);border-radius:8px;padding:12px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
<span style="font-size:13px;font-weight:500;color:var(--tekst-sporedni);"
x-text="'Stavka ' + (i + 1)"></span>
<button type="button" @click="ukloniStavku(i)"
x-show="stavke.length > 1"
style="background:none;border:0.5px solid #dc2626;color:#dc2626;cursor:pointer;font-size:13px;padding:2px 8px;border-radius:4px;">
Ukloni
</button>
</div>
<div class="kolona" style="gap:10px;">
<div>
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Artikal</label>
<select :name="'artikal_id[]'" x-model="stavka.artikal_id"
@change="izaberiArtikal(stavka)" :disabled="!isMobile" style="width:100%;">
<option value="">— odaberi artikal —</option>
<template x-for="a in artikliOpcije" :key="a.id">
<option :value="a.id" x-text="a.naziv"></option>
</template>
</select>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<div>
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Količina</label>
<input type="number" :name="'kolicina[]'" x-model="stavka.kolicina" @input="preracunajSve()" min="1" :disabled="!isMobile" style="width:100%;">
</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_po_komadu[]'" x-model="stavka.cena" @input="preracunajSve()" min="0" step="0.01" :disabled="!isMobile" style="width:100%;">
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;">
<div>
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Marža %</label>
<input type="number" :name="'marza[]'" x-model="stavka.marza" @input="izracunajProdajnu(stavka)" min="0" step="0.01" :disabled="!isMobile" style="width:100%;">
</div>
<div>
<label style="font-size:12px;color:var(--tekst-sporedni);display:block;margin-bottom:4px;">Prodajna/kom (din)</label>
<input type="number" :name="'prodajna[]'" x-model="stavka.prodajna" @input="izracunajMarzu(stavka)" min="0" step="0.01" :disabled="!isMobile" style="width:100%;">
</div>
</div>
<div style="text-align:right;font-size:14px;font-weight:500;color:var(--tekst-glavni);">
Ukupno: <span x-text="ukupnoStavke(stavka) + ' din'"></span>
</div>
</div>
</div>
</template>
<div style="text-align:right;font-size:15px;font-weight:600;color:var(--tekst-glavni);padding:8px 4px;">
Ukupno: <span x-text="ukupnoSvega() + ' din'"></span>
</div>
</div>
</div>
<!-- zavisni troškovi -->
<div class="kartica forma-kartica animiraj" style="margin-bottom:16px;">
<div style="margin-bottom:16px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:8px;">
<span style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">Zavisni troškovi</span>
<button type="button" @click="dodajTrosak()" class="btn-primarno" style="font-size:13px;padding:6px 14px;">
+ Dodaj trošak
</button>
</div>
<template x-if="troskovi.length > 0">
<div class="kolona" style="gap:10px;">
<!-- metod raspodele -->
<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
<label class="polje-labela" style="margin:0;">Raspodela na stavke:</label>
<select name="metod_raspodele" x-model="metodRaspodele" @change="preracunajSve()" style="max-width:240px;">
<option value="vrednost">po vrednosti stavke</option>
<option value="kolicina">po količini</option>
</select>
</div>
<!-- redovi troškova -->
<template x-for="(t, i) in troskovi" :key="i">
<div style="display:flex;gap:8px;align-items:center;">
<input type="text" :name="'trosak_naziv[]'" x-model="t.naziv"
placeholder="npr. Prevoz, Carina, Špedicija" style="flex:1;">
<input type="number" :name="'trosak_iznos[]'" x-model="t.iznos"
@input="preracunajSve()" min="0" step="0.01"
placeholder="iznos (din)" style="width:140px;text-align:right;">
<button type="button" @click="ukloniTrosak(i)"
style="background:none;border:none;cursor:pointer;color:#dc2626;font-size:18px;line-height:1;padding:2px 6px;border-radius:4px;"
title="Ukloni trošak">×</button>
</div>
</template>
<div style="text-align:right;font-size:13px;color:var(--tekst-sporedni);">
Ukupno troškovi: <strong x-text="ukupanTrosak().toFixed(2) + ' din'"></strong>
</div>
</div>
</template>
<template x-if="troskovi.length === 0">
<div style="font-size:13px;color:var(--tekst-sporedni);">
Nema zavisnih troškova. Dodaj trošak (prevoz, carina…) — raspodeliće se na stavke i ući u kalkulativnu nabavnu cenu.
</div>
</template>
</div>
<!-- dugmad forme -->
<div style="display:flex;justify-content:flex-end;gap:10px;">
<a href="/nabavke" class="btn-sekundarno">Odustani</a>
<button type="submit" class="btn-primarno">Sačuvaj nabavku</button>
</div>
</form>
<!-- modal: novi artikal -->
<div x-show="modal" x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
class="modal-overlay"
@click.self="zatvoriModal()" @keydown.escape.window="zatvoriModal()">
<div class="kartica modal-sadrzaj" style="width:100%;max-width:480px;padding:24px;max-height:90vh;overflow-y:auto;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
<span style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">Novi artikal</span>
<button type="button" @click="zatvoriModal()" aria-label="Zatvori"
style="background:none;border:none;cursor:pointer;color:var(--tekst-sporedni);font-size:20px;line-height:1;padding:2px 6px;border-radius:4px;transition:background 0.15s;">×</button>
</div>
<div x-show="modalGreska" class="poruka-greska greska-animacija" x-text="modalGreska"></div>
<div class="kolona" style="gap:14px;">
<div>
<label class="polje-labela">
Naziv <span style="color:#dc2626;">*</span>
</label>
<input type="text" x-model="modalNaziv" x-ref="modalNazivInput"
placeholder="npr. RAM DDR4 8GB Kingston"
style="width:100%;"
@keydown.enter.prevent="sacuvajArtikal()">
</div>
<div>
<label class="polje-labela">Kategorija</label>
<select x-model="modalKategorijaID" style="width:100%;">
<option value="">— bez kategorije —</option>
{{range .Kategorije}}
<option value="{{.ID}}">{{.Naziv}}</option>
{{end}}
</select>
</div>
<div>
<label class="polje-labela">Opis</label>
<textarea x-model="modalOpis" rows="2"
placeholder="Kratak opis artikla..."
style="width:100%;resize:vertical;"></textarea>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div>
<label class="polje-labela">Količina na stanju</label>
<input type="number" x-model="modalKolicina" min="0" placeholder="0" style="width:100%;">
</div>
<div>
<label class="polje-labela">Minimalna količina</label>
<input type="number" x-model="modalKolicinaMin" min="0" placeholder="0" style="width:100%;">
</div>
</div>
<div>
<label class="polje-labela">Prodajna cena (din)</label>
<input type="number" x-model="modalCena" min="0" step="0.01"
placeholder="0"
style="width:100%;">
</div>
<div>
<label class="polje-labela">Lokacija u magacinu</label>
<input type="text" x-model="modalLokacija"
placeholder="npr. Regal A3, polica 2"
style="width:100%;">
</div>
<div>
<label class="polje-labela">Napomena</label>
<textarea x-model="modalNapomena" rows="2"
placeholder="Interna napomena o artiklu..."
style="width:100%;resize:vertical;"></textarea>
</div>
</div>
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px;padding-top:14px;border-top:0.5px solid var(--ivica);">
<button type="button" @click="zatvoriModal()" class="btn-sekundarno">Odustani</button>
<button type="button" @click="sacuvajArtikal()" :disabled="modalUcitavanje" class="btn-primarno"
:style="modalUcitavanje ? 'opacity:0.6;cursor:not-allowed' : ''">
<span x-text="modalUcitavanje ? 'Čuvanje...' : 'Dodaj artikal'"></span>
</button>
</div>
</div>
</div>
<!-- modal: novi dobavljač -->
<div x-show="modalDob" x-transition:enter="transition ease-out duration-200"
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
x-transition:leave="transition ease-in duration-150"
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
class="modal-overlay"
@click.self="zatvoriModalDobavljac()" @keydown.escape.window="zatvoriModalDobavljac()">
<div class="kartica modal-sadrzaj" style="width:100%;max-width:480px;padding:24px;max-height:90vh;overflow-y:auto;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;padding-bottom:14px;border-bottom:0.5px solid var(--ivica);">
<span style="font-size:16px;font-weight:500;color:var(--tekst-glavni);">Novi dobavljač</span>
<button type="button" @click="zatvoriModalDobavljac()" aria-label="Zatvori"
style="background:none;border:none;cursor:pointer;color:var(--tekst-sporedni);font-size:20px;line-height:1;padding:2px 6px;border-radius:4px;transition:background 0.15s;">×</button>
</div>
<div x-show="modalDobGreska" class="poruka-greska greska-animacija" x-text="modalDobGreska"></div>
<div class="kolona" style="gap:14px;">
<div>
<label class="polje-labela">Naziv <span style="color:#dc2626;">*</span></label>
<input type="text" x-model="modalDobNaziv" x-ref="modalDobNazivInput"
placeholder="npr. TechDistrib d.o.o." style="width:100%;"
@keydown.enter.prevent="sacuvajDobavljaca()">
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div>
<label class="polje-labela">Kontakt osoba</label>
<input type="text" x-model="modalDobKontakt" placeholder="npr. Marko Petrović" style="width:100%;">
</div>
<div>
<label class="polje-labela">Telefon</label>
<input type="text" x-model="modalDobTelefon" placeholder="npr. 011 123 4567" style="width:100%;">
</div>
</div>
<div>
<label class="polje-labela">E-pošta</label>
<input type="text" x-model="modalDobEmail" placeholder="npr. nabavka@techdistrib.rs" style="width:100%;">
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
<div>
<label class="polje-labela">PIB</label>
<input type="text" x-model="modalDobPib" placeholder="npr. 123456789" style="width:100%;">
</div>
<div>
<label class="polje-labela">Mesto / grad</label>
<input type="text" x-model="modalDobMesto" placeholder="npr. Beograd" style="width:100%;">
</div>
</div>
<div>
<label class="polje-labela">Napomena</label>
<textarea x-model="modalDobNapomena" rows="2"
placeholder="Interna napomena o dobavljaču..."
style="width:100%;resize:vertical;"></textarea>
</div>
</div>
<div style="display:flex;justify-content:flex-end;gap:10px;margin-top:20px;padding-top:14px;border-top:0.5px solid var(--ivica);">
<button type="button" @click="zatvoriModalDobavljac()" class="btn-sekundarno">Odustani</button>
<button type="button" @click="sacuvajDobavljaca()" :disabled="modalDobUcitavanje" class="btn-primarno"
:style="modalDobUcitavanje ? 'opacity:0.6;cursor:not-allowed' : ''">
<span x-text="modalDobUcitavanje ? 'Čuvanje...' : 'Dodaj dobavljača'"></span>
</button>
</div>
</div>
</div>
</div>
{{end}}