Sidebar: +ERP +CRM +Dokumenti, godišnjaci import (18 PDFs), filter helpers

- pgz nav now includes /erp/full, /crm/v2, /admin/users, /dokumenti
- 4 dokumenti endpoints: list, godišnjaci/list, godišnjak/{godina} PDF, detail
- 18 godišnjaka u pgz_sport.dokumenti (2006-2024) with savez_id=333
- PGŽ filter helpers (window._pgz_filter_priority, togglePGZFilter)
- navItemClick handler for nav items with href
This commit is contained in:
2026-05-05 13:08:11 +02:00
parent 9fb512932a
commit 1d02c0897d
970 changed files with 268354 additions and 434 deletions
+342
View File
@@ -0,0 +1,342 @@
-- erp_full_20260505.sql — FULL ERP (SAP-Lite) za PGŽ Sport
-- Author: Damir Radulić (dradulic@outlook.com / damir@rinet.one)
-- Date: 2026-05-05
-- Description: 9 tablica + 5 viewova + seed HR-RRIF kontnog plana
SET search_path TO pgz_sport, public;
-- ======================================================================
-- 1) KONTNI PLAN (HR-RRIF)
-- ======================================================================
CREATE TABLE IF NOT EXISTS pgz_sport.kontni_plan (
id SERIAL PRIMARY KEY,
sifra TEXT UNIQUE NOT NULL,
naziv TEXT NOT NULL,
klasa SMALLINT NOT NULL CHECK (klasa BETWEEN 0 AND 9),
vrsta TEXT NOT NULL CHECK (vrsta IN ('aktiva','pasiva','prihod','rashod','izvanbilanca','kapital')),
parent_id INTEGER REFERENCES pgz_sport.kontni_plan(id),
aktivan BOOLEAN DEFAULT true,
napomena TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_kontni_plan_klasa ON pgz_sport.kontni_plan(klasa);
-- ======================================================================
-- 2) PARTNERI (kupci/dobavljači)
-- ======================================================================
CREATE TABLE IF NOT EXISTS pgz_sport.partneri (
id SERIAL PRIMARY KEY,
oib CHAR(11) UNIQUE,
naziv TEXT NOT NULL,
vrsta TEXT NOT NULL CHECK (vrsta IN ('kupac','dobavljac','oba')),
iban TEXT,
adresa TEXT,
grad TEXT,
drzava TEXT DEFAULT 'HR',
email TEXT,
telefon TEXT,
aktivan BOOLEAN DEFAULT true,
napomena TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_partneri_naziv ON pgz_sport.partneri(naziv);
-- ======================================================================
-- 3) DNEVNIK + KNJIŽENJA (double-entry)
-- ======================================================================
CREATE TABLE IF NOT EXISTS pgz_sport.dnevnik_zapisa (
id SERIAL PRIMARY KEY,
datum DATE NOT NULL,
opis TEXT,
dokument_tip TEXT, -- 'racun_u'|'racun_i'|'placa'|'rucno'|'storno'
dokument_id INTEGER,
redni_broj INTEGER, -- u godini
godina INTEGER GENERATED ALWAYS AS (EXTRACT(YEAR FROM datum)::int) STORED,
storno_od_id INTEGER REFERENCES pgz_sport.dnevnik_zapisa(id),
created_by INTEGER,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_dnev_datum ON pgz_sport.dnevnik_zapisa(datum);
CREATE INDEX IF NOT EXISTS ix_dnev_dokument ON pgz_sport.dnevnik_zapisa(dokument_tip, dokument_id);
CREATE TABLE IF NOT EXISTS pgz_sport.knjizenja (
id SERIAL PRIMARY KEY,
dnevnik_id INTEGER NOT NULL REFERENCES pgz_sport.dnevnik_zapisa(id) ON DELETE CASCADE,
konto_id INTEGER NOT NULL REFERENCES pgz_sport.kontni_plan(id),
partner_id INTEGER REFERENCES pgz_sport.partneri(id),
duguje NUMERIC(14,2) DEFAULT 0 CHECK (duguje >= 0),
potrazuje NUMERIC(14,2) DEFAULT 0 CHECK (potrazuje >= 0),
opis TEXT,
CHECK (duguje = 0 OR potrazuje = 0),
CHECK (duguje > 0 OR potrazuje > 0)
);
CREATE INDEX IF NOT EXISTS ix_knj_dnevnik ON pgz_sport.knjizenja(dnevnik_id);
CREATE INDEX IF NOT EXISTS ix_knj_konto ON pgz_sport.knjizenja(konto_id);
CREATE INDEX IF NOT EXISTS ix_knj_partner ON pgz_sport.knjizenja(partner_id);
-- ======================================================================
-- 4) RAČUNI (ulazni/izlazni) + STAVKE
-- ======================================================================
CREATE TABLE IF NOT EXISTS pgz_sport.racuni_ulazni (
id SERIAL PRIMARY KEY,
broj TEXT,
partner_id INTEGER REFERENCES pgz_sport.partneri(id),
klub_id INTEGER REFERENCES pgz_sport.klubovi(id),
datum_izdavanja DATE NOT NULL,
datum_dospjeca DATE,
datum_primitka DATE DEFAULT CURRENT_DATE,
valuta TEXT DEFAULT 'EUR',
iznos_neto NUMERIC(14,2) DEFAULT 0,
iznos_pdv NUMERIC(14,2) DEFAULT 0,
iznos_brutto NUMERIC(14,2) DEFAULT 0,
status TEXT DEFAULT 'nacrt' CHECK (status IN ('nacrt','knjizen','placen','otkazan')),
napomena TEXT,
eracun_xml TEXT,
dnevnik_id INTEGER REFERENCES pgz_sport.dnevnik_zapisa(id),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_racu_status ON pgz_sport.racuni_ulazni(status);
CREATE INDEX IF NOT EXISTS ix_racu_partner ON pgz_sport.racuni_ulazni(partner_id);
CREATE INDEX IF NOT EXISTS ix_racu_datum ON pgz_sport.racuni_ulazni(datum_izdavanja);
CREATE TABLE IF NOT EXISTS pgz_sport.racuni_izlazni (
id SERIAL PRIMARY KEY,
broj TEXT,
partner_id INTEGER REFERENCES pgz_sport.partneri(id),
klub_id INTEGER REFERENCES pgz_sport.klubovi(id),
datum_izdavanja DATE NOT NULL,
datum_dospjeca DATE,
valuta TEXT DEFAULT 'EUR',
iznos_neto NUMERIC(14,2) DEFAULT 0,
iznos_pdv NUMERIC(14,2) DEFAULT 0,
iznos_brutto NUMERIC(14,2) DEFAULT 0,
status TEXT DEFAULT 'nacrt' CHECK (status IN ('nacrt','knjizen','placen','otkazan')),
napomena TEXT,
dnevnik_id INTEGER REFERENCES pgz_sport.dnevnik_zapisa(id),
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX IF NOT EXISTS ix_raci_status ON pgz_sport.racuni_izlazni(status);
CREATE INDEX IF NOT EXISTS ix_raci_partner ON pgz_sport.racuni_izlazni(partner_id);
CREATE INDEX IF NOT EXISTS ix_raci_datum ON pgz_sport.racuni_izlazni(datum_izdavanja);
CREATE TABLE IF NOT EXISTS pgz_sport.racun_stavke (
id SERIAL PRIMARY KEY,
racun_tip TEXT NOT NULL CHECK (racun_tip IN ('ulazni','izlazni')),
racun_id INTEGER NOT NULL,
naziv TEXT NOT NULL,
kolicina NUMERIC(12,3) DEFAULT 1,
jed_mjera TEXT DEFAULT 'kom',
cijena_jed NUMERIC(14,4) DEFAULT 0,
popust_pct NUMERIC(5,2) DEFAULT 0,
pdv_pct NUMERIC(5,2) DEFAULT 25,
iznos_neto NUMERIC(14,2) DEFAULT 0,
iznos_pdv NUMERIC(14,2) DEFAULT 0,
iznos_brutto NUMERIC(14,2) DEFAULT 0
);
CREATE INDEX IF NOT EXISTS ix_stavke_racun ON pgz_sport.racun_stavke(racun_tip, racun_id);
-- ======================================================================
-- 5) ZAPOSLENICI + PLAĆE
-- ======================================================================
CREATE TABLE IF NOT EXISTS pgz_sport.zaposlenici (
id SERIAL PRIMARY KEY,
oib CHAR(11) UNIQUE,
ime TEXT NOT NULL,
prezime TEXT NOT NULL,
klub_id INTEGER REFERENCES pgz_sport.klubovi(id),
radno_mjesto TEXT,
plata_bruto NUMERIC(12,2) DEFAULT 0,
iban TEXT,
datum_pocetka DATE,
datum_kraja DATE,
aktivan BOOLEAN DEFAULT true,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE TABLE IF NOT EXISTS pgz_sport.place_obracun (
id SERIAL PRIMARY KEY,
zaposlenik_id INTEGER NOT NULL REFERENCES pgz_sport.zaposlenici(id),
godina INTEGER NOT NULL,
mjesec SMALLINT NOT NULL CHECK (mjesec BETWEEN 1 AND 12),
bruto NUMERIC(12,2) NOT NULL,
osobni_odbitak NUMERIC(12,2) DEFAULT 600,
doprinosi_iz_plate NUMERIC(12,2) DEFAULT 0, -- 20% MIO
porezna_osnovica NUMERIC(12,2) DEFAULT 0,
dohodnina NUMERIC(12,2) DEFAULT 0,
prirez NUMERIC(12,2) DEFAULT 0,
neto NUMERIC(12,2) DEFAULT 0,
doprinosi_na_plate NUMERIC(12,2) DEFAULT 0, -- 16.5% zdravstveno
ukupni_trosak NUMERIC(12,2) DEFAULT 0,
datum_isplate DATE,
dnevnik_id INTEGER REFERENCES pgz_sport.dnevnik_zapisa(id),
created_at TIMESTAMPTZ DEFAULT now(),
UNIQUE(zaposlenik_id, godina, mjesec)
);
-- ======================================================================
-- 6) VIEWS
-- ======================================================================
CREATE OR REPLACE VIEW pgz_sport.v_glavna_knjiga AS
SELECT k.konto_id, kp.sifra, kp.naziv, kp.klasa, kp.vrsta,
SUM(k.duguje) AS sum_duguje,
SUM(k.potrazuje) AS sum_potrazuje,
SUM(k.duguje) - SUM(k.potrazuje) AS saldo,
COUNT(*) AS broj_stavki
FROM pgz_sport.knjizenja k
JOIN pgz_sport.kontni_plan kp ON kp.id = k.konto_id
GROUP BY k.konto_id, kp.sifra, kp.naziv, kp.klasa, kp.vrsta
ORDER BY kp.sifra;
CREATE OR REPLACE VIEW pgz_sport.v_partner_saldo AS
SELECT p.id AS partner_id, p.naziv, p.oib, p.vrsta,
COALESCE(SUM(k.duguje),0) AS uk_duguje,
COALESCE(SUM(k.potrazuje),0) AS uk_potrazuje,
COALESCE(SUM(k.duguje),0) - COALESCE(SUM(k.potrazuje),0) AS saldo
FROM pgz_sport.partneri p
LEFT JOIN pgz_sport.knjizenja k ON k.partner_id = p.id
GROUP BY p.id, p.naziv, p.oib, p.vrsta;
CREATE OR REPLACE VIEW pgz_sport.v_pdv_ulazni AS
SELECT r.id, r.broj, r.datum_izdavanja, r.datum_primitka,
p.naziv AS partner_naziv, p.oib AS partner_oib,
r.iznos_neto, r.iznos_pdv, r.iznos_brutto, r.status
FROM pgz_sport.racuni_ulazni r
LEFT JOIN pgz_sport.partneri p ON p.id = r.partner_id
WHERE r.status IN ('knjizen','placen');
CREATE OR REPLACE VIEW pgz_sport.v_pdv_izlazni AS
SELECT r.id, r.broj, r.datum_izdavanja,
p.naziv AS partner_naziv, p.oib AS partner_oib,
r.iznos_neto, r.iznos_pdv, r.iznos_brutto, r.status
FROM pgz_sport.racuni_izlazni r
LEFT JOIN pgz_sport.partneri p ON p.id = r.partner_id
WHERE r.status IN ('knjizen','placen');
CREATE OR REPLACE VIEW pgz_sport.v_bilanca AS
SELECT kp.klasa, kp.vrsta, kp.sifra, kp.naziv,
COALESCE(SUM(k.duguje),0) AS duguje,
COALESCE(SUM(k.potrazuje),0) AS potrazuje,
COALESCE(SUM(k.duguje),0) - COALESCE(SUM(k.potrazuje),0) AS saldo
FROM pgz_sport.kontni_plan kp
LEFT JOIN pgz_sport.knjizenja k ON k.konto_id = kp.id
WHERE kp.vrsta IN ('aktiva','pasiva','kapital')
GROUP BY kp.klasa, kp.vrsta, kp.sifra, kp.naziv
ORDER BY kp.sifra;
CREATE OR REPLACE VIEW pgz_sport.v_pnl AS
SELECT kp.klasa, kp.vrsta, kp.sifra, kp.naziv,
COALESCE(SUM(k.duguje),0) AS duguje,
COALESCE(SUM(k.potrazuje),0) AS potrazuje,
CASE WHEN kp.vrsta='prihod'
THEN COALESCE(SUM(k.potrazuje),0) - COALESCE(SUM(k.duguje),0)
ELSE COALESCE(SUM(k.duguje),0) - COALESCE(SUM(k.potrazuje),0)
END AS iznos
FROM pgz_sport.kontni_plan kp
LEFT JOIN pgz_sport.knjizenja k ON k.konto_id = kp.id
WHERE kp.vrsta IN ('prihod','rashod')
GROUP BY kp.klasa, kp.vrsta, kp.sifra, kp.naziv
ORDER BY kp.sifra;
-- ======================================================================
-- 7) SEED HR-RRIF kontni plan (skraćeni okvirni, ~80 konta)
-- ======================================================================
INSERT INTO pgz_sport.kontni_plan (sifra, naziv, klasa, vrsta) VALUES
-- KLASA 0 — Dugotrajna imovina
('00','DUGOTRAJNA NEMATERIJALNA IMOVINA',0,'aktiva'),
('001','Izdaci za razvoj',0,'aktiva'),
('002','Koncesije, patenti, licencije',0,'aktiva'),
('003','Software',0,'aktiva'),
('01','DUGOTRAJNA MATERIJALNA IMOVINA',0,'aktiva'),
('010','Zemljišta',0,'aktiva'),
('011','Građevinski objekti',0,'aktiva'),
('012','Postrojenja i oprema',0,'aktiva'),
('013','Alati, pogonski inventar',0,'aktiva'),
('014','Transportna sredstva',0,'aktiva'),
('029','Ispravak vrijednosti DI',0,'aktiva'),
-- KLASA 1 — Novac, potraživanja, financijska imovina
('10','NOVAC U BANCI I BLAGAJNI',1,'aktiva'),
('100','Blagajna - kuna/euro',1,'aktiva'),
('1000','Glavna blagajna',1,'aktiva'),
('101','Žiro-račun',1,'aktiva'),
('1010','Žiro-račun HRK/EUR',1,'aktiva'),
('102','Devizni račun',1,'aktiva'),
('12','POTRAŽIVANJA OD KUPACA',1,'aktiva'),
('120','Potraživanja od kupaca u zemlji',1,'aktiva'),
('1200','Kupci u zemlji - domaće osobe',1,'aktiva'),
('121','Potraživanja od kupaca u inozemstvu',1,'aktiva'),
('13','POTRAŽIVANJA OD ZAPOSLENIH',1,'aktiva'),
('130','Predujmovi za putne troškove',1,'aktiva'),
('14','POTRAŽIVANJA ZA PDV',1,'aktiva'),
('1400','Pretporez',1,'aktiva'),
('15','POTRAŽIVANJA ZA SUFINANCIRANJE',1,'aktiva'),
('1500','Potraživanja od PGŽ',1,'aktiva'),
('1501','Potraživanja od HOO/Ministarstva',1,'aktiva'),
-- KLASA 2 — Obveze
('22','OBVEZE PREMA DOBAVLJAČIMA',2,'pasiva'),
('220','Dobavljači u zemlji',2,'pasiva'),
('2200','Dobavljači - domaće osobe',2,'pasiva'),
('221','Dobavljači u inozemstvu',2,'pasiva'),
('23','KRATKOROČNE OBVEZE PO KREDITIMA',2,'pasiva'),
('24','OBVEZE PREMA ZAPOSLENIMA',2,'pasiva'),
('240','Obveze za neto plaće',2,'pasiva'),
('241','Obveze za doprinose iz plaća',2,'pasiva'),
('242','Obveze za dohodninu',2,'pasiva'),
('243','Obveze za prirez',2,'pasiva'),
('244','Obveze za doprinose na plaće',2,'pasiva'),
('25','OBVEZE ZA PDV',2,'pasiva'),
('2500','Porez na dodanu vrijednost',2,'pasiva'),
-- KLASA 3 — Zalihe
('30','ZALIHE SIROVINA I MATERIJALA',3,'aktiva'),
('31','ZALIHE TRGOVAČKE ROBE',3,'aktiva'),
-- KLASA 4 — Rashodi
('40','MATERIJALNI TROŠKOVI',4,'rashod'),
('400','Utrošeni materijal',4,'rashod'),
('401','Energija',4,'rashod'),
('402','Sitan inventar',4,'rashod'),
('41','TROŠKOVI USLUGA',4,'rashod'),
('410','Usluge prijevoza',4,'rashod'),
('411','Usluge održavanja',4,'rashod'),
('412','Najamnine',4,'rashod'),
('413','Komunalne usluge',4,'rashod'),
('414','Telekomunikacije',4,'rashod'),
('415','Sudske takse, javnobilježničke usluge',4,'rashod'),
('42','PLAĆE I NAKNADE',4,'rashod'),
('420','Bruto plaće',4,'rashod'),
('421','Doprinosi na plaće',4,'rashod'),
('422','Naknade volonterima',4,'rashod'),
('423','Putni troškovi - dnevnice',4,'rashod'),
('424','Putni troškovi - prijevoz',4,'rashod'),
('43','AMORTIZACIJA',4,'rashod'),
('430','Amortizacija DMI',4,'rashod'),
('44','OSTALI TROŠKOVI POSLOVANJA',4,'rashod'),
('440','Reprezentacija',4,'rashod'),
('441','Reklama i promidžba',4,'rashod'),
('442','Članarine savezima',4,'rashod'),
('443','Kotizacije i natjecanja',4,'rashod'),
('444','Sportska oprema',4,'rashod'),
('445','Liječnički pregledi',4,'rashod'),
('446','Suđenja, suci',4,'rashod'),
-- KLASA 7 — Prihodi (preskačemo 5,6 — manje korišteni za neprofit)
('70','PRIHODI OD ČLANARINA',7,'prihod'),
('700','Članarine članova',7,'prihod'),
('71','PRIHODI OD SUFINANCIRANJA',7,'prihod'),
('710','Sufinanciranje PGŽ',7,'prihod'),
('711','Sufinanciranje Ministarstva',7,'prihod'),
('712','Sufinanciranje HOO/HOK',7,'prihod'),
('713','Sufinanciranje grad/općina',7,'prihod'),
('72','PRIHODI OD DONACIJA',7,'prihod'),
('720','Donacije od pravnih osoba',7,'prihod'),
('721','Donacije od fizičkih osoba',7,'prihod'),
('73','PRIHODI OD KOTIZACIJA',7,'prihod'),
('730','Kotizacije za natjecanja',7,'prihod'),
('74','OSTALI POSLOVNI PRIHODI',7,'prihod'),
('740','Sponzorstva',7,'prihod'),
('741','Naplata reklamnog prostora',7,'prihod'),
-- KLASA 9 — Kapital
('90','VLASTITI IZVORI',9,'kapital'),
('900','Temeljni kapital',9,'kapital'),
('91','REZERVE',9,'kapital'),
('92','REZULTAT POSLOVANJA',9,'kapital'),
('920','Višak prihoda nad rashodima',9,'kapital'),
('921','Manjak prihoda nad rashodima',9,'kapital')
ON CONFLICT (sifra) DO NOTHING;