97683534ac
Po stavci nabavke: marža% (predpopunjena globalnom iz podešavanja, kalkulacija_marza) i prodajna cena = nabavna × (1+marža/100) × (1+PDV/100), živo računato u Alpine, izmenjivo. Na čuvanje se ažurira nabavna+prodajna cena artikla (ArtikalRepo.AzurirajCene) i upiše nivelacija 'kalkulacija'; prazna/nulta prodajna se preskače. ArtikliJSON nosi pdv_stopa. Postavka podrazumevane marže u Podešavanja → Sistem.
229 lines
11 KiB
Go
229 lines
11 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"ntech/internal/model"
|
|
)
|
|
|
|
// ArtikalRepository definiše operacije nad artiklima
|
|
type ArtikalRepository interface {
|
|
Lista(ctx context.Context, filter ArtikalFilter) ([]model.ArtikalSaKategorijom, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.Artikal, error)
|
|
Kreiraj(ctx context.Context, a *model.Artikal) (int64, error)
|
|
Izmeni(ctx context.Context, a *model.Artikal) error
|
|
// AzurirajCene menja samo nabavnu i prodajnu cenu (kalkulacija pri nabavci)
|
|
AzurirajCene(ctx context.Context, id int64, nabavna, prodajna float64) error
|
|
PremestiKategoriju(ctx context.Context, id int64, kategorijaID *int64) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
}
|
|
|
|
// KategorijaRepository definiše operacije nad kategorijama
|
|
type KategorijaRepository interface {
|
|
Lista(ctx context.Context) ([]model.Kategorija, error)
|
|
Kreiraj(ctx context.Context, k *model.Kategorija) (int64, error)
|
|
}
|
|
|
|
// PdvStopaRepository definiše operacije nad šifarnikom PDV stopa
|
|
type PdvStopaRepository interface {
|
|
Lista(ctx context.Context, samoAktivne bool) ([]model.PdvStopa, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.PdvStopa, error)
|
|
Kreiraj(ctx context.Context, s *model.PdvStopa) (int64, error)
|
|
Izmeni(ctx context.Context, s *model.PdvStopa) error
|
|
PostaviAktivnu(ctx context.Context, id int64, aktivna bool) error
|
|
}
|
|
|
|
// PdvKirRepository definiše operacije nad knjigom izdatih računa (KIR)
|
|
type PdvKirRepository interface {
|
|
Lista(ctx context.Context, od, do time.Time) ([]model.PdvKir, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.PdvKir, error)
|
|
Kreiraj(ctx context.Context, k *model.PdvKir) (int64, error)
|
|
Obrisi(ctx context.Context, id int64) error
|
|
// ObrisiPoIzvoru briše zapise vezane za dati izvor (npr. pri stornu prodaje)
|
|
ObrisiPoIzvoru(ctx context.Context, izvor string, izvorID int64) error
|
|
}
|
|
|
|
// PdvKprRepository definiše operacije nad knjigom primljenih računa (KPR)
|
|
type PdvKprRepository interface {
|
|
Lista(ctx context.Context, od, do time.Time) ([]model.PdvKpr, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.PdvKpr, error)
|
|
Kreiraj(ctx context.Context, k *model.PdvKpr) (int64, error)
|
|
Obrisi(ctx context.Context, id int64) error
|
|
// ObrisiPoIzvoru briše zapise vezane za dati izvor (npr. pri brisanju nabavke)
|
|
ObrisiPoIzvoru(ctx context.Context, izvor string, izvorID int64) error
|
|
}
|
|
|
|
// NivelacijaRepository definiše operacije nad evidencijom promene prodajnih cena
|
|
type NivelacijaRepository interface {
|
|
// PromeniCenu transakciono menja prodajnu cenu artikla i upisuje nivelacioni zapis;
|
|
// vraća kreirani zapis (sa starom i novom cenom). Izvor je "rucno".
|
|
PromeniCenu(ctx context.Context, artikalID int64, novaCena float64, razlog string, korisnikID *int64) (*model.Nivelacija, error)
|
|
// Kreiraj upisuje gotov nivelacioni zapis (npr. auto-trag pri izmeni artikla)
|
|
Kreiraj(ctx context.Context, n *model.Nivelacija) (int64, error)
|
|
// Lista vraća nivelacije u periodu (po datumu); nulti datum znači bez granice
|
|
Lista(ctx context.Context, od, do time.Time) ([]model.Nivelacija, error)
|
|
// ListaZaArtikal vraća sve nivelacije jednog artikla (najnovije prvo)
|
|
ListaZaArtikal(ctx context.Context, artikalID int64) ([]model.Nivelacija, error)
|
|
}
|
|
|
|
// ArtikalFilter definiše parametre za filtriranje liste artikala
|
|
type ArtikalFilter struct {
|
|
Pretraga string
|
|
KategorijaID *int64
|
|
SamoKriticni bool
|
|
}
|
|
|
|
// NabavkaRepository definiše operacije nad nabavkama
|
|
type NabavkaRepository interface {
|
|
Lista(ctx context.Context) ([]model.NabavkaSaDetaljem, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.Nabavka, error)
|
|
DohvatiStavke(ctx context.Context, nabavkaID int64) ([]model.StavkaSaArtiklom, error)
|
|
Kreiraj(ctx context.Context, n *model.Nabavka, stavke []model.StavkaNabavke) (int64, error)
|
|
Obrisi(ctx context.Context, id int64) error
|
|
}
|
|
|
|
// DobavljacRepository definiše operacije nad dobavljačima
|
|
type DobavljacRepository interface {
|
|
Lista(ctx context.Context, pretraga string) ([]model.Dobavljac, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.Dobavljac, error)
|
|
Kreiraj(ctx context.Context, d *model.Dobavljac) (int64, error)
|
|
Izmeni(ctx context.Context, d *model.Dobavljac) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
}
|
|
|
|
// KlijentRepository definiše operacije nad klijentima
|
|
type KlijentRepository interface {
|
|
Lista(ctx context.Context, pretraga string) ([]model.Klijent, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.Klijent, error)
|
|
Kreiraj(ctx context.Context, k *model.Klijent) (int64, error)
|
|
Izmeni(ctx context.Context, k *model.Klijent) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
}
|
|
|
|
// ServisRepository definiše operacije nad servisnim nalozima
|
|
type ServisRepository interface {
|
|
Lista(ctx context.Context, pretraga, status string) ([]model.ServisniNalogSaKlijentom, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.ServisniNalog, error)
|
|
Kreiraj(ctx context.Context, n *model.ServisniNalog) (int64, error)
|
|
Izmeni(ctx context.Context, n *model.ServisniNalog) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
SledeciBroj(ctx context.Context) (string, error)
|
|
}
|
|
|
|
// ProdajaRepository definiše operacije nad prodajnim nalozima
|
|
type ProdajaRepository interface {
|
|
Lista(ctx context.Context, pretraga string) ([]model.ProdajniNalogSaDetaljem, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.ProdajniNalog, error)
|
|
DohvatiStavke(ctx context.Context, nalogID int64) ([]model.StavkaProdajeSaArtiklom, error)
|
|
Kreiraj(ctx context.Context, n *model.ProdajniNalog, stavke []model.StavkaProdaje, korisnikID *int64) (int64, error)
|
|
Storno(ctx context.Context, id int64, razlog string, korisnikID *int64) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
SledeciBroj(ctx context.Context) (string, error)
|
|
}
|
|
|
|
// ServisniDeloviRepository definiše operacije nad ugrađenim delovima u servisu
|
|
type ServisniDeloviRepository interface {
|
|
DohvatiZaNalog(ctx context.Context, nalogID int64) ([]model.ServisniDeoSaArtiklom, error)
|
|
Dodaj(ctx context.Context, nalogID, artikalID int64, kolicina int, cenaKomada float64, korisnikID *int64) (int64, error)
|
|
Obrisi(ctx context.Context, id int64, korisnikID *int64) error
|
|
}
|
|
|
|
// MagacinskePromeneRepository definiše operacije nad revizijskim tragom magacina
|
|
type MagacinskePromeneRepository interface {
|
|
Lista(ctx context.Context, artikalID *int64, limit int) ([]model.MagacinskaPromenaSaDetaljem, error)
|
|
}
|
|
|
|
// KorisniciRepository definiše operacije nad korisnicima
|
|
type KorisniciRepository interface {
|
|
Kreiraj(ctx context.Context, korisnickoIme, lozinkaHash, uloga string) (*model.Korisnik, error)
|
|
DohvatiPoImenu(ctx context.Context, korisnickoIme string) (*model.Korisnik, error)
|
|
DohvatiPoID(ctx context.Context, id int64) (*model.Korisnik, error)
|
|
Lista(ctx context.Context) ([]model.Korisnik, error)
|
|
AzurirajUlogu(ctx context.Context, id int64, uloga string) error
|
|
AzurirajAktivan(ctx context.Context, id int64, aktivan bool) error
|
|
PromeniLozinku(ctx context.Context, id int64, hash string) error
|
|
SacuvajTotpTajnu(ctx context.Context, id int64, tajna string) error
|
|
SacuvajLokalnuTemu(ctx context.Context, id int64, lokalnaTema string, koristi bool) error
|
|
SacuvajLokalnuPozadinu(ctx context.Context, id int64, pozadina, opacity, blur, blurPozadine, glassOpacity string) error
|
|
PostojiIjedan(ctx context.Context) (bool, error)
|
|
Obrisi(ctx context.Context, id int64) error
|
|
}
|
|
|
|
// SesijeRepository definiše operacije nad sesijama
|
|
type SesijeRepository interface {
|
|
Kreiraj(ctx context.Context, korisnikID int64, token string, istice time.Time, totpPotvrdjeno bool) error
|
|
DohvatiPoTokenu(ctx context.Context, token string) (*model.Sesija, error)
|
|
PotvrdiTotp(ctx context.Context, token string, novoIstice time.Time) error
|
|
Obrisi(ctx context.Context, token string) error
|
|
ObrisiIstekle(ctx context.Context) error
|
|
}
|
|
|
|
// PodsetnikFilter definiše parametre za filtriranje liste podsetnika
|
|
type PodsetnikFilter struct {
|
|
SamoAktivni bool // true = samo nezavršeni; false = svi
|
|
KorisnikID *int64 // ako nije nil — samo podsetnici tog korisnika
|
|
}
|
|
|
|
// PokusajiPrijaveRepository definiše operacije nad evidencijom pokušaja prijave
|
|
type PokusajiPrijaveRepository interface {
|
|
Zabeleži(ctx context.Context, ip, korisnickoIme string, uspeh bool) error
|
|
BrojNeuspeha(ctx context.Context, ip string, od time.Time) (int, error)
|
|
VremePoslednjeg(ctx context.Context, ip string, od time.Time) (time.Time, bool, error)
|
|
ObrisiStare(ctx context.Context, pre time.Time) error
|
|
}
|
|
|
|
// LoginIstorijsaRepository definiše operacije nad evidencijom prijava
|
|
type LoginIstorijsaRepository interface {
|
|
Zabeleži(ctx context.Context, korisnikID *int64, ip, userAgent, razlog string, uspeh bool) error
|
|
ListaZaKorisnika(ctx context.Context, korisnikID int64, limit int) ([]*model.LoginPokusaj, error)
|
|
}
|
|
|
|
// DozvoleRepository definiše operacije nad dozvolama po ulogama
|
|
type DozvoleRepository interface {
|
|
ImaDozvolu(ctx context.Context, uloga, akcija string) bool
|
|
SveDozvole(ctx context.Context, uloga string) map[string]bool
|
|
Sacuvaj(ctx context.Context, uloga, akcija string, dozvoljeno bool) error
|
|
Reset(ctx context.Context) error
|
|
}
|
|
|
|
// RezervniKodoviRepository definiše operacije nad rezervnim (jednokratnim) 2FA kodovima.
|
|
// Kodovi se čuvaju kao bcrypt heš; Iskoristi prima čist kod i poredi ga sa hešovima.
|
|
type RezervniKodoviRepository interface {
|
|
Zameni(ctx context.Context, korisnikID int64, hashevi []string) error
|
|
Iskoristi(ctx context.Context, korisnikID int64, kod string) (bool, error)
|
|
BrojPreostalih(ctx context.Context, korisnikID int64) (int, error)
|
|
Obrisi(ctx context.Context, korisnikID int64) error
|
|
}
|
|
|
|
// IzvestajRepository definiše read-only upite za dashboard i stranicu izveštaja.
|
|
// Vraća sirove podatke; prezentaciju (datumi, boje, rang) radi handler.
|
|
type IzvestajRepository interface {
|
|
// dashboard — brojači
|
|
BrojArtikala(ctx context.Context) (int, error)
|
|
BrojAktivnihServisa(ctx context.Context) (int, error)
|
|
PrihodTekuciMesec(ctx context.Context) (float64, error)
|
|
BrojKriticnihZaliha(ctx context.Context) (int, error)
|
|
// dashboard — liste
|
|
PoslednjiServisi(ctx context.Context, limit int) ([]model.ServisRedDashboard, error)
|
|
KriticneZalihe(ctx context.Context, limit int) ([]model.ZalihaRed, error)
|
|
PoslednjeProdaje(ctx context.Context, limit int) ([]model.ProdajaRedDashboard, error)
|
|
// izveštaji
|
|
MesecniPrihodProdaja(ctx context.Context) ([]model.MesecniIznos, error)
|
|
MesecniPrihodServis(ctx context.Context) ([]model.MesecniIznos, error)
|
|
StariOtvoreniNalozi(ctx context.Context) ([]model.StariNalogRed, error)
|
|
TopArtikli(ctx context.Context, limit int) ([]model.TopArtikalRed, error)
|
|
TopKlijenti(ctx context.Context, limit int) ([]model.TopKlijentRed, error)
|
|
}
|
|
|
|
// PodsetnikRepository definiše operacije nad podsetnicima
|
|
type PodsetnikRepository interface {
|
|
Lista(ctx context.Context, filter PodsetnikFilter) ([]model.Podsetnik, error)
|
|
DohvatiID(ctx context.Context, id int64) (*model.Podsetnik, error)
|
|
Kreiraj(ctx context.Context, p *model.Podsetnik) (int64, error)
|
|
Izmeni(ctx context.Context, p *model.Podsetnik) error
|
|
OznaciZavrsenim(ctx context.Context, id int64, zavrseno bool) error
|
|
Obrisi(ctx context.Context, id int64) error
|
|
BrojAktivnih(ctx context.Context, filter PodsetnikFilter) (int, error)
|
|
}
|