Uklanjanje nabavne cene iz artikala, responsive dashboard, dodavanje tabela za nabavke
This commit is contained in:
@@ -25,7 +25,7 @@ func (r *ArtikalRepo) Lista(ctx context.Context, filter db.ArtikalFilter) ([]mod
|
|||||||
SELECT
|
SELECT
|
||||||
a.id, a.kategorija_id, a.naziv, a.opis,
|
a.id, a.kategorija_id, a.naziv, a.opis,
|
||||||
a.kolicina, a.kolicina_min, a.lokacija,
|
a.kolicina, a.kolicina_min, a.lokacija,
|
||||||
a.nabavna_cena, a.prodajna_cena, a.napomena, a.datum_unosa,
|
a.prodajna_cena, a.napomena, a.datum_unosa,
|
||||||
COALESCE(k.naziv, '') as kategorija_naziv
|
COALESCE(k.naziv, '') as kategorija_naziv
|
||||||
FROM artikli a
|
FROM artikli a
|
||||||
LEFT JOIN kategorije k ON a.kategorija_id = k.id
|
LEFT JOIN kategorije k ON a.kategorija_id = k.id
|
||||||
@@ -63,7 +63,7 @@ func (r *ArtikalRepo) Lista(ctx context.Context, filter db.ArtikalFilter) ([]mod
|
|||||||
err := redovi.Scan(
|
err := redovi.Scan(
|
||||||
&a.ID, &kategorijaID, &a.Naziv, &a.Opis,
|
&a.ID, &kategorijaID, &a.Naziv, &a.Opis,
|
||||||
&a.Kolicina, &a.KolicinMin, &a.Lokacija,
|
&a.Kolicina, &a.KolicinMin, &a.Lokacija,
|
||||||
&a.NabavnaCena, &a.ProdajnaCena, &a.Napomena, &a.DatumUnosa,
|
&a.ProdajnaCena, &a.Napomena, &a.DatumUnosa,
|
||||||
&a.KategorijaNaziv,
|
&a.KategorijaNaziv,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -89,11 +89,11 @@ func (r *ArtikalRepo) DohvatiID(ctx context.Context, id int64) (*model.Artikal,
|
|||||||
|
|
||||||
err := r.db.QueryRowContext(ctx, `
|
err := r.db.QueryRowContext(ctx, `
|
||||||
SELECT id, kategorija_id, naziv, opis, kolicina, kolicina_min,
|
SELECT id, kategorija_id, naziv, opis, kolicina, kolicina_min,
|
||||||
lokacija, nabavna_cena, prodajna_cena, napomena, datum_unosa
|
lokacija, prodajna_cena, napomena, datum_unosa
|
||||||
FROM artikli WHERE id = ?`, id).Scan(
|
FROM artikli WHERE id = ?`, id).Scan(
|
||||||
&a.ID, &kategorijaID, &a.Naziv, &a.Opis,
|
&a.ID, &kategorijaID, &a.Naziv, &a.Opis,
|
||||||
&a.Kolicina, &a.KolicinMin, &a.Lokacija,
|
&a.Kolicina, &a.KolicinMin, &a.Lokacija,
|
||||||
&a.NabavnaCena, &a.ProdajnaCena, &a.Napomena, &a.DatumUnosa,
|
&a.ProdajnaCena, &a.Napomena, &a.DatumUnosa,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("ntech: ArtikalRepo.DohvatiID: %w", err)
|
return nil, fmt.Errorf("ntech: ArtikalRepo.DohvatiID: %w", err)
|
||||||
@@ -111,10 +111,10 @@ func (r *ArtikalRepo) Kreiraj(ctx context.Context, a *model.Artikal) (int64, err
|
|||||||
rezultat, err := r.db.ExecContext(ctx, `
|
rezultat, err := r.db.ExecContext(ctx, `
|
||||||
INSERT INTO artikli
|
INSERT INTO artikli
|
||||||
(kategorija_id, naziv, opis, kolicina, kolicina_min, lokacija,
|
(kategorija_id, naziv, opis, kolicina, kolicina_min, lokacija,
|
||||||
nabavna_cena, prodajna_cena, napomena)
|
prodajna_cena, napomena)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
a.KategorijaID, a.Naziv, a.Opis, a.Kolicina, a.KolicinMin,
|
a.KategorijaID, a.Naziv, a.Opis, a.Kolicina, a.KolicinMin,
|
||||||
a.Lokacija, a.NabavnaCena, a.ProdajnaCena, a.Napomena,
|
a.Lokacija, a.ProdajnaCena, a.Napomena,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, fmt.Errorf("ntech: ArtikalRepo.Kreiraj: %w", err)
|
return 0, fmt.Errorf("ntech: ArtikalRepo.Kreiraj: %w", err)
|
||||||
@@ -133,11 +133,11 @@ func (r *ArtikalRepo) Izmeni(ctx context.Context, a *model.Artikal) error {
|
|||||||
_, err := r.db.ExecContext(ctx, `
|
_, err := r.db.ExecContext(ctx, `
|
||||||
UPDATE artikli SET
|
UPDATE artikli SET
|
||||||
kategorija_id = ?, naziv = ?, opis = ?, kolicina = ?,
|
kategorija_id = ?, naziv = ?, opis = ?, kolicina = ?,
|
||||||
kolicina_min = ?, lokacija = ?, nabavna_cena = ?,
|
kolicina_min = ?, lokacija = ?,
|
||||||
prodajna_cena = ?, napomena = ?
|
prodajna_cena = ?, napomena = ?
|
||||||
WHERE id = ?`,
|
WHERE id = ?`,
|
||||||
a.KategorijaID, a.Naziv, a.Opis, a.Kolicina,
|
a.KategorijaID, a.Naziv, a.Opis, a.Kolicina,
|
||||||
a.KolicinMin, a.Lokacija, a.NabavnaCena,
|
a.KolicinMin, a.Lokacija,
|
||||||
a.ProdajnaCena, a.Napomena, a.ID,
|
a.ProdajnaCena, a.Napomena, a.ID,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -230,14 +230,6 @@ func parseFormuArtikla(r *http.Request) (model.Artikal, string) {
|
|||||||
artikal.KolicinMin = v
|
artikal.KolicinMin = v
|
||||||
}
|
}
|
||||||
|
|
||||||
if c := r.FormValue("nabavna_cena"); c != "" {
|
|
||||||
v, err := strconv.ParseFloat(c, 64)
|
|
||||||
if err != nil || v < 0 {
|
|
||||||
return artikal, "Nabavna cena mora biti pozitivan broj."
|
|
||||||
}
|
|
||||||
artikal.NabavnaCena = v
|
|
||||||
}
|
|
||||||
|
|
||||||
if c := r.FormValue("prodajna_cena"); c != "" {
|
if c := r.FormValue("prodajna_cena"); c != "" {
|
||||||
v, err := strconv.ParseFloat(c, 64)
|
v, err := strconv.ParseFloat(c, 64)
|
||||||
if err != nil || v < 0 {
|
if err != nil || v < 0 {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ type Artikal struct {
|
|||||||
Kolicina int
|
Kolicina int
|
||||||
KolicinMin int
|
KolicinMin int
|
||||||
Lokacija string
|
Lokacija string
|
||||||
NabavnaCena float64
|
|
||||||
ProdajnaCena float64
|
ProdajnaCena float64
|
||||||
Napomena string
|
Napomena string
|
||||||
DatumUnosa time.Time
|
DatumUnosa time.Time
|
||||||
@@ -28,5 +27,5 @@ type Kategorija struct {
|
|||||||
type ArtikalSaKategorijom struct {
|
type ArtikalSaKategorijom struct {
|
||||||
Artikal
|
Artikal
|
||||||
KategorijaNaziv string
|
KategorijaNaziv string
|
||||||
KriticnaZaliha bool // true ako je kolicina <= kolicina_min
|
KriticnaZaliha bool
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
-- uklanjamo nabavnu cenu iz artikala
|
||||||
|
-- SQLite ne podržava DROP COLUMN direktno pre verzije 3.35
|
||||||
|
-- koristimo standardni pristup: nova tabela, kopiranje, brisanje stare
|
||||||
|
CREATE TABLE artikli_novi (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
kategorija_id INTEGER REFERENCES kategorije(id) ON DELETE SET NULL,
|
||||||
|
naziv TEXT NOT NULL,
|
||||||
|
opis TEXT,
|
||||||
|
kolicina INTEGER NOT NULL DEFAULT 0,
|
||||||
|
kolicina_min INTEGER NOT NULL DEFAULT 0,
|
||||||
|
lokacija TEXT,
|
||||||
|
prodajna_cena REAL NOT NULL DEFAULT 0,
|
||||||
|
napomena TEXT,
|
||||||
|
datum_unosa DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO artikli_novi
|
||||||
|
(id, kategorija_id, naziv, opis, kolicina, kolicina_min,
|
||||||
|
lokacija, prodajna_cena, napomena, datum_unosa)
|
||||||
|
SELECT
|
||||||
|
id, kategorija_id, naziv, opis, kolicina, kolicina_min,
|
||||||
|
lokacija, prodajna_cena, napomena, datum_unosa
|
||||||
|
FROM artikli;
|
||||||
|
|
||||||
|
DROP TABLE artikli;
|
||||||
|
ALTER TABLE artikli_novi RENAME TO artikli;
|
||||||
|
|
||||||
|
-- tabela nabavki
|
||||||
|
CREATE TABLE IF NOT EXISTS nabavke (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
dobavljac_id INTEGER REFERENCES dobavljaci(id) ON DELETE SET NULL,
|
||||||
|
broj_nabavke TEXT NOT NULL UNIQUE,
|
||||||
|
napomena TEXT,
|
||||||
|
ukupno REAL NOT NULL DEFAULT 0,
|
||||||
|
datum DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- stavke nabavke
|
||||||
|
CREATE TABLE IF NOT EXISTS stavke_nabavke (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
nabavka_id INTEGER NOT NULL REFERENCES nabavke(id) ON DELETE CASCADE,
|
||||||
|
artikal_id INTEGER NOT NULL REFERENCES artikli(id) ON DELETE RESTRICT,
|
||||||
|
kolicina INTEGER NOT NULL DEFAULT 1,
|
||||||
|
cena_po_komadu REAL NOT NULL,
|
||||||
|
ukupno REAL NOT NULL
|
||||||
|
);
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
{{define "naslov"}}Dashboard — NTech{{end}}
|
{{define "naslov"}}Dashboard — NTech{{end}}
|
||||||
|
|
||||||
{{define "sadrzaj"}}
|
{{define "sadrzaj"}}
|
||||||
<div class="grid grid-cols-4 gap-3 mb-6">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-3 mb-6">
|
||||||
<!-- stat kartice -->
|
<!-- stat kartice -->
|
||||||
<div class="kartica">
|
<div class="kartica">
|
||||||
<div style="width:36px;height:36px;border-radius:8px;background:#eff2ff;display:flex;align-items:center;justify-content:center;margin-bottom:10px;">
|
<div style="width:36px;height:36px;border-radius:8px;background:#eff2ff;display:flex;align-items:center;justify-content:center;margin-bottom:10px;">
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<!-- poslednji servisi -->
|
<!-- poslednji servisi -->
|
||||||
<div class="kartica">
|
<div class="kartica">
|
||||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;">
|
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:14px;">
|
||||||
|
|||||||
@@ -56,7 +56,6 @@
|
|||||||
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Naziv</th>
|
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Naziv</th>
|
||||||
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Kategorija</th>
|
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Kategorija</th>
|
||||||
<th style="padding:12px 16px;text-align:center;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Količina</th>
|
<th style="padding:12px 16px;text-align:center;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Količina</th>
|
||||||
<th style="padding:12px 16px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Nabavna</th>
|
|
||||||
<th style="padding:12px 16px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Prodajna</th>
|
<th style="padding:12px 16px;text-align:right;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Prodajna</th>
|
||||||
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Lokacija</th>
|
<th style="padding:12px 16px;text-align:left;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Lokacija</th>
|
||||||
<th style="padding:12px 16px;text-align:center;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Akcije</th>
|
<th style="padding:12px 16px;text-align:center;font-size:12px;font-weight:500;color:var(--tekst-sporedni);">Akcije</th>
|
||||||
@@ -76,7 +75,6 @@
|
|||||||
{{.Kolicina}}
|
{{.Kolicina}}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td style="padding:12px 16px;text-align:right;font-size:13px;color:var(--tekst-sporedni);">{{printf "%.0f" .NabavnaCena}} din</td>
|
|
||||||
<td style="padding:12px 16px;text-align:right;font-size:14px;color:var(--tekst-glavni);">{{printf "%.0f" .ProdajnaCena}} din</td>
|
<td style="padding:12px 16px;text-align:right;font-size:14px;color:var(--tekst-glavni);">{{printf "%.0f" .ProdajnaCena}} din</td>
|
||||||
<td style="padding:12px 16px;font-size:13px;color:var(--tekst-sporedni);">
|
<td style="padding:12px 16px;font-size:13px;color:var(--tekst-sporedni);">
|
||||||
{{if .Lokacija}}{{.Lokacija}}{{else}}—{{end}}
|
{{if .Lokacija}}{{.Lokacija}}{{else}}—{{end}}
|
||||||
|
|||||||
@@ -68,17 +68,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- cene -->
|
|
||||||
<div class="forma-grid-2" style="display:grid;grid-template-columns:1fr 1fr;gap:12px;">
|
|
||||||
<div>
|
|
||||||
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:6px;">Nabavna cena (din)</label>
|
|
||||||
<input type="number" name="nabavna_cena" value="{{.Artikal.NabavnaCena}}" min="0" step="0.01" style="width:100%;">
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:6px;">Prodajna cena (din)</label>
|
<label style="font-size:13px;color:var(--tekst-sporedni);display:block;margin-bottom:6px;">Prodajna cena (din)</label>
|
||||||
<input type="number" name="prodajna_cena" value="{{.Artikal.ProdajnaCena}}" min="0" step="0.01" style="width:100%;">
|
<input type="number" name="prodajna_cena" value="{{.Artikal.ProdajnaCena}}" min="0" step="0.01" style="width:100%;">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- lokacija -->
|
<!-- lokacija -->
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Reference in New Issue
Block a user