feat(kalkulacija): Faza C — marža po kategoriji/artiklu + zavisni troškovi (backend)
Celina 1 (kompletna) — marža po kategoriji/artiklu: - migracija 046: nullable marza na artikli i kategorije - model Marza *float64 (Artikal, Kategorija) + KategorijaMarza u ArtikalSaKategorijom - repo: čitanje/pisanje marže; nove DohvatiID/Izmeni za kategoriju - dozvola kategorija.izmeni; handler IzmeniKategoriju + ruta - UI: polje marže u formi artikla i kategorije; modal izmene kategorije - nabavka: fallback predlog marže artikal → kategorija → globalna (izaberiArtikal) Celina 2 (backend) — zavisni troškovi nabavke: - migracija 047: tabela nabavka_troskovi + kolona metod_raspodele na nabavke - model NabavkaTrosak, MetodRaspodele; čista funkcija RasporediTroskove + test - repo: Kreiraj upisuje troškove i metod; DohvatiTroskove - handler: parsiranje troškova/metoda; kalkulativna nabavna cena na serveru UI forme troškova i prikaz u detaljima nabavke slede.
This commit is contained in:
@@ -1,14 +1,26 @@
|
||||
package model
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Nabavka predstavlja zaglavlje jedne nabavke
|
||||
type Nabavka struct {
|
||||
ID int64
|
||||
DobavljacID *int64
|
||||
Napomena string
|
||||
Ukupno float64
|
||||
Datum time.Time
|
||||
ID int64
|
||||
DobavljacID *int64
|
||||
Napomena string
|
||||
Ukupno float64
|
||||
MetodRaspodele string // "vrednost" ili "kolicina"; prazno = nema zavisnih troškova
|
||||
Datum time.Time
|
||||
}
|
||||
|
||||
// NabavkaTrosak je jedna stavka zavisnih troškova nabavke (npr. prevoz, carina)
|
||||
type NabavkaTrosak struct {
|
||||
ID int64
|
||||
NabavkaID int64
|
||||
Naziv string
|
||||
Iznos float64
|
||||
}
|
||||
|
||||
// StavkaNabavke predstavlja jednu liniju (artikal) unutar nabavke
|
||||
@@ -21,6 +33,44 @@ type StavkaNabavke struct {
|
||||
Ukupno float64
|
||||
}
|
||||
|
||||
// RasporediTroskove raspodeljuje ukupan zavisni trošak na stavke nabavke i vraća
|
||||
// kalkulativnu nabavnu cenu po komadu za svaku stavku (isti redosled kao ulazne stavke).
|
||||
// metod "kolicina" deli trošak po broju komada; svaka druga vrednost (uklj. "vrednost")
|
||||
// deli po nabavnoj vrednosti stavke (količina × cena).
|
||||
// Ako nema troška ili je osnovica nula, vraća nepromenjenu cenu po komadu.
|
||||
func RasporediTroskove(stavke []StavkaNabavke, ukupanTrosak float64, metod string) []float64 {
|
||||
kalk := make([]float64, len(stavke))
|
||||
|
||||
// osnovica raspodele po izabranom metodu
|
||||
var osnovica float64
|
||||
for _, s := range stavke {
|
||||
if metod == "kolicina" {
|
||||
osnovica += float64(s.Kolicina)
|
||||
} else {
|
||||
osnovica += float64(s.Kolicina) * s.CenaPoKomadu
|
||||
}
|
||||
}
|
||||
|
||||
for i, s := range stavke {
|
||||
kalk[i] = s.CenaPoKomadu
|
||||
// bez troška, bez osnovice ili bez količine — nema šta da se raspodeli
|
||||
if ukupanTrosak <= 0 || osnovica <= 0 || s.Kolicina == 0 {
|
||||
continue
|
||||
}
|
||||
var udeo float64
|
||||
if metod == "kolicina" {
|
||||
udeo = float64(s.Kolicina) / osnovica
|
||||
} else {
|
||||
udeo = (float64(s.Kolicina) * s.CenaPoKomadu) / osnovica
|
||||
}
|
||||
trosakPoKomadu := (ukupanTrosak * udeo) / float64(s.Kolicina)
|
||||
// zaokruženo na 2 decimale — kalkulativna nabavna je cena koja se čuva
|
||||
kalk[i] = math.Round((s.CenaPoKomadu+trosakPoKomadu)*100) / 100
|
||||
}
|
||||
|
||||
return kalk
|
||||
}
|
||||
|
||||
// NabavkaSaDetaljem je nabavka sa nazivom dobavljača — za prikaz u listi
|
||||
type NabavkaSaDetaljem struct {
|
||||
Nabavka
|
||||
|
||||
Reference in New Issue
Block a user