diff --git a/internal/db/repository.go b/internal/db/repository.go index 519682c..23ef318 100644 --- a/internal/db/repository.go +++ b/internal/db/repository.go @@ -70,6 +70,9 @@ type PdvKirRepository interface { ObrisiPoIzvoru(ctx context.Context, izvor string, izvorID int64) error // PostojiZaIzvor vraća true ako postoji bar jedan zapis za dati izvor i izvorID PostojiZaIzvor(ctx context.Context, izvor string, izvorID int64) (bool, error) + // PostojiPoBrojuDokumenta vraća true ako postoji zapis sa datim brojem dokumenta + // (npr. zaštita od duplog unosa dnevnog pazara "FISK-YYYYMMDD") + PostojiPoBrojuDokumenta(ctx context.Context, brojDokumenta string) (bool, error) } // PdvKprRepository definiše operacije nad knjigom primljenih računa (KPR) diff --git a/internal/db/sqlite/pdv_evidencija.go b/internal/db/sqlite/pdv_evidencija.go index 61652b5..1851c61 100644 --- a/internal/db/sqlite/pdv_evidencija.go +++ b/internal/db/sqlite/pdv_evidencija.go @@ -148,6 +148,18 @@ func (r *PdvKirRepo) PostojiZaIzvor(ctx context.Context, izvor string, izvorID i return n > 0, nil } +// PostojiPoBrojuDokumenta vraća true ako postoji KIR zapis sa datim brojem dokumenta +func (r *PdvKirRepo) PostojiPoBrojuDokumenta(ctx context.Context, brojDokumenta string) (bool, error) { + var n int + err := r.db.QueryRowContext(ctx, + "SELECT COUNT(*) FROM pdv_kir WHERE broj_dokumenta = ?", brojDokumenta, + ).Scan(&n) + if err != nil { + return false, fmt.Errorf("ntech: PdvKirRepo.PostojiPoBrojuDokumenta: %w", err) + } + return n > 0, nil +} + // izvorIliRucno vraća izvor ili podrazumevano „rucno" (izvor kolona je NOT NULL) func izvorIliRucno(izvor string) string { if izvor == "" { diff --git a/internal/handler/pdv_kir.go b/internal/handler/pdv_kir.go index 7a5b718..5c0b91e 100644 --- a/internal/handler/pdv_kir.go +++ b/internal/handler/pdv_kir.go @@ -251,9 +251,10 @@ func (h *Handler) KirBackfillProdaje(w http.ResponseWriter, r *http.Request) { // PodaciDnevniPazar su podaci za formu zbirnog KIR unosa (maloprodaja) type PodaciDnevniPazar struct { model.PodaciStranice - Datum string - Promet model.DnevniPrometKir - Ukupno float64 + Datum string + Promet model.DnevniPrometKir + Ukupno float64 + VecUpisano bool // true: za ovaj datum već postoji zbirni KIR zapis } // DnevniPazarKir prikazuje formu za potvrdu zbirnog KIR unosa za izabrani datum. @@ -281,6 +282,11 @@ func (h *Handler) DnevniPazarKir(w http.ResponseWriter, r *http.Request) { ukupno := math.Round((promet.OsnovicaOpsta+promet.PdvOpsta+promet.OsnovicaPosebna+promet.PdvPosebna)*100) / 100 + var vecUpisano bool + if brojDok, e := brojDokumentaDnevniPazar(datum); e == nil { + vecUpisano, _ = h.PdvKirRepo.PostojiPoBrojuDokumenta(r.Context(), brojDok) + } + ps := h.popuniPodaciStranice(r, podesavanja) ps.Stranica = "pdv-kir" ps.NaslovStranice = "Dnevni pazar — KIR unos" @@ -289,9 +295,20 @@ func (h *Handler) DnevniPazarKir(w http.ResponseWriter, r *http.Request) { Datum: datum, Promet: promet, Ukupno: ukupno, + VecUpisano: vecUpisano, }) } +// brojDokumentaDnevniPazar gradi deterministički broj dokumenta za zbirni KIR unos +// dnevnog pazara ("FISK-YYYYMMDD") — koristi se i za upis i za proveru duplikata. +func brojDokumentaDnevniPazar(datum string) (string, error) { + d, err := time.Parse("2006-01-02", datum) + if err != nil { + return "", err + } + return fmt.Sprintf("FISK-%s", d.Format("20060102")), nil +} + // SacuvajDnevniPazarKir prima POST i upisuje zbirni KIR zapis za dnevni pazar. func (h *Handler) SacuvajDnevniPazarKir(w http.ResponseWriter, r *http.Request) { if _, ok := h.zahtevajDozvolu(w, r, "pdv.dodaj"); !ok { @@ -302,17 +319,25 @@ func (h *Handler) SacuvajDnevniPazarKir(w http.ResponseWriter, r *http.Request) return } - datum, e1 := time.Parse("2006-01-02", strings.TrimSpace(r.FormValue("datum"))) + datumStr := strings.TrimSpace(r.FormValue("datum")) + datum, e1 := time.Parse("2006-01-02", datumStr) if e1 != nil { middleware.SetFlash(w, r, h.DB, "greska", "Datum je obavezan.") http.Redirect(w, r, "/pdv/kir/dnevni-pazar", http.StatusSeeOther) return } + brojDokumenta := fmt.Sprintf("FISK-%s", datum.Format("20060102")) + if postoji, _ := h.PdvKirRepo.PostojiPoBrojuDokumenta(r.Context(), brojDokumenta); postoji { + middleware.SetFlash(w, r, h.DB, "greska", fmt.Sprintf("Dnevni pazar za %s je već upisan u KIR.", datum.Format("02.01.2006."))) + http.Redirect(w, r, "/pdv/kir/dnevni-pazar?datum="+datumStr, http.StatusSeeOther) + return + } + z := model.PdvKir{ DatumPrometa: datum, DatumKnjizenja: datum, - BrojDokumenta: fmt.Sprintf("FISK-%s", datum.Format("20060102")), + BrojDokumenta: brojDokumenta, KupacNaziv: "Promet fizičkim licima", OsnovicaOpsta: parsiraIznos(r.FormValue("osnovica_opsta")), PdvOpsta: parsiraIznos(r.FormValue("pdv_opsta")), diff --git a/web/templates/stranice/pdv_kir_dnevni_pazar.html b/web/templates/stranice/pdv_kir_dnevni_pazar.html index 34c89b7..d4d3d46 100644 --- a/web/templates/stranice/pdv_kir_dnevni_pazar.html +++ b/web/templates/stranice/pdv_kir_dnevni_pazar.html @@ -78,7 +78,16 @@ - {{if gt .Promet.BrojNaloga 0}} + {{if .VecUpisano}} +