feat(magacin): nivelacija — promena cene uz trag (Faza A)

Tabela nivelacije (migr 045) beleži svaku promenu prodajne cene:
artikal, stara→nova cena, razlog, izvor, korisnik, datum. Dva okidača:
posebna akcija „Promeni cenu" (modal, izvor 'rucno') i auto-trag pri
izmeni artikla (izvor 'izmena'). PromeniCenu je transakciono (update
cene + upis zapisa). Pregled /nivelacije sa filterom perioda i razlikom
(+/− i %). Modal otvara svoj nextElementSibling — radi i na mobilnom
uprkos dupliranim id-jevima iz dva rasporeda.
This commit is contained in:
2026-06-14 09:37:49 +02:00
parent c9d4704c3d
commit 0f1f65c7f7
13 changed files with 463 additions and 2 deletions
+21
View File
@@ -2,6 +2,7 @@ package handler
import (
"fmt"
"log/slog"
"net/http"
"strconv"
@@ -182,12 +183,32 @@ func (h *Handler) SacuvajIzmenuArtikla(w http.ResponseWriter, r *http.Request) {
return
}
// stara prodajna cena — za nivelacioni trag ako se promeni kroz izmenu
var staraCena float64
if stari, e := h.Artikli.DohvatiID(r.Context(), id); e == nil {
staraCena = stari.ProdajnaCena
}
artikal.ID = id
if err := h.Artikli.Izmeni(r.Context(), &artikal); err != nil {
http.Error(w, "Greška pri čuvanju izmene", http.StatusInternalServerError)
return
}
// ako se prodajna cena promenila, automatski upiši nivelacioni zapis (izvor "izmena")
if razlika := artikal.ProdajnaCena - staraCena; razlika > 0.005 || razlika < -0.005 {
korisnikID := &k.ID
if _, e := h.NivelacijaRepo.Kreiraj(r.Context(), &model.Nivelacija{
ArtikalID: id,
StaraCena: staraCena,
NovaCena: artikal.ProdajnaCena,
Izvor: "izmena",
KorisnikID: korisnikID,
}); e != nil {
slog.Error("auto-nivelacija pri izmeni artikla nije upisana", "artikal_id", id, "error", e)
}
}
http.Redirect(w, r, "/magacin?sacuvano=1", http.StatusSeeOther)
}