KPO: knjiga o ostvarenom prometu — lista, ručni unos, backfill, auto-upis iz prodaje i servisa
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"ntech/internal/model"
|
||||
)
|
||||
|
||||
// KpoRepo je SQLite implementacija KpoRepository interfejsa.
|
||||
type KpoRepo struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NoviKpoRepo kreira novi KpoRepo.
|
||||
func NoviKpoRepo(db *sql.DB) *KpoRepo {
|
||||
return &KpoRepo{db: db}
|
||||
}
|
||||
|
||||
// Lista vraća KPO unose u zadatom periodu (po datumu prometa); nulti datum = bez granice.
|
||||
func (r *KpoRepo) Lista(ctx context.Context, od, do time.Time) ([]model.KpoZapis, error) {
|
||||
q := `SELECT id, datum_prometa, redni_broj, broj_dokumenta, opis, prihod,
|
||||
nacin_placanja, napomena, izvor, izvor_id, datum_unosa
|
||||
FROM kpo_unosi WHERE 1=1`
|
||||
var args []any
|
||||
if !od.IsZero() {
|
||||
q += " AND datum_prometa >= ?"
|
||||
args = append(args, od.Format("2006-01-02"))
|
||||
}
|
||||
if !do.IsZero() {
|
||||
q += " AND datum_prometa <= ?"
|
||||
args = append(args, do.Format("2006-01-02"))
|
||||
}
|
||||
q += " ORDER BY datum_prometa, id"
|
||||
|
||||
redovi, err := r.db.QueryContext(ctx, q, args...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ntech: KpoRepo.Lista: %w", err)
|
||||
}
|
||||
defer redovi.Close()
|
||||
|
||||
var rezultat []model.KpoZapis
|
||||
for redovi.Next() {
|
||||
var z model.KpoZapis
|
||||
var opis, nacinPlacanja, napomena sql.NullString
|
||||
var redniBroj sql.NullInt64
|
||||
var izvorID sql.NullInt64
|
||||
|
||||
err := redovi.Scan(
|
||||
&z.ID, &z.DatumPrometa, &redniBroj, &z.BrojDokumenta, &opis, &z.Prihod,
|
||||
&nacinPlacanja, &napomena, &z.Izvor, &izvorID, &z.DatumUnosa,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ntech: KpoRepo.Lista: scan: %w", err)
|
||||
}
|
||||
if redniBroj.Valid {
|
||||
n := int(redniBroj.Int64)
|
||||
z.RedniBroj = &n
|
||||
}
|
||||
z.Opis = opis.String
|
||||
z.NacinPlacanja = nacinPlacanja.String
|
||||
z.Napomena = napomena.String
|
||||
if izvorID.Valid {
|
||||
z.IzvorID = &izvorID.Int64
|
||||
}
|
||||
rezultat = append(rezultat, z)
|
||||
}
|
||||
return rezultat, redovi.Err()
|
||||
}
|
||||
|
||||
// Kreiraj upisuje novi KPO zapis i vraća njegov ID.
|
||||
func (r *KpoRepo) Kreiraj(ctx context.Context, z *model.KpoZapis) (int64, error) {
|
||||
rez, err := r.db.ExecContext(ctx, `
|
||||
INSERT INTO kpo_unosi
|
||||
(datum_prometa, broj_dokumenta, opis, prihod, nacin_placanja, napomena, izvor, izvor_id)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
z.DatumPrometa.Format("2006-01-02"),
|
||||
z.BrojDokumenta,
|
||||
nullString(z.Opis),
|
||||
z.Prihod,
|
||||
nullString(z.NacinPlacanja),
|
||||
nullString(z.Napomena),
|
||||
izvorIliRucno(z.Izvor),
|
||||
izvorIDArg(z.IzvorID),
|
||||
)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("ntech: KpoRepo.Kreiraj: %w", err)
|
||||
}
|
||||
id, err := rez.LastInsertId()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("ntech: KpoRepo.Kreiraj: id: %w", err)
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// Obrisi briše KPO zapis po ID-ju.
|
||||
func (r *KpoRepo) Obrisi(ctx context.Context, id int64) error {
|
||||
if _, err := r.db.ExecContext(ctx, "DELETE FROM kpo_unosi WHERE id = ?", id); err != nil {
|
||||
return fmt.Errorf("ntech: KpoRepo.Obrisi: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PostojiZaIzvor vraća true ako postoji bar jedan KPO zapis za dati izvor i izvorID.
|
||||
func (r *KpoRepo) PostojiZaIzvor(ctx context.Context, izvor string, izvorID int64) (bool, error) {
|
||||
var n int
|
||||
err := r.db.QueryRowContext(ctx,
|
||||
"SELECT COUNT(*) FROM kpo_unosi WHERE izvor = ? AND izvor_id = ?", izvor, izvorID,
|
||||
).Scan(&n)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("ntech: KpoRepo.PostojiZaIzvor: %w", err)
|
||||
}
|
||||
return n > 0, nil
|
||||
}
|
||||
|
||||
// ObrisiPoIzvoru briše KPO zapise vezane za dati izvor (npr. pri stornu prodaje).
|
||||
func (r *KpoRepo) ObrisiPoIzvoru(ctx context.Context, izvor string, izvorID int64) error {
|
||||
if _, err := r.db.ExecContext(ctx, "DELETE FROM kpo_unosi WHERE izvor = ? AND izvor_id = ?", izvor, izvorID); err != nil {
|
||||
return fmt.Errorf("ntech: KpoRepo.ObrisiPoIzvoru: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user