KIR: prikaz sumnjivih duplikata (double-submit) preskočenih pri backfill-u
Na KIR stranici se sad vidi kartica sa B2B prodajama koje je automatski backfill preskočio jer izgledaju kao dupli submit forme naplate (isti kupac i iznos u roku od 60s) — sa objašnjenjem i linkom na ručni unos ili storno.
This commit is contained in:
+29
-11
@@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
appdb "ntech/internal/db"
|
||||||
"ntech/internal/db/sqlite"
|
"ntech/internal/db/sqlite"
|
||||||
"ntech/internal/middleware"
|
"ntech/internal/middleware"
|
||||||
"ntech/internal/model"
|
"ntech/internal/model"
|
||||||
@@ -20,11 +21,12 @@ import (
|
|||||||
// PodaciPdvKir su podaci za pregled knjige izdatih računa
|
// PodaciPdvKir su podaci za pregled knjige izdatih računa
|
||||||
type PodaciPdvKir struct {
|
type PodaciPdvKir struct {
|
||||||
model.PodaciStranice
|
model.PodaciStranice
|
||||||
Zapisi []model.PdvKir
|
Zapisi []model.PdvKir
|
||||||
Sume model.PdvKirSume
|
Sume model.PdvKirSume
|
||||||
Od string // filter perioda (YYYY-MM-DD), prazno = bez granice
|
Od string
|
||||||
Do string
|
Do string
|
||||||
Zastareo map[int64]bool // ID zapisa dnevnog pazara čiji je iznos van sinhronizacije sa trenutnim prometom (npr. posle naknadnog storna)
|
Zastareo map[int64]bool
|
||||||
|
SumnjiviDuplikati []model.ProdajniNalogSaDetaljem // B2B prodaje preskočene pri backfill-u (double-submit)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PodaciPdvKirForma su podaci za formu unosa zapisa KIR
|
// PodaciPdvKirForma su podaci za formu unosa zapisa KIR
|
||||||
@@ -105,13 +107,29 @@ func (h *Handler) PdvKir(w http.ResponseWriter, r *http.Request) {
|
|||||||
ps := h.popuniPodaciStranice(r, podesavanja)
|
ps := h.popuniPodaciStranice(r, podesavanja)
|
||||||
ps.Stranica = "pdv-kir"
|
ps.Stranica = "pdv-kir"
|
||||||
ps.NaslovStranice = "KIR — knjiga izdatih računa"
|
ps.NaslovStranice = "KIR — knjiga izdatih računa"
|
||||||
|
|
||||||
|
// detektuj sumnjive duplikate (double-submit) da ih korisnik vidi
|
||||||
|
var sumnjivi []model.ProdajniNalogSaDetaljem
|
||||||
|
if _, _, kandidati, err := h.kirKandidatiProdaje(r.Context()); err == nil {
|
||||||
|
duplikati := sumnjiviDuplikati(kandidati)
|
||||||
|
if len(duplikati) > 0 {
|
||||||
|
nalozi, _ := h.ProdajaRepo.Lista(r.Context(), appdb.ProdajaFilter{})
|
||||||
|
for _, nd := range nalozi {
|
||||||
|
if duplikati[nd.ID] {
|
||||||
|
sumnjivi = append(sumnjivi, nd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
h.renderujTemplate(w, "pdv_kir", PodaciPdvKir{
|
h.renderujTemplate(w, "pdv_kir", PodaciPdvKir{
|
||||||
PodaciStranice: ps,
|
PodaciStranice: ps,
|
||||||
Zapisi: zapisi,
|
Zapisi: zapisi,
|
||||||
Sume: model.SumirajKir(zapisi),
|
Sume: model.SumirajKir(zapisi),
|
||||||
Od: odStr,
|
Od: odStr,
|
||||||
Do: doStr,
|
Do: doStr,
|
||||||
Zastareo: zastareo,
|
Zastareo: zastareo,
|
||||||
|
SumnjiviDuplikati: sumnjivi,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -101,5 +101,49 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- sumnjivi duplikati (double-submit) — prodaje preskočene pri automatskom uvozu -->
|
||||||
|
{{if .SumnjiviDuplikati}}
|
||||||
|
<div class="kartica animiraj" style="margin-top:24px;">
|
||||||
|
<div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;">
|
||||||
|
<span style="font-size:14px;font-weight:600;">⚠ Sumnjivi duplikati</span>
|
||||||
|
<span style="font-size:12px;color:var(--tekst-sporedni);">({{len .SumnjiviDuplikati}} preskočeno pri uvozu — mogući double-submit, proveri ručno)</span>
|
||||||
|
</div>
|
||||||
|
<div style="overflow-x:auto;">
|
||||||
|
<table class="tabela" style="width:100%;border-collapse:collapse;font-size:13px;min-width:600px;">
|
||||||
|
<thead>
|
||||||
|
<tr style="text-align:left;color:var(--tekst-sporedni);border-bottom:0.5px solid var(--ivica);">
|
||||||
|
<th style="padding:8px 12px;">Broj</th>
|
||||||
|
<th style="padding:8px 12px;">Datum</th>
|
||||||
|
<th style="padding:8px 12px;">Kupac</th>
|
||||||
|
<th style="padding:8px 12px;text-align:right;">Iznos</th>
|
||||||
|
<th style="padding:8px 12px;"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{range .SumnjiviDuplikati}}
|
||||||
|
<tr style="border-bottom:0.5px solid var(--ivica);{{if .Stornirano}}opacity:.5;{{end}}">
|
||||||
|
<td style="padding:8px 12px;font-family:monospace;">{{.BrojNaloga}}</td>
|
||||||
|
<td style="padding:8px 12px;white-space:nowrap;">{{.Datum.Format "02.01.2006. 15:04"}}</td>
|
||||||
|
<td style="padding:8px 12px;">{{.KlijentNaziv}}</td>
|
||||||
|
<td style="padding:8px 12px;text-align:right;font-weight:500;">{{dinari .Ukupno}}</td>
|
||||||
|
<td style="padding:8px 12px;text-align:right;white-space:nowrap;">
|
||||||
|
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML"
|
||||||
|
href="/prodaja/{{.ID}}" class="btn-sekundarno" style="font-size:12px;padding:4px 10px;">Pregled</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{end}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top:12px;font-size:12px;color:var(--tekst-sporedni);line-height:1.6;">
|
||||||
|
Ovo su prodaje koje izgledaju kao dupli unos (isti kupac, isti iznos, unutar 60 sekundi).
|
||||||
|
Automatski uvoz ih preskače da ne bi duplirao prihod u KIR-u.
|
||||||
|
<strong>Ako su to stvarno dve odvojene prodaje</strong> — unesi ručno preko
|
||||||
|
<a hx-boost="true" hx-target="#glavni-sadrzaj" hx-select="#glavni-sadrzaj" hx-swap="outerHTML" href="/pdv/kir/nova">+ Nov izlazni račun</a>.
|
||||||
|
<strong>Ako je greška (double-submit)</strong> — storniraj/obriši duplikat u Prodaji.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user