Servis: otključavanje naloga pri nabavci potraživanih delova

Nakon što nabavka poveća stanje artikla, SacuvajNabavku poziva
ProveriIPocistiZaArtikal koja FIFO briše/smanjuje potraživane redove.
Kada nestanu svi potraživani redovi, nalog izlazi iz Čeka delove.
This commit is contained in:
2026-06-22 15:19:50 +02:00
parent 1a56f6966e
commit 2f7e99bfd0
3 changed files with 67 additions and 0 deletions
+3
View File
@@ -221,6 +221,9 @@ type ServisniPotrazivaniDeloviRepository interface {
DodajIliUvecaj(ctx context.Context, nalogID, artikalID int64, kolicina int) (int64, error)
Obrisi(ctx context.Context, id int64) error
ObrisiZaArtikal(ctx context.Context, nalogID, artikalID int64) error
// ProveriIPocistiZaArtikal proverava potraživane redove za dati artikal nakon
// povećanja stanja i briše/smanjuje redove koji se mogu pokriti (FIFO).
ProveriIPocistiZaArtikal(ctx context.Context, artikalID int64) error
}
// ServisniRadoviRepository definiše operacije nad radovima (uslugama) na nalogu
@@ -105,3 +105,60 @@ func (r *ServisniPotrazivaniDeloviRepo) ObrisiZaArtikal(ctx context.Context, nal
}
return nil
}
// ProveriIPocistiZaArtikal poziva se nakon što stanje artikla poraste (nabavka)
// i čisti potraživane redove koji se sada mogu pokriti dostupnim stanjem (FIFO).
// Delimično pokrivanje smanjuje traženu količinu umesto brisanja.
func (r *ServisniPotrazivaniDeloviRepo) ProveriIPocistiZaArtikal(ctx context.Context, artikalID int64) error {
var stanje int
err := r.db.QueryRowContext(ctx, "SELECT kolicina FROM artikli WHERE id = ?", artikalID).Scan(&stanje)
if err != nil {
return fmt.Errorf("ntech: ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal: stanje: %w", err)
}
if stanje <= 0 {
return nil
}
redovi, err := r.db.QueryContext(ctx,
"SELECT id, kolicina FROM servisni_potrazivani_delovi WHERE artikal_id = ? ORDER BY datum",
artikalID,
)
if err != nil {
return fmt.Errorf("ntech: ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal: query: %w", err)
}
defer redovi.Close()
type red struct {
id int64
kolicina int
}
var lista []red
for redovi.Next() {
var p red
if err := redovi.Scan(&p.id, &p.kolicina); err != nil {
return fmt.Errorf("ntech: ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal: scan: %w", err)
}
lista = append(lista, p)
}
redovi.Close()
dostupno := stanje
for _, p := range lista {
if dostupno <= 0 {
break
}
if dostupno >= p.kolicina {
if _, err := r.db.ExecContext(ctx, "DELETE FROM servisni_potrazivani_delovi WHERE id = ?", p.id); err != nil {
return fmt.Errorf("ntech: ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal: delete: %w", err)
}
dostupno -= p.kolicina
} else {
novaKol := p.kolicina - dostupno
if _, err := r.db.ExecContext(ctx, "UPDATE servisni_potrazivani_delovi SET kolicina = ? WHERE id = ?", novaKol, p.id); err != nil {
return fmt.Errorf("ntech: ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal: update: %w", err)
}
dostupno = 0
}
}
return nil
}
+7
View File
@@ -261,6 +261,13 @@ func (h *Handler) SacuvajNabavku(w http.ResponseWriter, r *http.Request) {
}
}
// nakon povećanja stanja proveri da li se potraživani delovi u servisu mogu pokriti
for _, s := range stavke {
if err := h.ServisniPotrazivaniDeloviRepo.ProveriIPocistiZaArtikal(r.Context(), s.ArtikalID); err != nil {
slog.Error("provera potraživanih delova nije uspela", "artikal_id", s.ArtikalID, "error", err)
}
}
http.Redirect(w, r, "/nabavke/"+strconv.FormatInt(id, 10)+"?sacuvano=1", http.StatusSeeOther)
}