Nabavka: broj računa, datum računa, PDV iznos + KPR backfill za stare nabavke
This commit is contained in:
@@ -320,6 +320,7 @@ document.addEventListener('alpine:init', () => {
|
||||
stavke: [{artikal_id: '', kolicina: 1, cena: 0, marza: 0, prodajna: 0}],
|
||||
artikliOpcije: [],
|
||||
dobavljacId: '', // izabrani dobavljač nabavke — filtrira listu artikala
|
||||
brojRacuna: '', // broj računa dobavljača — obavezan za PDV KPR
|
||||
prikaziSveArtikle: false, // true = prikaži sve artikle, ne samo dobavljačeve
|
||||
marzaDefault: 0,
|
||||
troskovi: [], // zavisni troškovi {naziv, iznos}
|
||||
@@ -357,6 +358,21 @@ document.addEventListener('alpine:init', () => {
|
||||
window.matchMedia('(max-width: 768px)').addEventListener('change', e => {
|
||||
this.isMobile = e.matches
|
||||
})
|
||||
const resetujNedostupne = () => {
|
||||
if (this.prikaziSveArtikle) return
|
||||
const dostupni = new Set(this.artikliZaDobavljaca().map(a => String(a.id)))
|
||||
this.stavke.forEach(s => {
|
||||
if (s.artikal_id && !dostupni.has(String(s.artikal_id))) {
|
||||
s.artikal_id = ''
|
||||
s.cena = 0
|
||||
s.marza = this.marzaDefault
|
||||
s.prodajna = 0
|
||||
}
|
||||
})
|
||||
this.preracunajSve()
|
||||
}
|
||||
this.$watch('dobavljacId', resetujNedostupne)
|
||||
this.$watch('prikaziSveArtikle', resetujNedostupne)
|
||||
},
|
||||
dodajStavku() {
|
||||
// ne dozvoli novu stavku dok poslednja nema izabran artikal
|
||||
@@ -389,6 +405,10 @@ document.addEventListener('alpine:init', () => {
|
||||
if (a.marza != null) s.marza = a.marza
|
||||
else if (a.kategorija_marza != null) s.marza = a.kategorija_marza
|
||||
else s.marza = this.marzaDefault
|
||||
} else {
|
||||
s.cena = 0
|
||||
s.marza = this.marzaDefault
|
||||
s.prodajna = 0
|
||||
}
|
||||
this.izracunajProdajnu(s)
|
||||
this.preracunajSve()
|
||||
@@ -437,6 +457,11 @@ document.addEventListener('alpine:init', () => {
|
||||
this.stavke.forEach(s => this.izracunajProdajnu(s))
|
||||
},
|
||||
dodajTrosak() {
|
||||
const poslednji = this.troskovi[this.troskovi.length - 1]
|
||||
if (poslednji && !poslednji.naziv.trim()) {
|
||||
if (window.ntechToast) window.ntechToast('Prvo unesi naziv poslednjeg troška.', 'greska')
|
||||
return
|
||||
}
|
||||
this.troskovi.push({naziv: '', iznos: 0})
|
||||
},
|
||||
ukloniTrosak(i) {
|
||||
@@ -571,6 +596,7 @@ document.addEventListener('alpine:init', () => {
|
||||
opcija.textContent = novi.naziv
|
||||
this.$refs.selDobavljac.appendChild(opcija)
|
||||
this.$refs.selDobavljac.value = novi.id
|
||||
this.dobavljacId = String(novi.id)
|
||||
this.zatvoriModalDobavljac()
|
||||
} catch {
|
||||
this.modalDobGreska = 'Greška pri komunikaciji sa serverom.'
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
{{if .Sacuvano}}
|
||||
<div class="poruka-uspeh poruka-animacija">Nabavka je uspešno sačuvana.</div>
|
||||
{{end}}
|
||||
{{if .Greska}}
|
||||
<div class="poruka-greska greska-animacija">{{.Greska}}</div>
|
||||
{{end}}
|
||||
|
||||
<!-- nazad dugme -->
|
||||
<a href="/nabavke" class="nazad-link" hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML">
|
||||
@@ -45,6 +48,18 @@
|
||||
{{if .DobavljacNaziv}}{{.DobavljacNaziv}}{{else}}—{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Broj računa</div>
|
||||
<div style="font-size:14px;color:var(--tekst-glavni);">
|
||||
{{if .Nabavka.BrojRacuna}}{{.Nabavka.BrojRacuna}}{{else}}—{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Datum računa</div>
|
||||
<div style="font-size:14px;color:var(--tekst-glavni);">
|
||||
{{if .Nabavka.DatumRacuna}}{{.Nabavka.DatumRacuna.Format "02.01.2006."}}{{else}}—{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style="font-size:12px;color:var(--tekst-sporedni);margin-bottom:4px;">Napomena</div>
|
||||
<div style="font-size:14px;color:var(--tekst-glavni);">
|
||||
@@ -173,7 +188,7 @@
|
||||
Storno vraća količine artikala na stanje u magacinu. Nabavka ostaje u evidenciji sa oznakom stornirana. Nabavna cena se ne menja.
|
||||
</div>
|
||||
</div>
|
||||
<form method="POST" action="/nabavke/storno/{{.Nabavka.ID}}" style="display:flex;flex-direction:column;gap:8px;align-items:flex-end;">
|
||||
<form method="POST" action="/nabavke/storno/{{.Nabavka.ID}}" data-full-reload style="display:flex;flex-direction:column;gap:8px;align-items:flex-end;">
|
||||
<input type="hidden" name="csrf_token" value="{{.CsrfToken}}">
|
||||
<input type="text" name="razlog" placeholder="Razlog storniranja (opciono)" style="width:240px;">
|
||||
<button type="submit" class="btn-upozorenje"
|
||||
|
||||
@@ -60,7 +60,33 @@
|
||||
<div x-show="dobavljacId && prikaziSveArtikle" class="pomocni-tekst" style="margin-top:4px;">
|
||||
Napomena: izabrani artikal koji nije od ovog dobavljača biće mu dodat pri čuvanju nabavke.
|
||||
</div>
|
||||
{{if .PdvObveznik}}
|
||||
<div x-show="!dobavljacId" style="display:flex;align-items:center;gap:6px;margin-top:8px;padding:8px 10px;background:rgba(234,179,8,0.1);border:0.5px solid rgba(234,179,8,0.4);border-radius:8px;font-size:12px;color:#ca8a04;">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
||||
Bez dobavljača KPR zapis neće imati PIB — što nije ispravno za PDV evidenciju.
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;">
|
||||
<div>
|
||||
<label class="polje-labela">Broj računa dobavljača{{if .PdvObveznik}} <span style="color:#dc2626;">*</span>{{end}}</label>
|
||||
<input type="text" name="broj_racuna" x-model="brojRacuna" placeholder="npr. 2024/00123"
|
||||
style="width:100%;">
|
||||
</div>
|
||||
<div>
|
||||
<label class="polje-labela">Datum računa</label>
|
||||
<input type="date" name="datum_racuna" value="{{.Danas}}" style="width:100%;">
|
||||
</div>
|
||||
</div>
|
||||
{{if .PdvObveznik}}
|
||||
<div>
|
||||
<label class="polje-labela">PDV sa računa dobavljača (din)</label>
|
||||
<input type="number" name="pdv_iznos" min="0" step="0.01"
|
||||
placeholder="Ostavite prazno za automatski obračun iz stope"
|
||||
style="width:100%;">
|
||||
<div class="pomocni-tekst" style="margin-top:4px;">Ako unesete iznos, koristiće se umesto aproksimacije iz stope artikla u KPR.</div>
|
||||
</div>
|
||||
{{end}}
|
||||
<div>
|
||||
<label class="polje-labela">Napomena</label>
|
||||
<textarea name="napomena" rows="2"
|
||||
@@ -265,7 +291,12 @@
|
||||
<!-- dugmad forme -->
|
||||
<div style="display:flex;justify-content:flex-end;gap:10px;">
|
||||
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/nabavke" class="btn-sekundarno">Odustani</a>
|
||||
<button type="submit" class="btn-primarno">Sačuvaj nabavku</button>
|
||||
<button type="submit" class="btn-primarno"
|
||||
:disabled="pdvObveznik && (!dobavljacId || !brojRacuna.trim())"
|
||||
@click="if(pdvObveznik && !dobavljacId){ $event.preventDefault(); window.ntechToast('Izaberi dobavljača — PDV evidencija zahteva PIB.', 'greska'); }
|
||||
else if(pdvObveznik && !brojRacuna.trim()){ $event.preventDefault(); window.ntechToast('Unesi broj računa dobavljača — obavezan je za KPR.', 'greska'); }">
|
||||
Sačuvaj nabavku
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
@@ -20,7 +20,18 @@
|
||||
<button type="submit" style="padding:8px 16px;background:var(--sb-aktivan);color:var(--tekst-jak);border:0.5px solid var(--ivica);border-radius:8px;font-size:13px;cursor:pointer;">Prikaži</button>
|
||||
{{if or .Od .Do}}<a href="/pdv/kpr" class="nazad-link" hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" style="margin-bottom:0;">Poništi filter</a>{{end}}
|
||||
</form>
|
||||
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/pdv/kpr/nova" class="btn-primarno" style="font-size:13px;padding:8px 16px;white-space:nowrap;">+ Nov ulazni račun</a>
|
||||
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
|
||||
{{if index .Dozvole "pdv.dodaj"}}
|
||||
<form method="POST" action="/pdv/kpr/backfill-nabavke" data-full-reload>
|
||||
<input type="hidden" name="csrf_token" value="{{.CsrfToken}}">
|
||||
<button type="submit" class="btn-sekundarno" style="font-size:13px;padding:8px 16px;white-space:nowrap;"
|
||||
data-potvrda="Uvesti sve nabavke koje još nisu u KPR-u?">
|
||||
Uvezi iz nabavki
|
||||
</button>
|
||||
</form>
|
||||
{{end}}
|
||||
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/pdv/kpr/nova" class="btn-primarno" style="font-size:13px;padding:8px 16px;white-space:nowrap;">+ Nov ulazni račun</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user