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:
@@ -0,0 +1,37 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
|
||||
// Nivelacija je zapis o promeni prodajne cene artikla (revizioni trag).
|
||||
// Razlika i procenat se izvode iz stare i nove cene (ne čuvaju se u bazi).
|
||||
type Nivelacija struct {
|
||||
ID int64
|
||||
ArtikalID int64
|
||||
ArtikalNaziv string // iz JOIN-a, radi prikaza; nije kolona u nivelacije
|
||||
StaraCena float64
|
||||
NovaCena float64
|
||||
Razlog string
|
||||
Izvor string // "rucno" | "izmena" | "kalkulacija"
|
||||
KorisnikID *int64
|
||||
KorisnikIme string // iz JOIN-a, radi prikaza
|
||||
Datum time.Time
|
||||
DatumUnosa time.Time
|
||||
}
|
||||
|
||||
// Razlika vraća apsolutnu promenu cene (nova − stara); negativna znači pojeftinjenje.
|
||||
func (n Nivelacija) Razlika() float64 {
|
||||
return n.NovaCena - n.StaraCena
|
||||
}
|
||||
|
||||
// Procenat vraća procentualnu promenu u odnosu na staru cenu (0 ako je stara cena 0).
|
||||
func (n Nivelacija) Procenat() float64 {
|
||||
if n.StaraCena == 0 {
|
||||
return 0
|
||||
}
|
||||
return (n.NovaCena - n.StaraCena) / n.StaraCena * 100
|
||||
}
|
||||
|
||||
// Poskupljenje vraća true kada je nova cena veća od stare.
|
||||
func (n Nivelacija) Poskupljenje() bool {
|
||||
return n.NovaCena > n.StaraCena
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNivelacija(t *testing.T) {
|
||||
// poskupljenje: 100 → 120 = +20, +20%
|
||||
n := Nivelacija{StaraCena: 100, NovaCena: 120}
|
||||
if !blizu(n.Razlika(), 20) || !blizu(n.Procenat(), 20) || !n.Poskupljenje() {
|
||||
t.Errorf("razlika=%v procenat=%v poskupljenje=%v, očekivano 20/20/true", n.Razlika(), n.Procenat(), n.Poskupljenje())
|
||||
}
|
||||
|
||||
// pojeftinjenje: 200 → 150 = -50, -25%
|
||||
n2 := Nivelacija{StaraCena: 200, NovaCena: 150}
|
||||
if !blizu(n2.Razlika(), -50) || !blizu(n2.Procenat(), -25) || n2.Poskupljenje() {
|
||||
t.Errorf("razlika=%v procenat=%v poskupljenje=%v, očekivano -50/-25/false", n2.Razlika(), n2.Procenat(), n2.Poskupljenje())
|
||||
}
|
||||
|
||||
// stara cena 0 → procenat 0 (bez deljenja nulom)
|
||||
n3 := Nivelacija{StaraCena: 0, NovaCena: 80}
|
||||
if !blizu(n3.Procenat(), 0) {
|
||||
t.Errorf("procenat=%v, očekivano 0 kada je stara cena 0", n3.Procenat())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user