Popravka sidebara: kolaps, podmeni i HTMX navigacija
This commit is contained in:
@@ -21,7 +21,9 @@ type Handler struct {
|
||||
DobavljaciRepo db.DobavljacRepository
|
||||
NabavkeRepo db.NabavkaRepository
|
||||
KlijentiRepo db.KlijentRepository
|
||||
ServisRepo db.ServisRepository
|
||||
ServisRepo db.ServisRepository
|
||||
ServisniDeloviRepo db.ServisniDeloviRepository
|
||||
MagacinskePromeneRepo db.MagacinskePromeneRepository
|
||||
ProdajaRepo db.ProdajaRepository
|
||||
KorisniciRepo db.KorisniciRepository
|
||||
SesijeRepo db.SesijeRepository
|
||||
@@ -43,8 +45,10 @@ func Novi(baza *sql.DB) *Handler {
|
||||
DobavljaciRepo: sqlite.NoviDobavljacRepo(baza),
|
||||
NabavkeRepo: sqlite.NoviNabavkaRepo(baza),
|
||||
KlijentiRepo: sqlite.NoviKlijentRepo(baza),
|
||||
ServisRepo: sqlite.NoviServisRepo(baza),
|
||||
ProdajaRepo: sqlite.NoviProdajaRepo(baza),
|
||||
ServisRepo: sqlite.NoviServisRepo(baza),
|
||||
ServisniDeloviRepo: sqlite.NoviServisniDeloviRepo(baza),
|
||||
MagacinskePromeneRepo: sqlite.NoviMagacinskePromeneRepo(baza),
|
||||
ProdajaRepo: sqlite.NoviProdajaRepo(baza),
|
||||
KorisniciRepo: sqlite.NoviKorisniciRepo(baza),
|
||||
SesijeRepo: sqlite.NoviSesijeRepo(baza),
|
||||
PodsetnikRepo: sqlite.NoviPodsetnikRepo(baza),
|
||||
@@ -63,6 +67,8 @@ func (h *Handler) reinicijalizujRepozitorijume(novaDB *sql.DB) {
|
||||
h.NabavkeRepo = sqlite.NoviNabavkaRepo(novaDB)
|
||||
h.KlijentiRepo = sqlite.NoviKlijentRepo(novaDB)
|
||||
h.ServisRepo = sqlite.NoviServisRepo(novaDB)
|
||||
h.ServisniDeloviRepo = sqlite.NoviServisniDeloviRepo(novaDB)
|
||||
h.MagacinskePromeneRepo = sqlite.NoviMagacinskePromeneRepo(novaDB)
|
||||
h.ProdajaRepo = sqlite.NoviProdajaRepo(novaDB)
|
||||
h.KorisniciRepo = sqlite.NoviKorisniciRepo(novaDB)
|
||||
h.SesijeRepo = sqlite.NoviSesijeRepo(novaDB)
|
||||
|
||||
@@ -227,21 +227,31 @@ func (h *Handler) ObrisiKlijenta(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// parseFormuKlijenta čita polja iz HTTP forme, validira ih i vraća model i eventualnu grešku
|
||||
func parseFormuKlijenta(r *http.Request) (model.Klijent, string) {
|
||||
tip := r.FormValue("tip")
|
||||
if tip != "fizicko" && tip != "pravno" {
|
||||
tip = "fizicko"
|
||||
}
|
||||
|
||||
ime := strings.TrimSpace(r.FormValue("ime"))
|
||||
nazivFirme := strings.TrimSpace(r.FormValue("naziv_firme"))
|
||||
|
||||
if ime == "" && nazivFirme == "" {
|
||||
return model.Klijent{}, "Mora biti uneto ime i prezime ili naziv firme."
|
||||
if tip == "fizicko" && ime == "" {
|
||||
return model.Klijent{Tip: tip}, "Za fizičko lice obavezno je uneti ime."
|
||||
}
|
||||
if tip == "pravno" && nazivFirme == "" {
|
||||
return model.Klijent{Tip: tip}, "Za pravno lice obavezan je naziv firme."
|
||||
}
|
||||
|
||||
email := strings.TrimSpace(r.FormValue("email"))
|
||||
if email != "" && !strings.Contains(email, "@") {
|
||||
return model.Klijent{}, "Adresa e-pošte nije ispravna."
|
||||
return model.Klijent{Tip: tip}, "Adresa e-pošte nije ispravna."
|
||||
}
|
||||
|
||||
return model.Klijent{
|
||||
Tip: tip,
|
||||
Ime: ime,
|
||||
Prezime: strings.TrimSpace(r.FormValue("prezime")),
|
||||
JMBG: strings.TrimSpace(r.FormValue("jmbg")),
|
||||
NazivFirme: nazivFirme,
|
||||
PIB: strings.TrimSpace(r.FormValue("pib")),
|
||||
Telefon: strings.TrimSpace(r.FormValue("telefon")),
|
||||
|
||||
@@ -606,6 +606,7 @@ func (h *Handler) PodesavanjaOpste(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
podaci.Stranica = "podesavanja-opste"
|
||||
h.renderujTemplate(w, "podesavanja_opste", podaci)
|
||||
}
|
||||
|
||||
@@ -621,6 +622,7 @@ func (h *Handler) PodesavanjaIzgled(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
podaci.Stranica = "podesavanja-izgled"
|
||||
h.renderujTemplate(w, "podesavanja_izgled", podaci)
|
||||
}
|
||||
|
||||
@@ -636,6 +638,7 @@ func (h *Handler) PodesavanjaSistem(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Greška pri učitavanju podešavanja", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
podaci.Stranica = "podesavanja-sistem"
|
||||
h.renderujTemplate(w, "podesavanja_sistem", podaci)
|
||||
}
|
||||
|
||||
|
||||
@@ -57,17 +57,18 @@ type PodaciStampeProdaje struct {
|
||||
PIB string
|
||||
}
|
||||
|
||||
// artikalUJSONSaCenom pretvara listu artikala u template.JS vrednost sa prodajnom cenom i stanjem
|
||||
// artikalUJSONSaCenom pretvara listu artikala u template.JS vrednost sa prodajnom cenom, PDV stopom i stanjem
|
||||
func artikalUJSONSaCenom(artikli []model.ArtikalSaKategorijom) template.JS {
|
||||
type stavka struct {
|
||||
ID int64 `json:"id"`
|
||||
Naziv string `json:"naziv"`
|
||||
Cena float64 `json:"cena"`
|
||||
PdvStopa float64 `json:"pdv_stopa"`
|
||||
Kolicina int `json:"kolicina"`
|
||||
}
|
||||
lista := make([]stavka, 0, len(artikli))
|
||||
for _, a := range artikli {
|
||||
lista = append(lista, stavka{ID: a.ID, Naziv: a.Naziv, Cena: a.ProdajnaCena, Kolicina: a.Kolicina})
|
||||
lista = append(lista, stavka{ID: a.ID, Naziv: a.Naziv, Cena: a.ProdajnaCena, PdvStopa: a.PdvStopa, Kolicina: a.Kolicina})
|
||||
}
|
||||
b, _ := json.Marshal(lista)
|
||||
return template.JS(b)
|
||||
@@ -185,7 +186,7 @@ func (h *Handler) SacuvajProdaju(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
nalog.Ukupno = ukupno
|
||||
|
||||
id, err := h.ProdajaRepo.Kreiraj(r.Context(), &nalog, stavke)
|
||||
id, err := h.ProdajaRepo.Kreiraj(r.Context(), &nalog, stavke, &k.ID)
|
||||
if err != nil {
|
||||
var errStanje *appdb.ErrNedovoljnoKolicine
|
||||
if errors.As(err, &errStanje) {
|
||||
@@ -336,10 +337,15 @@ func parseFormuProdaje(r *http.Request) (model.ProdajniNalog, []model.StavkaProd
|
||||
}
|
||||
}
|
||||
nalog.Napomena = strings.TrimSpace(r.FormValue("napomena"))
|
||||
nalog.NacinPlacanja = r.FormValue("nacin_placanja")
|
||||
if nalog.NacinPlacanja != "gotovina" && nalog.NacinPlacanja != "kartica" && nalog.NacinPlacanja != "prenos" {
|
||||
nalog.NacinPlacanja = "gotovina"
|
||||
}
|
||||
|
||||
artikalIDovi := r.Form["artikal_id[]"]
|
||||
kolicine := r.Form["kolicina[]"]
|
||||
cene := r.Form["cena_po_komadu[]"]
|
||||
pdvStope := r.Form["pdv_stopa[]"]
|
||||
|
||||
if len(artikalIDovi) == 0 {
|
||||
return nalog, nil, "Prodaja mora imati najmanje jednu stavku."
|
||||
@@ -366,17 +372,23 @@ func parseFormuProdaje(r *http.Request) (model.ProdajniNalog, []model.StavkaProd
|
||||
return nalog, nil, "Cena mora biti pozitivan broj."
|
||||
}
|
||||
|
||||
var pdvStopa float64
|
||||
if i < len(pdvStope) {
|
||||
pdvStopa, _ = strconv.ParseFloat(strings.TrimSpace(pdvStope[i]), 64)
|
||||
}
|
||||
|
||||
stavke = append(stavke, model.StavkaProdaje{
|
||||
ArtikalID: artikalID,
|
||||
Kolicina: kolicina,
|
||||
CenaPoKomadu: cena,
|
||||
PdvStopa: pdvStopa,
|
||||
})
|
||||
}
|
||||
|
||||
return nalog, stavke, ""
|
||||
}
|
||||
|
||||
// StornoProdaje stornira prodajni nalog: vraća artikle na stanje i briše nalog
|
||||
// StornoProdaje stornira prodajni nalog: vraća artikle na stanje i označava nalog kao storniran
|
||||
func (h *Handler) StornoProdaje(w http.ResponseWriter, r *http.Request) {
|
||||
k := middleware.KorisnikIzKonteksta(r.Context())
|
||||
if !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "prodaja.storno") {
|
||||
@@ -388,12 +400,19 @@ func (h *Handler) StornoProdaje(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Neispravan ID naloga", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if err := h.ProdajaRepo.Obrisi(r.Context(), id); err != nil {
|
||||
http.Error(w, "Greška pri storniranju naloga", http.StatusInternalServerError)
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, "Greška pri čitanju forme", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
razlog := strings.TrimSpace(r.FormValue("razlog"))
|
||||
if err := h.ProdajaRepo.Storno(r.Context(), id, razlog, &k.ID); err != nil {
|
||||
log.Printf("greška pri storniranju naloga: %v", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri storniranju. Možda je nalog već storniran.")
|
||||
http.Redirect(w, r, "/prodaja/"+strconv.FormatInt(id, 10), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
middleware.SetFlash(w, r, h.DB, "uspeh", "Prodajni nalog je storniran.")
|
||||
http.Redirect(w, r, "/prodaja", http.StatusSeeOther)
|
||||
http.Redirect(w, r, "/prodaja/"+strconv.FormatInt(id, 10), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// renderujFormuProdaje renderuje HTML šablon forme za unos nove prodaje
|
||||
|
||||
+149
-9
@@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
appdbPkg "ntech/internal/db"
|
||||
"ntech/internal/db/sqlite"
|
||||
"ntech/internal/middleware"
|
||||
"ntech/internal/model"
|
||||
@@ -30,6 +31,7 @@ type PodaciFormeNaloga struct {
|
||||
model.PodaciStranice
|
||||
Nalog model.ServisniNalog
|
||||
Klijenti []model.Klijent
|
||||
Tehnicari []model.Korisnik
|
||||
SviStatusi []string
|
||||
Greska string
|
||||
Izmena bool
|
||||
@@ -38,9 +40,12 @@ type PodaciFormeNaloga struct {
|
||||
// PodaciDetaljiNaloga su podaci za pregled jednog servisnog naloga
|
||||
type PodaciDetaljiNaloga struct {
|
||||
model.PodaciStranice
|
||||
Nalog model.ServisniNalog
|
||||
KlijentNaziv string
|
||||
Sacuvano bool
|
||||
Nalog model.ServisniNalog
|
||||
KlijentNaziv string
|
||||
TehnicarNaziv string
|
||||
ServisniDelovi []model.ServisniDeoSaArtiklom
|
||||
Artikli []model.ArtikalSaKategorijom
|
||||
Sacuvano bool
|
||||
}
|
||||
|
||||
// Servis renderuje listu servisnih naloga sa opcionom pretragom i filterom statusa
|
||||
@@ -96,6 +101,12 @@ func (h *Handler) NoviNalog(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tehnicari, err := h.KorisniciRepo.Lista(r.Context())
|
||||
if err != nil {
|
||||
http.Error(w, "Greška pri učitavanju tehničara", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Novi nalog"
|
||||
@@ -103,6 +114,7 @@ func (h *Handler) NoviNalog(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: model.ServisniNalog{BrojNaloga: brojNaloga, Status: model.StatusPrimljeno},
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Izmena: false,
|
||||
})
|
||||
@@ -124,6 +136,7 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
||||
if greska != "" {
|
||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||
tehnicari, _ := h.KorisniciRepo.Lista(r.Context())
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Novi nalog"
|
||||
@@ -131,6 +144,7 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: nalog,
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Greska: greska,
|
||||
Izmena: false,
|
||||
@@ -143,6 +157,7 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("greška pri čuvanju naloga: %v", err)
|
||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||
tehnicari, _ := h.KorisniciRepo.Lista(r.Context())
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Novi nalog"
|
||||
@@ -150,6 +165,7 @@ func (h *Handler) SacuvajNalog(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: nalog,
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||
Izmena: false,
|
||||
@@ -186,6 +202,12 @@ func (h *Handler) IzmeniNalog(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
tehnicari, err := h.KorisniciRepo.Lista(r.Context())
|
||||
if err != nil {
|
||||
http.Error(w, "Greška pri učitavanju tehničara", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Izmeni nalog"
|
||||
@@ -193,6 +215,7 @@ func (h *Handler) IzmeniNalog(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: *nalog,
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Izmena: true,
|
||||
})
|
||||
@@ -220,6 +243,7 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
if greska != "" {
|
||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||
tehnicari, _ := h.KorisniciRepo.Lista(r.Context())
|
||||
nalog.ID = id
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
@@ -228,6 +252,7 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: nalog,
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Greska: greska,
|
||||
Izmena: true,
|
||||
@@ -240,6 +265,7 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("greška pri čuvanju izmene naloga: %v", err)
|
||||
podesavanja, _ := sqlite.DohvatiSvaPodesavanja(r.Context(), h.DB)
|
||||
klijenti, _ := h.KlijentiRepo.Lista(r.Context(), "")
|
||||
tehnicari, _ := h.KorisniciRepo.Lista(r.Context())
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Izmeni nalog"
|
||||
@@ -247,6 +273,7 @@ func (h *Handler) SacuvajIzmenaNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: nalog,
|
||||
Klijenti: klijenti,
|
||||
Tehnicari: tehnicari,
|
||||
SviStatusi: model.SviStatusi,
|
||||
Greska: "Došlo je do greške pri čuvanju. Pokušajte ponovo.",
|
||||
Izmena: true,
|
||||
@@ -278,7 +305,7 @@ func (h *Handler) ObrisiNalog(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/servis?obrisan=1", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// DetaljiNaloga prikazuje sve podatke jednog servisnog naloga
|
||||
// DetaljiNaloga prikazuje sve podatke jednog servisnog naloga sa ugrađenim delovima
|
||||
func (h *Handler) DetaljiNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := parseID(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
@@ -302,14 +329,29 @@ func (h *Handler) DetaljiNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
if nalog.KlijentID != nil {
|
||||
klijent, err := h.KlijentiRepo.DohvatiID(r.Context(), *nalog.KlijentID)
|
||||
if err == nil {
|
||||
if klijent.NazivFirme != "" {
|
||||
klijentNaziv = klijent.NazivFirme
|
||||
} else {
|
||||
klijentNaziv = strings.TrimSpace(klijent.Ime + " " + klijent.Prezime)
|
||||
}
|
||||
klijentNaziv = klijent.PunoIme()
|
||||
}
|
||||
}
|
||||
|
||||
tehnicarNaziv := ""
|
||||
if nalog.TehnicarID != nil {
|
||||
tehnicar, err := h.KorisniciRepo.DohvatiPoID(r.Context(), *nalog.TehnicarID)
|
||||
if err == nil {
|
||||
tehnicarNaziv = tehnicar.KorisnickoIme
|
||||
}
|
||||
}
|
||||
|
||||
delovi, err := h.ServisniDeloviRepo.DohvatiZaNalog(r.Context(), id)
|
||||
if err != nil {
|
||||
log.Printf("greška pri učitavanju delova: %v", err)
|
||||
}
|
||||
|
||||
appdb := appdbPkg.ArtikalFilter{}
|
||||
artikli, err := h.Artikli.Lista(r.Context(), appdb)
|
||||
if err != nil {
|
||||
log.Printf("greška pri učitavanju artikala: %v", err)
|
||||
}
|
||||
|
||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||
ps.Stranica = "servis"
|
||||
ps.NaslovStranice = "Detalji naloga"
|
||||
@@ -317,12 +359,96 @@ func (h *Handler) DetaljiNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
PodaciStranice: ps,
|
||||
Nalog: *nalog,
|
||||
KlijentNaziv: klijentNaziv,
|
||||
TehnicarNaziv: tehnicarNaziv,
|
||||
ServisniDelovi: delovi,
|
||||
Artikli: artikli,
|
||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||
}
|
||||
|
||||
h.renderujTemplate(w, "servis_detalji", podaci)
|
||||
}
|
||||
|
||||
// DodajDeloNalogu prima POST formu i dodaje artikal kao deo servisnog naloga
|
||||
func (h *Handler) DodajDeloNalogu(w http.ResponseWriter, r *http.Request) {
|
||||
k := middleware.KorisnikIzKonteksta(r.Context())
|
||||
if !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "servis.izmeni") {
|
||||
http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
nalogID, err := parseID(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
http.Error(w, "Neispravan ID naloga", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, "Greška pri čitanju forme", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
artikalID, err := strconv.ParseInt(r.FormValue("artikal_id"), 10, 64)
|
||||
if err != nil || artikalID <= 0 {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Neispravan artikal.")
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
kolicina, err := strconv.Atoi(r.FormValue("kolicina"))
|
||||
if err != nil || kolicina <= 0 {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Količina mora biti pozitivan broj.")
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
cena, err := strconv.ParseFloat(r.FormValue("cena_komada"), 64)
|
||||
if err != nil || cena < 0 {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Cena mora biti pozitivan broj.")
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := h.ServisniDeloviRepo.Dodaj(r.Context(), nalogID, artikalID, kolicina, cena, &k.ID); err != nil {
|
||||
log.Printf("greška pri dodavanju dela: %v", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri dodavanju dela. Proverite stanje na magacinu.")
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
middleware.SetFlash(w, r, h.DB, "uspeh", "Deo je dodat.")
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// ObrisiDeloNaloga prima POST zahtev i uklanja deo iz servisnog naloga
|
||||
func (h *Handler) ObrisiDeloNaloga(w http.ResponseWriter, r *http.Request) {
|
||||
k := middleware.KorisnikIzKonteksta(r.Context())
|
||||
if !h.DozvoleRepo.ImaDozvolu(r.Context(), k.Uloga, "servis.izmeni") {
|
||||
http.Error(w, "Nemate dozvolu za ovu akciju.", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
nalogID, err := parseID(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
http.Error(w, "Neispravan ID naloga", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
deoID, err := parseID(chi.URLParam(r, "deo_id"))
|
||||
if err != nil {
|
||||
http.Error(w, "Neispravan ID dela", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.ServisniDeloviRepo.Obrisi(r.Context(), deoID, &k.ID); err != nil {
|
||||
log.Printf("greška pri brisanju dela: %v", err)
|
||||
middleware.SetFlash(w, r, h.DB, "greska", "Greška pri uklanjanju dela.")
|
||||
} else {
|
||||
middleware.SetFlash(w, r, h.DB, "uspeh", "Deo je uklonjen.")
|
||||
}
|
||||
|
||||
http.Redirect(w, r, "/servis/"+strconv.FormatInt(nalogID, 10), http.StatusSeeOther)
|
||||
}
|
||||
|
||||
// parseFormuNaloga čita i validira polja iz HTTP forme
|
||||
func parseFormuNaloga(r *http.Request) (model.ServisniNalog, string) {
|
||||
uredjaj := strings.TrimSpace(r.FormValue("uredjaj"))
|
||||
@@ -355,6 +481,13 @@ func parseFormuNaloga(r *http.Request) (model.ServisniNalog, string) {
|
||||
}
|
||||
}
|
||||
|
||||
// opcioni tehničar
|
||||
if tidStr := r.FormValue("tehnicar_id"); tidStr != "" {
|
||||
if tid, err := strconv.ParseInt(tidStr, 10, 64); err == nil {
|
||||
nalog.TehnicarID = &tid
|
||||
}
|
||||
}
|
||||
|
||||
// opcione cene — prazno polje ostaje nil
|
||||
nalog.CenaOd = parseOpcionuCenu(r.FormValue("cena_od"))
|
||||
nalog.CenaDo = parseOpcionuCenu(r.FormValue("cena_do"))
|
||||
@@ -368,6 +501,13 @@ func parseFormuNaloga(r *http.Request) (model.ServisniNalog, string) {
|
||||
}
|
||||
}
|
||||
|
||||
// opcioni datum garancije
|
||||
if gd := strings.TrimSpace(r.FormValue("garancija_do")); gd != "" {
|
||||
if t, err := time.Parse("2006-01-02", gd); err == nil {
|
||||
nalog.GarancijaDo = &t
|
||||
}
|
||||
}
|
||||
|
||||
return nalog, ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user