Podešavanja: matični broj, poslovna jedinica i kompaktniji raspored
Opšte → Firma: dodato polje Matični broj (validacija 8 cifara) i nova grupa Poslovna jedinica (naziv, oznaka, opština, grad) za fiskalizaciju. Polja firme upakovana u parove (forma-grid-3 klasa, responsive).
This commit is contained in:
@@ -28,6 +28,12 @@ type PodaciPodesavanja struct {
|
||||
Adresa string
|
||||
Telefon string
|
||||
PIB string
|
||||
MaticniBroj string
|
||||
// poslovna jedinica — za fiskalizaciju (oznaka PJ se šalje uz svaki račun)
|
||||
NazivPJ string
|
||||
OznakaPJ string
|
||||
Opstina string
|
||||
Grad string
|
||||
LogoPutanja string
|
||||
TopbarLogoSlika bool
|
||||
// profil firme — pravni/poreski status (Faza 0); određuje koji se zakonski moduli pale
|
||||
@@ -83,6 +89,11 @@ func (h *Handler) Podesavanja(w http.ResponseWriter, r *http.Request) {
|
||||
Adresa: podesavanja["adresa"],
|
||||
Telefon: podesavanja["telefon"],
|
||||
PIB: podesavanja["pib"],
|
||||
MaticniBroj: podesavanja["maticni_broj"],
|
||||
NazivPJ: podesavanja["poslovna_jedinica_naziv"],
|
||||
OznakaPJ: podesavanja["poslovna_jedinica_oznaka"],
|
||||
Opstina: podesavanja["opstina"],
|
||||
Grad: podesavanja["grad"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
TopbarLogoSlika: podesavanja["topbar_logo_slika"] == "1",
|
||||
Sacuvano: r.URL.Query().Get("sacuvano") == "1",
|
||||
@@ -225,6 +236,24 @@ func kopiraFajl(izvor, odrediste string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// validirajMaticniBroj proverava da li uneti matični broj ima tačno 8 cifara.
|
||||
// Prazan broj je dozvoljen (polje nije obavezno). Vraća srpsku poruku o grešci
|
||||
// ili prazan string ako je broj ispravan.
|
||||
func validirajMaticniBroj(broj string) string {
|
||||
if broj == "" {
|
||||
return ""
|
||||
}
|
||||
if len(broj) != 8 {
|
||||
return "Matični broj mora imati tačno 8 cifara."
|
||||
}
|
||||
for _, c := range broj {
|
||||
if c < '0' || c > '9' {
|
||||
return "Matični broj sme sadržati samo cifre."
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// SacuvajPodesavanja prima POST i čuva podešavanja u bazu
|
||||
func (h *Handler) SacuvajPodesavanja(w http.ResponseWriter, r *http.Request) {
|
||||
if _, ok := h.zahtevajDozvolu(w, r, "podesavanja.izmeni"); !ok {
|
||||
@@ -241,12 +270,29 @@ func (h *Handler) SacuvajPodesavanja(w http.ResponseWriter, r *http.Request) {
|
||||
topbarLogoSlika = "1"
|
||||
}
|
||||
|
||||
// matični broj — 8 cifara; prazno je dozvoljeno (polje nije obavezno)
|
||||
maticniBroj := strings.TrimSpace(r.FormValue("maticni_broj"))
|
||||
if greska := validirajMaticniBroj(maticniBroj); greska != "" {
|
||||
middleware.SetFlash(w, r, h.DB, "greska", greska)
|
||||
sledeci := "/podesavanja"
|
||||
if r.FormValue("_next") == "/admin/podesavanja/opste" {
|
||||
sledeci = "/admin/podesavanja/opste"
|
||||
}
|
||||
http.Redirect(w, r, sledeci, http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
polja := map[string]string{
|
||||
"naziv_firme": r.FormValue("naziv_firme"),
|
||||
"podnazlov": r.FormValue("podnazlov"),
|
||||
"adresa": r.FormValue("adresa"),
|
||||
"telefon": r.FormValue("telefon"),
|
||||
"pib": r.FormValue("pib"),
|
||||
"maticni_broj": maticniBroj,
|
||||
"poslovna_jedinica_naziv": r.FormValue("poslovna_jedinica_naziv"),
|
||||
"poslovna_jedinica_oznaka": r.FormValue("poslovna_jedinica_oznaka"),
|
||||
"opstina": r.FormValue("opstina"),
|
||||
"grad": r.FormValue("grad"),
|
||||
"topbar_logo_slika": topbarLogoSlika,
|
||||
// profil firme (Faza 0) — radio dugmad uvek šalju vrednost, pa se uredno čuvaju
|
||||
"firma_pravni_oblik": r.FormValue("firma_pravni_oblik"),
|
||||
@@ -695,6 +741,11 @@ func (h *Handler) napuniPodaciPodesavanja(r *http.Request, naslov string) (Podac
|
||||
Adresa: podesavanja["adresa"],
|
||||
Telefon: podesavanja["telefon"],
|
||||
PIB: podesavanja["pib"],
|
||||
MaticniBroj: podesavanja["maticni_broj"],
|
||||
NazivPJ: podesavanja["poslovna_jedinica_naziv"],
|
||||
OznakaPJ: podesavanja["poslovna_jedinica_oznaka"],
|
||||
Opstina: podesavanja["opstina"],
|
||||
Grad: podesavanja["grad"],
|
||||
LogoPutanja: podesavanja["logo_putanja"],
|
||||
TopbarLogoSlika: podesavanja["topbar_logo_slika"] == "1",
|
||||
FirmaPravniOblik: vrednostIliDefault(podesavanja, "firma_pravni_oblik", "pausalac"),
|
||||
|
||||
@@ -873,6 +873,11 @@ select {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.forma-grid-3 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.forma-grid-4 {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||
@@ -1000,6 +1005,7 @@ select {
|
||||
|
||||
/* forme */
|
||||
.forma-grid-2 { grid-template-columns: 1fr !important; }
|
||||
.forma-grid-3 { grid-template-columns: 1fr !important; }
|
||||
|
||||
/* magacin traka */
|
||||
.magacin-traka { flex-direction: column; align-items: stretch; }
|
||||
|
||||
@@ -60,40 +60,49 @@
|
||||
</div>
|
||||
|
||||
<div class="kolona" style="gap:14px;">
|
||||
<div class="forma-grid-2">
|
||||
<div>
|
||||
<label class="polje-labela">Naziv firme</label>
|
||||
<input type="text" name="naziv_firme" value="{{.NazivFirme}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. NTech">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="polje-labela">Podnazlov</label>
|
||||
<input type="text" name="podnazlov" value="{{.Podnazlov}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. Servis računara">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="forma-grid-2">
|
||||
<div>
|
||||
<label class="polje-labela">Adresa</label>
|
||||
<input type="text" name="adresa" value="{{.Adresa}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. Ulica i broj, Grad">
|
||||
</div>
|
||||
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:14px;">
|
||||
<div>
|
||||
<label class="polje-labela">Telefon</label>
|
||||
<input type="text" name="telefon" value="{{.Telefon}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. +381 11 123 4567">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="forma-grid-2">
|
||||
<div>
|
||||
<label class="polje-labela">PIB</label>
|
||||
<input type="text" name="pib" value="{{.PIB}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. 123456789">
|
||||
</div>
|
||||
<div>
|
||||
<label class="polje-labela">Matični broj</label>
|
||||
<input type="text" name="maticni_broj" value="{{.MaticniBroj}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. 12345678">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border:0.5px solid var(--ivica);border-radius:8px;">
|
||||
@@ -119,6 +128,58 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- poslovna jedinica: podaci koje fiskalizacija (SUF) traži uz svaki račun -->
|
||||
<form method="POST" action="/podesavanja/sacuvaj">
|
||||
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
|
||||
<input type="hidden" name="_next" value="/admin/podesavanja/opste">
|
||||
<div class="kartica animiraj" style="margin-bottom:16px;">
|
||||
<div style="display:flex;align-items:center;gap:10px;margin-bottom:16px;padding-bottom:12px;border-bottom:0.5px solid var(--ivica);">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--sb-akcent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M9 22V12h6v10"/></svg>
|
||||
<span style="font-size:15px;font-weight:500;color:var(--tekst-glavni);">Poslovna jedinica</span>
|
||||
</div>
|
||||
|
||||
<div class="kolona" style="gap:14px;">
|
||||
<div class="forma-grid-2">
|
||||
<div>
|
||||
<label class="polje-labela">Naziv poslovne jedinice</label>
|
||||
<input type="text" name="poslovna_jedinica_naziv" value="{{.NazivPJ}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. Prodavnica centar">
|
||||
</div>
|
||||
<div>
|
||||
<label class="polje-labela">Oznaka poslovne jedinice</label>
|
||||
<input type="text" name="poslovna_jedinica_oznaka" value="{{.OznakaPJ}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. BU-001">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="forma-grid-2">
|
||||
<div>
|
||||
<label class="polje-labela">Opština</label>
|
||||
<input type="text" name="opstina" value="{{.Opstina}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. Savski venac">
|
||||
</div>
|
||||
<div>
|
||||
<label class="polje-labela">Grad</label>
|
||||
<input type="text" name="grad" value="{{.Grad}}"
|
||||
style="width:100%;padding:8px 12px;border:0.5px solid var(--ivica);border-radius:8px;font-size:14px;background:var(--pozadina);color:var(--tekst-glavni);outline:none;"
|
||||
placeholder="npr. Beograd">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;justify-content:flex-end;margin-top:20px;">
|
||||
<button type="submit"
|
||||
style="background:var(--sb-akcent);color:#fff;border:none;padding:10px 24px;border-radius:8px;font-size:14px;font-weight:500;cursor:pointer;transition:opacity 0.2s;"
|
||||
onmouseover="this.style.opacity='0.85'" onmouseout="this.style.opacity='1'">
|
||||
Sačuvaj poslovnu jedinicu
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- profil firme: pravni/poreski status (Faza 0) — određuje koji se zakonski moduli pale -->
|
||||
<form method="POST" action="/podesavanja/sacuvaj">
|
||||
<input type="hidden" name="_csrf" value="{{.CsrfToken}}">
|
||||
|
||||
Reference in New Issue
Block a user