=== Canis Price Complience HR ===
Contributors: canisliberi
Tags: cjenik, cijene, csv, xml, hrvatska
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 8.0
Stable tag: 0.7.0
License: GPLv2 or later

Standalone WordPress plugin za vođenje, prikaz, povijest i strojno čitljivu objavu cjenika proizvoda i usluga.

== Description ==

Canis Price Complience HR pruža:
* rad bez WooCommercea
* proizvode i usluge te više prodajnih/uslužnih lokacija
* ručni unos, uređivanje, pretragu, filtre i bulk promjene
* za proizvode: količinu pakiranja i automatski izračun cijene za jedinicu mjere (npr. €/kg, €/l), uz opciju "nije primjenjiva"
* za usluge: jednostavan model naziv + količina + jedinica + cijena
* sidrenu/referentnu cijenu, datum na koji se cijena odnosi i napomenu
* evidenciju svake promjene maloprodajne cijene
* automatski izračun najniže cijene u prethodnih 30 dana pri početku posebnog oblika prodaje
* upozorenje ako akcijska cijena nije niža od spremljene 30-dnevne reference ili nema dovoljno povijesti
* CSV/XML import s mapiranjem polja
* CSV/XML export s brojem pohrane/batcha po lokaciji
* zasebne ON/OFF postavke automatske objave nakon promjene proizvoda i usluga (proizvodi zadano OFF, usluge zadano ON)
* opcionalni interni dnevni WP-Cron u 07:30 te zaštićeni server-cron endpoint
* glavni ON/OFF prekidač javnog digitalnog cjenika koji zajedno zaustavlja stranicu, API, javni download/arhivu i automatsko generiranje
* zaseban ON/OFF modul sidrenih cijena bez brisanja spremljenih podataka; najniža cijena prethodnih 30 dana ostaje neovisna
* javnu arhivu cjenika najmanje 30 dana (zadano 35), grupiranu po batchu s CSV/XML linkovima
* ručno brisanje cijelog export batcha uz dodatnu potvrdu za cjenike mlađe od 30 dana i zaštitu od ostavljanja lokacije bez potpunog cjenika
* javni REST API /wp-json/cpchr/v1/cjenik
* opcionalnu samostalnu minimalističku stranicu Digitalni cjenik na željenom URL slugu
* opcionalni link za povratak na vrhu minimalističkog cjenika, s početnom stranicom ili prilagođenim URL-om kao ciljem
* stabilne linkove aktualni.csv / aktualni.xml te javne arhivske linkove
* shortcode [canis_cjenik] za klasični prikaz unutar WordPress teme
* opcionalno potpuno uklanjanje podataka pri deinstalaciji, zadano isključeno
* audit log i zasebnu administratorsku Povijest cijena
* obvezno prihvaćanje izjave o odgovornosti prije javnog generiranja


== Količine i jedinice mjere ==

Za proizvod se unose količina pakiranja (npr. 750) i jedinica pakiranja (npr. g), a plugin iz maloprodajne cijene automatski izračunava usporedivu cijenu za baznu jedinicu, npr. €/kg ili €/l. Podržane su uobičajene jedinice mase, volumena, duljine, površine, obujma i komadi. Ako cijena za jedinicu mjere nije primjenjiva, administrator to izričito označava checkboxom; tada se usporediva cijena ne računa niti objavljuje.

Za uslugu se unose naziv, količina, jedinica i cijena (npr. Pranje tepiha, 1, m², 8,00 €). Kod usluga se ne vodi dodatno polje "cijena jedinice" jer se cijena odnosi na unesenu količinu i jedinicu.

CSV/XML import podržava nova polja `kolicina`, `jedinica_kolicine` i `cijena_jedinice_nije_primjenjiva`, ali ostaje kompatibilan sa starim `unit` / `unit_price` formatom.

Sidrena cijena ima zaseban datum `datum_sidrene_cijene`. Importer automatski prepoznaje datum iz zaglavlja poput `SIDRENA CIJENA NA 2.5.2025` ili može mapirati zaseban stupac datuma. Ako se sidrena cijena uveze bez datuma, koristi se 10.09.2026. kao zadana vrijednost, ali zapis ostaje označen kao nepotvrđen dok ga administrator ne pregleda.

== Dnevna objava ==

Plugin može zakazati dnevno generiranje u 07:30 prema WordPress vremenskoj zoni. Interni WP-Cron može se uključiti ili isključiti u Canis Cjenik > Automatizacija. WP-Cron ovisi o tome da WordPress cron bude pokrenut i sam po sebi ne jamči izvršavanje prije određenog roka. Za produkciju se može koristiti pravi server cron koji izravno poziva zaštićeni endpoint oko 07:30 (tada interni plugin cron može biti isključen) ili cPanel koji periodički pokreće wp-cron.php (tada interni plugin cron mora ostati uključen).

Dashboard posebno provjerava postoji li za svaku aktivnu lokaciju potpuni CSV/XML batch evidentiran do 08:00 te nakon 08:00 prikazuje upozorenje ako takva objava nedostaje.

== Posebni oblici prodaje i 30-dnevna cijena ==

Sidrena/referentna cijena i najniža cijena prethodnih 30 dana odvojeni su podaci.

Pri prvom uključivanju posebnog oblika prodaje na postojećoj stavci plugin iz povijesti maloprodajnih cijena izračunava najnižu cijenu koja je bila primjenjivana tijekom 30 dana prije početka posebnog oblika prodaje i sprema je uz tu akciju. Nova akcijska cijena nakon toga ulazi u povijest.

Ako nema dovoljno zabilježene povijesti ili unesena akcijska cijena nije niža od izračunate reference, plugin prikazuje upozorenje. Upozorenje nije zamjena za provjeru zakonskih iznimki i specifičnih okolnosti proizvoda/usluge.

== Javna stranica ==

Opcija “Aktiviraj javni digitalni cjenik” glavni je prekidač javne objave. Kad je isključena, upravljana stranica prelazi u draft, REST API se ne registrira, javne CSV/XML download i arhivske rute nisu dostupne, interni dnevni WP-Cron događaj se uklanja, a server-cron i automatska objava nakon promjena ne stvaraju nove cjenike. Podaci, povijest i postojeća arhiva se ne brišu.

Sidrene cijene imaju zaseban ON/OFF modul. Kad je isključen, sidrena cijena/datum/napomena ne prikazuju se u shortcodeu i REST API-ju te ne ulaze u nove CSV/XML datoteke. Najniža cijena prethodnih 30 dana ostaje neovisna funkcija. Već objavljene povijesne datoteke ne mijenjaju se retroaktivno.

Kada je uključen samostalni prikaz, upravljana stranica ne koristi temu nego prikazuje minimalistički Digitalni cjenik s:
* linkom na aktualni CSV i XML po lokaciji
* datumom i vremenom posljednje objave
* linkom na javni API
* arhivom grupiranom po jednoj objavi/batchu, s CSV i XML linkom u istom retku

Kod jedne aktivne lokacije dostupan je i /<slug>/aktualni.csv odnosno /<slug>/aktualni.xml. Kod više lokacija aktualni link sadrži oznaku lokacije.

Opcija “Link za povratak” zadano je isključena. Kada se uključi, na vrhu samostalnog minimalističkog prikaza može voditi na početnu stranicu weba ili na administratorski definirani HTTP/HTTPS URL. Ne utječe na shortcode prikaz unutar WordPress teme.

== Sigurnost ==

* administrativne promjene zahtijevaju manage_options i WordPress nonce
* brisanje i bulk promjene koriste POST
* ulazi se sanitiziraju, a HTML izlaz escapira
* dinamički SQL parametri koriste $wpdb->prepare()
* CSV/XML import ograničen je na 5 MB i 50.000 redaka
* import koristi jednokratni token vezan uz administratora i privremenu datoteku
* XML s DOCTYPE ili ENTITY deklaracijama odbija se
* CSV export neutralizira spreadsheet formula injection u tekstualnim ćelijama
* cron koristi kriptografski nasumičan token i lock protiv paralelnog izvoza
* download handler provjerava da se datoteka nalazi unutar vlastitog export direktorija
* cleanup arhive može brisati samo datoteke iz vlastitog export direktorija
* mutacije i exporti bilježe se u audit log

== Važna pravna napomena / Disclaimer ==

Canis Price Complience HR je tehnički alat za evidenciju, prikaz i izvoz cjenika. Plugin nije pravni savjet i ne jamči sam po sebi potpunu usklađenost poslovanja korisnika s važećim propisima.

Korisnik je odgovoran za utvrđivanje primjenjuju li se pojedine obveze na njegovo poslovanje, za točnost i potpunost podataka, pravilnu klasifikaciju posebnih oblika prodaje, ispravnost sidrenih/referentnih cijena i povijesnih podataka, referentne datume, dostupnost, rokove objave te praćenje izmjena zakona, odluka, pravilnika i službenih tumačenja.

Autor i distributer plugina ne preuzima odgovornost za pogrešne ili nepotpune podatke koje unese ili uveze korisnik, nedostajuću povijest prije instalacije plugina, prekide web-poslužitelja ili WordPressa, neizvršavanje WP-Cron zadataka, promjene propisa nakon izdavanja verzije plugina niti za odluke nadležnih tijela.

== Installation ==

1. Uploadajte ZIP kroz Plugins > Add New > Upload Plugin.
2. Aktivirajte plugin.
3. Otvorite Canis Cjenik > Odgovornost i prihvatite izjavu.
4. Dodajte lokaciju te stavke ili napravite import.
5. U Canis Cjenik > Javna stranica uključite Digitalni cjenik i postavite željeni URL slug.
6. U Canis Cjenik > Automatizacija odaberite interni WP-Cron i pravila auto-objave; u Sigurnost je dostupan zaštićeni server-cron URL.
7. Provjeravajte Dashboard, Povijest cijena i Arhivu.

== Changelog ==

= 0.7.0 =
* Dodan glavni prekidač “Aktiviraj javni digitalni cjenik”. Isključivanje zaustavlja upravljanu javnu stranicu, REST API, javne download/arhivske rute, interni dnevni cron i automatsko generiranje nakon promjena, bez brisanja podataka ili arhive.
* Zaštićeni server-cron endpoint pri isključenoj javnoj objavi vraća status da je objava onemogućena i ne generira nove cjenike.
* Interni WP-Cron raspored automatski se uklanja kada je javna objava isključena i vraća kada se ponovno uključi, ako je njegova postavka aktivna.
* Dodan zaseban ON/OFF modul sidrenih cijena. Isključivanje skriva sidrenu cijenu/datum/napomenu iz shortcodea i REST API-ja te ih izostavlja iz novih CSV/XML datoteka, ali podatke ne briše.
* Najniža cijena prethodnih 30 dana ostaje potpuno neovisna o modulu sidrenih cijena.
* Zaglavlje shortcode tablice sada glasi “Sidrena cijena”, dok pojedinačni redovi i dalje prikazuju “Cijena na dan DD.MM.GGGG. – xx,xx €”.
* Ručni administratorski export ostaje moguć i kad je javna objava isključena; takve datoteke nisu javno dostupne dok se javni digitalni cjenik ponovno ne uključi.
* Dodatno je blokiran izravni HTTP pristup export direktoriju na Apache/LiteSpeed poslužiteljima; javne datoteke poslužuju se kroz provjerene WordPress rute.

= 0.6.1 =
* Dodana opcija za prikaz linka za povratak na vrhu samostalnog minimalističkog cjenika.
* Link je zadano isključen; administrator može definirati tekst i odabrati početnu stranicu ili prilagođeni HTTP/HTTPS URL.
* Opcija ne mijenja shortcode prikaz, CSV/XML, REST API, importer ni cron logiku.

= 0.6.0 =
* Dodan zaseban datum sidrene/referentne cijene po stavci.
* Postojećim stavkama sa sidrenom cijenom pri nadogradnji se dodjeljuje 10.09.2026. kao zadani datum, ali ostaju označene kao nepotvrđene.
* Dodan administratorski filter “Datum sidrene nije potvrđen” i trajno upozorenje dok postoje nepotvrđene stavke.
* Dodane bulk akcije za postavljanje i potvrdu datuma 10.09.2026. ili 02.05.2025.
* Importer mapira zaseban datum sidrene cijene i automatski ga izvodi iz zaglavlja poput `SIDRENA CIJENA NA 2.5.2025`.
* CSV/XML export uključuje `datum_sidrene_cijene`, a javni REST API `anchor_price_date`.
* Shortcode i prikaz unutar WordPress teme umjesto generičkog naziva “Sidrena cijena” prikazuju npr. “Cijena na dan 10.09.2026. – 12,99 €”.
* Ispravljena struktura ZIP paketa: unutarnja mapa ostaje `canis-price-complience-hr/` kako bi WordPress prepoznao nadogradnju.

= 0.5.0 =
* Dodan zaseban tab Automatizacija.
* Interni dnevni WP-Cron u 07:30 sada se može uključiti/isključiti.
* Dodane zasebne postavke automatske objave nakon promjene proizvoda i usluga; proizvodi su zadano OFF, usluge zadano ON.
* Promjene lokacije i postavki javne stranice više same ne stvaraju novi export batch.
* Javna i administratorska arhiva grupiraju CSV i XML istog batcha u jedan red.
* Aktualni CSV i XML uvijek se poslužuju iz istog posljednjeg potpunog batcha.
* Dodano ručno brisanje cijelog batcha (CSV + XML zajedno).
* Za batch mlađi od 30 dana potrebno je upisati OBRIŠI nakon upozorenja.
* Brisanje je blokirano ako bi lokacija ostala bez ijednog drugog potpunog CSV/XML cjenika.
* Ručno brisanje batcha evidentira se u audit logu.
* Import izvještaj sada bilježi tipove uvezenih stavki kako bi auto-objava po tipu radila i kod mješovitih importa.
* Stari export zapisi s batch brojem 0 pri nadogradnji dobivaju odvojene batch brojeve kako se povijest ne bi pogrešno grupirala.

= 0.4.1 =
* Ispravljen import količina koje u istom polju sadrže broj i jedinicu, npr. `0.15 kg`, `750 g` ili `1,5 l`.
* Ako NETO KOLIČINA sadrži jedinicu, ona ima prednost pred zasebnom prodajnom oznakom poput `ko`.
* Oznaka `ko` prepoznaje se kao `kom` kada se koristi kao jedinica.
* Poboljšano automatsko mapiranje hrvatskih zaglavlja poput NAZIV PROIZVODA, ŠIFRA PROIZVODA, NETO KOLIČINA, CIJENA ZA JEDINICU MJERE i SIDRENA CIJENA NA datum.
* Dodano mapiranje najniže cijene prethodnih 30 dana iz vanjskog cjenika.
* Import sada prikazuje broj obrađenih, uvezenih i preskočenih redaka te grupirane razloge i primjere pogrešnih redaka.
* Ako obvezna polja Naziv ili Cijena nisu mapirana, import se zaustavlja s jasnom porukom umjesto rezultata 0.

= 0.4.0 =
* Razdvojen unos proizvoda i usluga prema vrsti stavke.
* Proizvodi sada imaju količinu pakiranja i jedinicu pakiranja; cijena za jedinicu mjere računa se automatski.
* Dodan checkbox "Cijena za jedinicu mjere nije primjenjiva" samo za proizvode.
* Usluge sada koriste model naziv + količina + jedinica + cijena bez zasebnog polja cijene jedinice.
* Bulk promjena maloprodajne cijene automatski preračunava cijenu za jedinicu mjere proizvoda.
* CSV/XML export i REST API prošireni su količinom, jedinicom količine i statusom primjenjivosti jedinične cijene.
* Import mapper podržava novi format i zadržava kompatibilnost sa starim poljima.
* Nadogradnja sa 0.3.x čuva postojeće podatke i pokušava migrirati postojeće mjerne podatke bez brisanja stavki.

= 0.3.1 =
* Ispravljen pojedinačni gumb Obriši u popisu stavki.
* Dodana opcija "Obriši sve podatke pri deinstalaciji", zadano isključena.
* Kada je opcija uključena, uninstall čisti vlastite tablice, postavke, export/arhivu, privremene import datoteke i upravljanu javnu stranicu.

= 0.3.0 =
* Dodana zasebna tablica povijesti maloprodajnih cijena.
* Dodan automatski izračun najniže cijene prethodnih 30 dana pri početku posebnog oblika prodaje.
* Dodani datum početka akcije i spremljena 30-dnevna referentna cijena.
* Dodana upozorenja za nedostajuću povijest i potencijalno neodgovarajuću akcijsku cijenu.
* Dodan administratorski pregled Povijest cijena.
* Export sada uključuje najnižu cijenu 30 dana i početak posebne prodaje.
* Dodan sekvencijski broj pohrane/batcha u naziv export datoteke.
* Dodan javni REST API.
* Dodani stabilni javni linkovi aktualni.csv / aktualni.xml i arhivske rute.
* Upravljana javna stranica može biti samostalni minimalistički Digitalni cjenik bez WordPress teme.
* Nakon promjene stavke, bulk promjene, importa ili relevantne lokacijske promjene automatski se generira nova objava.
* Dashboard provjerava postoji li potpuni dnevni CSV/XML batch do 08:00.
* U bazi je rezervirano polje base_price za buduća pravila bez potrebe za redizajnom tablice.

= 0.2.2 =
* Dodani javni linkovi aktualnog CSV/XML cjenika i javna arhiva najmanje 30 dana.

= 0.2.1 =
* Dodano automatsko kreiranje WordPress stranice cjenika sa željenim slugom.

= 0.2.0 =
* Dodani pretraga, filteri, bulk akcije, uređivanje lokacija i sigurnosna poboljšanja.

= 0.1.1 =
* Dodano uređivanje i soft-brisanje stavki.

= 0.1.0 =
* Početna MVP verzija.
