Izveštaji: prometni list magacina i stanje zaliha
- Prometni list: sve promene magacina po periodu (filter od/do datuma), bojama označeni tipovi promena (ulaz/prodaja/servis/povraćaj/korekcija) - Stanje zaliha: svi artikli sa stanjem, min. količinom, cenama i ukupnom vrednošću zalihe; kritične zalihe istaknute crvenom bojom - Brzi linkovi na oba izveštaja sa glavne stranice izveštaja
This commit is contained in:
@@ -342,6 +342,8 @@ func main() {
|
|||||||
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.Get("/izvestaji", h.Izvestaji)
|
r.Get("/izvestaji", h.Izvestaji)
|
||||||
|
r.Get("/izvestaji/prometni-list", h.PrometniListMagacina)
|
||||||
|
r.Get("/izvestaji/stanje-zaliha", h.StanjeZalihaIzvestaj)
|
||||||
r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "prodaja.pregled")).Get("/prodaja", h.Prodaja)
|
r.With(ntechmw.RequireDozvola(h.DozvoleRepo.ImaDozvolu, "prodaja.pregled")).Get("/prodaja", h.Prodaja)
|
||||||
r.Get("/prodaja/nova", h.NovaProdaja)
|
r.Get("/prodaja/nova", h.NovaProdaja)
|
||||||
r.With(doz("prodaja.dodaj")).Post("/prodaja/nova", h.SacuvajProdaju)
|
r.With(doz("prodaja.dodaj")).Post("/prodaja/nova", h.SacuvajProdaju)
|
||||||
|
|||||||
@@ -222,6 +222,9 @@ type IzvestajRepository interface {
|
|||||||
StariOtvoreniNalozi(ctx context.Context) ([]model.StariNalogRed, error)
|
StariOtvoreniNalozi(ctx context.Context) ([]model.StariNalogRed, error)
|
||||||
TopArtikli(ctx context.Context, limit int) ([]model.TopArtikalRed, error)
|
TopArtikli(ctx context.Context, limit int) ([]model.TopArtikalRed, error)
|
||||||
TopKlijenti(ctx context.Context, limit int) ([]model.TopKlijentRed, error)
|
TopKlijenti(ctx context.Context, limit int) ([]model.TopKlijentRed, error)
|
||||||
|
// magacinski izveštaji
|
||||||
|
PrometniList(ctx context.Context, od, do time.Time) ([]model.PrometniRed, error)
|
||||||
|
StanjeZaliha(ctx context.Context) ([]model.StanjeZalihaRed, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodsetnikRepository definiše operacije nad podsetnicima
|
// PodsetnikRepository definiše operacije nad podsetnicima
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"ntech/internal/model"
|
"ntech/internal/model"
|
||||||
)
|
)
|
||||||
@@ -232,3 +233,59 @@ func (r *sqliteIzvestajRepo) TopKlijenti(ctx context.Context, limit int) ([]mode
|
|||||||
}
|
}
|
||||||
return lista, rows.Err()
|
return lista, rows.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrometniList vraća sve magacinske promene u zadatom periodu
|
||||||
|
func (r *sqliteIzvestajRepo) PrometniList(ctx context.Context, od, do time.Time) ([]model.PrometniRed, error) {
|
||||||
|
rows, err := r.db.QueryContext(ctx, `
|
||||||
|
SELECT mp.datum, a.naziv, COALESCE(a.sifra, ''), mp.tip_promene,
|
||||||
|
mp.promena_kolicine, mp.stanje_pre, mp.stanje_posle,
|
||||||
|
COALESCE(mp.napomena, '')
|
||||||
|
FROM magacinske_promene mp
|
||||||
|
JOIN artikli a ON a.id = mp.artikal_id
|
||||||
|
WHERE DATE(mp.datum) >= DATE(?) AND DATE(mp.datum) <= DATE(?)
|
||||||
|
ORDER BY mp.datum ASC`,
|
||||||
|
od.Format("2006-01-02"), do.Format("2006-01-02"),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ntech: IzvestajRepo.PrometniList: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var lista []model.PrometniRed
|
||||||
|
for rows.Next() {
|
||||||
|
var p model.PrometniRed
|
||||||
|
if err := rows.Scan(&p.Datum, &p.ArtikalNaziv, &p.ArtikalSifra, &p.TipPromene,
|
||||||
|
&p.PromenaKolicine, &p.StanjePre, &p.StanjePosle, &p.Napomena); err != nil {
|
||||||
|
return nil, fmt.Errorf("ntech: IzvestajRepo.PrometniList: scan: %w", err)
|
||||||
|
}
|
||||||
|
lista = append(lista, p)
|
||||||
|
}
|
||||||
|
return lista, rows.Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// StanjeZaliha vraća trenutno stanje svih artikala sa vrednostima
|
||||||
|
func (r *sqliteIzvestajRepo) StanjeZaliha(ctx context.Context) ([]model.StanjeZalihaRed, error) {
|
||||||
|
rows, err := r.db.QueryContext(ctx, `
|
||||||
|
SELECT a.naziv, COALESCE(a.sifra, ''), COALESCE(k.naziv, ''),
|
||||||
|
a.kolicina, a.kolicina_min, a.nabavna_cena, a.prodajna_cena,
|
||||||
|
a.kolicina * a.nabavna_cena AS vrednost
|
||||||
|
FROM artikli a
|
||||||
|
LEFT JOIN kategorije k ON k.id = a.kategorija_id
|
||||||
|
ORDER BY k.naziv ASC, a.naziv ASC`,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ntech: IzvestajRepo.StanjeZaliha: %w", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var lista []model.StanjeZalihaRed
|
||||||
|
for rows.Next() {
|
||||||
|
var s model.StanjeZalihaRed
|
||||||
|
if err := rows.Scan(&s.Naziv, &s.Sifra, &s.Kategorija,
|
||||||
|
&s.Kolicina, &s.KolicinMin, &s.NabavnaCena, &s.ProdajnaCena, &s.VrednostZalihe); err != nil {
|
||||||
|
return nil, fmt.Errorf("ntech: IzvestajRepo.StanjeZaliha: scan: %w", err)
|
||||||
|
}
|
||||||
|
lista = append(lista, s)
|
||||||
|
}
|
||||||
|
return lista, rows.Err()
|
||||||
|
}
|
||||||
|
|||||||
@@ -202,3 +202,96 @@ func (h *Handler) Izvestaji(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
h.renderujTemplate(w, "izvestaji", podaci)
|
h.renderujTemplate(w, "izvestaji", podaci)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PodaciPrometногLista su podaci za prometni list magacina
|
||||||
|
type PodaciPrometногLista struct {
|
||||||
|
model.PodaciStranice
|
||||||
|
Promene []model.PrometniRed
|
||||||
|
Od string
|
||||||
|
Do string
|
||||||
|
Ukupno int
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrometniListMagacina renderuje prometni list magacina za odabrani period
|
||||||
|
func (h *Handler) PrometniListMagacina(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if _, ok := h.zahtevajDozvolu(w, r, "izvestaj.pregled"); !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
danas := time.Now()
|
||||||
|
odStr := r.URL.Query().Get("od")
|
||||||
|
doStr := r.URL.Query().Get("do")
|
||||||
|
|
||||||
|
if odStr == "" {
|
||||||
|
odStr = danas.Format("2006-01-02")[:7] + "-01"
|
||||||
|
}
|
||||||
|
if doStr == "" {
|
||||||
|
doStr = danas.Format("2006-01-02")
|
||||||
|
}
|
||||||
|
|
||||||
|
od, err := time.Parse("2006-01-02", odStr)
|
||||||
|
if err != nil {
|
||||||
|
od = time.Now()
|
||||||
|
}
|
||||||
|
do, err := time.Parse("2006-01-02", doStr)
|
||||||
|
if err != nil {
|
||||||
|
do = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
promene, err := h.IzvestajRepo.PrometniList(r.Context(), od, do)
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("prometni list: greška", "error", err)
|
||||||
|
promene = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "izvestaji"
|
||||||
|
ps.NaslovStranice = "Prometni list"
|
||||||
|
|
||||||
|
h.renderujTemplate(w, "prometni_list", PodaciPrometногLista{
|
||||||
|
PodaciStranice: ps,
|
||||||
|
Promene: promene,
|
||||||
|
Od: odStr,
|
||||||
|
Do: doStr,
|
||||||
|
Ukupno: len(promene),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// PodaciStanjaZaliha su podaci za izveštaj o stanju zaliha
|
||||||
|
type PodaciStanjaZaliha struct {
|
||||||
|
model.PodaciStranice
|
||||||
|
Zalihe []model.StanjeZalihaRed
|
||||||
|
UkupnaVrednost float64
|
||||||
|
BrojArtikala int
|
||||||
|
}
|
||||||
|
|
||||||
|
// StanjeZalihaIzvestaj renderuje izveštaj o trenutnom stanju zaliha
|
||||||
|
func (h *Handler) StanjeZalihaIzvestaj(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if _, ok := h.zahtevajDozvolu(w, r, "izvestaj.pregled"); !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
zalihe, err := h.IzvestajRepo.StanjeZaliha(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
slog.Error("stanje zaliha: greška", "error", err)
|
||||||
|
zalihe = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var ukupnaVrednost float64
|
||||||
|
for _, z := range zalihe {
|
||||||
|
ukupnaVrednost += z.VrednostZalihe
|
||||||
|
}
|
||||||
|
|
||||||
|
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||||
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
|
ps.Stranica = "izvestaji"
|
||||||
|
ps.NaslovStranice = "Stanje zaliha"
|
||||||
|
|
||||||
|
h.renderujTemplate(w, "stanje_zaliha", PodaciStanjaZaliha{
|
||||||
|
PodaciStranice: ps,
|
||||||
|
Zalihe: zalihe,
|
||||||
|
UkupnaVrednost: ukupnaVrednost,
|
||||||
|
BrojArtikala: len(zalihe),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ var saSidebar = []string{
|
|||||||
"admin_korisnici", "admin_profil", "admin_login_istorija", "admin_dozvole",
|
"admin_korisnici", "admin_profil", "admin_login_istorija", "admin_dozvole",
|
||||||
"dashboard",
|
"dashboard",
|
||||||
"dobavljaci", "dobavljac_forma",
|
"dobavljaci", "dobavljac_forma",
|
||||||
"izvestaji",
|
"izvestaji", "prometni_list", "stanje_zaliha",
|
||||||
"kategorije",
|
"kategorije",
|
||||||
"klijenti", "klijent_forma",
|
"klijenti", "klijent_forma",
|
||||||
"magacin", "magacin_forma", "magacin_kartica",
|
"magacin", "magacin_forma", "magacin_kartica",
|
||||||
|
|||||||
@@ -58,3 +58,27 @@ type TopKlijentRed struct {
|
|||||||
UkupnoVrednost float64
|
UkupnoVrednost float64
|
||||||
BrojNaloga int
|
BrojNaloga int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrometniRed je jedan red prometnog lista magacina
|
||||||
|
type PrometniRed struct {
|
||||||
|
Datum time.Time
|
||||||
|
ArtikalNaziv string
|
||||||
|
ArtikalSifra string
|
||||||
|
TipPromene string
|
||||||
|
PromenaKolicine int
|
||||||
|
StanjePre int
|
||||||
|
StanjePosle int
|
||||||
|
Napomena string
|
||||||
|
}
|
||||||
|
|
||||||
|
// StanjeZalihaRed je jedan red izveštaja o stanju zaliha
|
||||||
|
type StanjeZalihaRed struct {
|
||||||
|
Naziv string
|
||||||
|
Sifra string
|
||||||
|
Kategorija string
|
||||||
|
Kolicina int
|
||||||
|
KolicinMin int
|
||||||
|
NabavnaCena float64
|
||||||
|
ProdajnaCena float64
|
||||||
|
VrednostZalihe float64 // kolicina × nabavna_cena
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,12 @@
|
|||||||
{{define "sadrzaj"}}
|
{{define "sadrzaj"}}
|
||||||
<div class="kolona" style="gap:20px;">
|
<div class="kolona" style="gap:20px;">
|
||||||
|
|
||||||
|
<!-- brzi linkovi ka magacinskim izveštajima -->
|
||||||
|
<div style="display:flex;gap:10px;flex-wrap:wrap;">
|
||||||
|
<a href="/izvestaji/prometni-list" class="btn-sekundarno">Prometni list magacina</a>
|
||||||
|
<a href="/izvestaji/stanje-zaliha" class="btn-sekundarno">Stanje zaliha</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 1. mesečni prihod -->
|
<!-- 1. mesečni prihod -->
|
||||||
<div class="kartica izv-sekcija animiraj">
|
<div class="kartica izv-sekcija animiraj">
|
||||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:4px;">
|
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;margin-bottom:4px;">
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
{{template "base" .}}
|
||||||
|
|
||||||
|
{{define "naslov"}}Prometni list — NTech{{end}}
|
||||||
|
|
||||||
|
{{define "sadrzaj"}}
|
||||||
|
<div class="kolona" style="gap:16px;">
|
||||||
|
|
||||||
|
<!-- filter perioda -->
|
||||||
|
<div class="kartica animiraj">
|
||||||
|
<form method="GET" action="/izvestaji/prometni-list" style="display:flex;gap:12px;align-items:flex-end;flex-wrap:wrap;">
|
||||||
|
<div>
|
||||||
|
<label class="polje-labela">Od datuma</label>
|
||||||
|
<input type="date" name="od" value="{{.Od}}" style="width:160px;">
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label class="polje-labela">Do datuma</label>
|
||||||
|
<input type="date" name="do" value="{{.Do}}" style="width:160px;">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn-primarno">Prikaži</button>
|
||||||
|
<a href="/izvestaji" class="btn-sekundarno">← Izveštaji</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- tabela promena -->
|
||||||
|
<div class="kartica animiraj" style="padding:0;overflow:hidden;">
|
||||||
|
<div style="padding:16px 20px;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:15px;font-weight:500;color:var(--tekst-glavni);">Prometni list magacina</span>
|
||||||
|
<span style="font-size:12px;color:var(--tekst-slabi);">{{.Od}} — {{.Do}} · {{.Ukupno}} promena</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if not .Promene}}
|
||||||
|
<div style="padding:40px;text-align:center;color:var(--tekst-slabi);font-size:14px;">
|
||||||
|
Nema promena u odabranom periodu.
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div style="overflow-x:auto;">
|
||||||
|
<table class="tabela">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Datum</th>
|
||||||
|
<th>Artikal</th>
|
||||||
|
<th>Šifra</th>
|
||||||
|
<th>Vrsta</th>
|
||||||
|
<th style="text-align:right;">Promena</th>
|
||||||
|
<th style="text-align:right;">Pre</th>
|
||||||
|
<th style="text-align:right;">Posle</th>
|
||||||
|
<th>Napomena</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .Promene}}
|
||||||
|
<tr>
|
||||||
|
<td style="white-space:nowrap;font-size:12px;color:var(--tekst-slabi);">
|
||||||
|
{{.Datum.Format "02.01.2006. 15:04"}}
|
||||||
|
</td>
|
||||||
|
<td style="font-weight:500;">{{.ArtikalNaziv}}</td>
|
||||||
|
<td style="font-family:monospace;font-size:12px;color:var(--tekst-slabi);">{{if .ArtikalSifra}}{{.ArtikalSifra}}{{else}}—{{end}}</td>
|
||||||
|
<td>
|
||||||
|
{{if eq .TipPromene "ulaz_nabavka"}}
|
||||||
|
<span class="bedz" style="background:rgba(34,197,94,0.12);color:#22c55e;">Ulaz</span>
|
||||||
|
{{else if eq .TipPromene "izlaz_prodaja"}}
|
||||||
|
<span class="bedz" style="background:rgba(59,130,246,0.12);color:#3b82f6;">Prodaja</span>
|
||||||
|
{{else if eq .TipPromene "izlaz_servis"}}
|
||||||
|
<span class="bedz" style="background:rgba(249,115,22,0.12);color:#f97316;">Servis</span>
|
||||||
|
{{else if eq .TipPromene "povracaj"}}
|
||||||
|
<span class="bedz" style="background:rgba(168,85,247,0.12);color:#a855f7;">Povraćaj</span>
|
||||||
|
{{else if eq .TipPromene "korekcija"}}
|
||||||
|
<span class="bedz" style="background:rgba(156,163,175,0.12);color:#9ca3af;">Korekcija</span>
|
||||||
|
{{else}}
|
||||||
|
<span class="bedz">{{.TipPromene}}</span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;font-weight:600;{{if gt .PromenaKolicine 0}}color:#22c55e;{{else}}color:#dc2626;{{end}}">
|
||||||
|
{{if gt .PromenaKolicine 0}}+{{end}}{{.PromenaKolicine}}
|
||||||
|
</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;color:var(--tekst-slabi);">{{.StanjePre}}</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;font-weight:500;">{{.StanjePosle}}</td>
|
||||||
|
<td style="font-size:12px;color:var(--tekst-slabi);">{{.Napomena}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
{{template "base" .}}
|
||||||
|
|
||||||
|
{{define "naslov"}}Stanje zaliha — NTech{{end}}
|
||||||
|
|
||||||
|
{{define "sadrzaj"}}
|
||||||
|
<div class="kolona" style="gap:16px;">
|
||||||
|
|
||||||
|
<!-- zaglavlje -->
|
||||||
|
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;">
|
||||||
|
<div style="display:flex;align-items:center;gap:12px;">
|
||||||
|
<a href="/izvestaji" class="nazad-link" style="margin-bottom:0;">
|
||||||
|
<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"><polyline points="15 18 9 12 15 6"/></svg>
|
||||||
|
Izveštaji
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;gap:16px;flex-wrap:wrap;">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<div style="font-size:12px;color:var(--tekst-slabi);">Broj artikala</div>
|
||||||
|
<div style="font-size:18px;font-weight:600;color:var(--tekst-glavni);">{{.BrojArtikala}}</div>
|
||||||
|
</div>
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<div style="font-size:12px;color:var(--tekst-slabi);">Ukupna vrednost zalihe</div>
|
||||||
|
<div style="font-size:18px;font-weight:600;color:var(--tekst-glavni);">{{printf "%.2f" .UkupnaVrednost}} din</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- tabela -->
|
||||||
|
<div class="kartica animiraj" style="padding:0;overflow:hidden;">
|
||||||
|
<div style="padding:14px 20px;border-bottom:0.5px solid var(--ivica);">
|
||||||
|
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Stanje zaliha</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{if not .Zalihe}}
|
||||||
|
<div style="padding:40px;text-align:center;color:var(--tekst-slabi);font-size:14px;">
|
||||||
|
Nema artikala u magacinu.
|
||||||
|
</div>
|
||||||
|
{{else}}
|
||||||
|
<div style="overflow-x:auto;">
|
||||||
|
<table class="tabela">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Artikal</th>
|
||||||
|
<th>Šifra</th>
|
||||||
|
<th>Kategorija</th>
|
||||||
|
<th style="text-align:right;">Stanje</th>
|
||||||
|
<th style="text-align:right;">Min.</th>
|
||||||
|
<th style="text-align:right;">Nab. cena</th>
|
||||||
|
<th style="text-align:right;">Prod. cena</th>
|
||||||
|
<th style="text-align:right;">Vrednost</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .Zalihe}}
|
||||||
|
<tr {{if le .Kolicina .KolicinMin}}style="background:rgba(220,38,38,0.05);"{{end}}>
|
||||||
|
<td style="font-weight:500;{{if le .Kolicina .KolicinMin}}color:#dc2626;{{end}}">{{.Naziv}}</td>
|
||||||
|
<td style="font-family:monospace;font-size:12px;color:var(--tekst-slabi);">{{if .Sifra}}{{.Sifra}}{{else}}—{{end}}</td>
|
||||||
|
<td style="font-size:12px;color:var(--tekst-slabi);">{{if .Kategorija}}{{.Kategorija}}{{else}}—{{end}}</td>
|
||||||
|
<td style="text-align:right;font-weight:600;{{if le .Kolicina .KolicinMin}}color:#dc2626;{{end}}">{{.Kolicina}}</td>
|
||||||
|
<td style="text-align:right;font-size:12px;color:var(--tekst-slabi);">{{.KolicinMin}}</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;font-size:12px;">{{printf "%.2f" .NabavnaCena}}</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;font-size:12px;">{{printf "%.2f" .ProdajnaCena}}</td>
|
||||||
|
<td style="text-align:right;font-family:monospace;font-weight:500;">{{printf "%.2f" .VrednostZalihe}}</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr style="border-top:1.5px solid var(--ivica);font-weight:600;">
|
||||||
|
<td colspan="7" style="padding:10px 12px;font-size:13px;">Ukupna vrednost zalihe</td>
|
||||||
|
<td style="text-align:right;padding:10px 12px;font-family:monospace;">{{printf "%.2f" .UkupnaVrednost}} din</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
Reference in New Issue
Block a user