=== Aplitap Sidrena Cijena i Cjenik ===
Contributors: aplitap
Tags: sidrena cijena, sidrene cijene, cijena, cjenik, cjenik csv
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 2.7.10
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Adds legally required reference prices and a machine-readable price list to your Croatian website — mandatory from 1 October 2026.

== Description ==

As of October 1, 2026, merchants and service providers in Croatia with their own website are required to, among other things:

* display a "reference price" (sidrena cijena) alongside the regular selling price of each product - the price that applied on 10.09.2026,
* publish a machine-readable price list ("cjenik") of their products and/or services (in XML or CSV format) on their website.

This free plugin helps websites comply with both obligations, without any code changes or manual template editing. The reference price feature requires WooCommerce; the price list also works for service providers without WooCommerce, via a manual list or CSV import.

= Reference price ("Sidrena cijena") =

* A field to enter the reference price on each product, and separately per variation for variable products
* Automatic display below the regular price everywhere WooCommerce shows a product price (product page, shop, categories, related/upsell products, widgets)
* Quick Edit support
* Global switch to turn the display on or off
* Customizable label text, font (family, weight, style, size, color), with separate font sizes for mobile and desktop

= Price list ("Cjenik") =

* Automatically generates an XML and/or CSV price list with the data required by the Decision: name, product code, brand, unit of measure, price per unit, retail price, name of any special sale form, reference price, barcode, availability
* Services get their own, separate price list document with just the fields the Decision requires for services (name, price, name of any special sale form, reference price) - not mixed in with the product price list
* Includes variations of variable products as separate line items
* Automatically excludes products that are not visible on the website (with a manual override to include or exclude any individual product)
* Regenerates daily before 8:00 (configurable time), and immediately whenever any product's price changes
* Archived, timestamped files are kept for at least 30 days (configurable), with a searchable archive list and one-click downloads in the admin
* Configurable CSV delimiter, email notification if generation fails
* Data preview tables inside the admin screen (products and services shown separately), before downloading the file
* Optional `[aplitap_cjenik]` / `[aplitap_cjenik_usluge]` shortcodes for a styled, human-readable price list page for your customers, alongside the required XML/CSV files
* Optional `[aplitap_cjenik_arhiva]` shortcode to publicly list every archived (30+ day) version with its generation date and a download link
* Works without WooCommerce too - manually add products and/or services in their own separate tables (each on its matching admin tab, with the right fields), with bulk select/delete and a "delete all" option, or bulk-import them from a CSV file
* Optional support for multiple business locations - define your locations once, assign manually entered rows to a specific one, and each location gets its own price list document with its own address, alongside the shared one

**Note**: The Decision on publishing price lists (NN 101/2026) specifies which data the price list must contain, but does not prescribe an exact CSV column order or XML schema. This plugin is a technical aid based on a publicly available interpretation of the regulation - we recommend checking with your accountant or lawyer for your specific situation.

= Requirements =

* WordPress
* PHP 7.4 or newer
* WooCommerce is only required for the reference price feature and for pulling products automatically into the price list. Without WooCommerce, the price list still works via manual entry or CSV import.

== Installation ==

1. Download the plugin zip file
2. In your WordPress admin, go to Plugins → Add New Plugin
3. Click Upload Plugin, select the downloaded zip file, click Install Now
4. After installation, click Activate Plugin
5. A new menu item "Sidrena cijena Aplitap" will appear in the left sidebar, with tabs for the reference price, the price list, and information about Aplitap
6. For each product (Products → edit product → General tab) enter the reference price; for the price list, set your outlet label under the price list tab

== Frequently Asked Questions ==

= Does the plugin work without WooCommerce? =

Partially. The reference price feature requires an active WooCommerce installation, since it displays alongside WooCommerce product prices. The price list ("Cjenik") works without WooCommerce too - add products and/or services manually in the tables on the "Proizvodi"/"Usluge" tabs, or import them from a CSV file. If both WooCommerce products and manually entered items are present, both are included.

= Do I need to enter the reference price manually for every product? =

Yes, it is entered manually per product (or per variation for variable products), since WordPress/WooCommerce does not keep a price history by default.

= Does it work with variable products? =

Yes - both the reference price and the price list support separate values per variation.

= Can I exclude a specific product from the price list? =

Yes - on each product (and in Quick Edit) there is a "Price list visibility" dropdown with the options Automatic / Always include / Always exclude.

= Where is the price list published? =

Files are saved under wp-content/uploads/cjenik-proizvodi/ (products) and wp-content/uploads/cjenik-usluga/ (services), and must be publicly accessible - please make sure a security plugin, firewall, or Cloudflare is not blocking automated tools from reading them. The direct links to the current CSV/XML files are shown on the price list settings tab.

= Can I show the price list to customers as a normal web page, not just a raw file? =

Yes. The regulation itself only requires the machine-readable XML/CSV files, but you can add the `[aplitap_cjenik]` shortcode (products) and/or `[aplitap_cjenik_usluge]` shortcode (services) to any WordPress page for a styled, human-readable table with the same data - useful if you want to link to it from your menu or footer for visitors, not just for automated tools.

= Is this legal advice? =

No. The plugin is a technical aid based on a publicly available interpretation of the Decision on publishing price lists (NN 101/2026). We recommend checking with an accountant or lawyer before 1.10.2026.

= Can I translate the plugin's text into another language? =

Yes - all of the plugin's text is translation-ready and works with [Loco Translate](https://wordpress.org/plugins/loco-translate/) (or any other .po/.mo-based translation tool). Open Loco Translate, find "Aplitap Sidrena Cijena i Cjenik" under Plugins, and start a new language - it will scan the plugin automatically.

== Screenshots ==

1. Settings - reference price tab, with live preview
2. Settings - price list tab, with the data preview table
3. Reference price displayed on the product page

== Changelog ==

= 2.7.10 =
* Fixed the reference price not showing on Cart/Checkout when the site uses WooCommerce's newer block-based Cart/Checkout (the Cart and Checkout blocks) rather than the classic shortcode pages - the previous fix (2.7.3) only worked on the classic pages, since the block-based cart reads product data through a completely different mechanism (the Store API) that never called our old hook. It now shows next to the product name, in the same place variation details like size/color normally appear, and works on both the classic and block-based cart/checkout

= 2.7.9 =
* Fixed selecting "Ostalo (upišite)" for Jedinica mjere in Quick Edit not revealing the free-text field - the change handler was bound directly to the dropdown, which could lose its listener when WordPress repositioned the field; now bound as a delegated handler so it works reliably regardless of when/how the row gets rebuilt

= 2.7.8 =
* Fixed the "Upišite jedinicu mjere" field in Quick Edit always showing, even when "Ostalo" wasn't selected - WooCommerce's own Quick Edit styling was overriding the CSS class we used to hide it, so it looked active (and made it seem like typing there "did nothing") when the dropdown was actually still set to a normal unit like "kom"

= 2.7.7 =
* Quick Edit on the products list now groups all Sidrena cijena i Cjenik fields together in one labeled block, matching the box on the product edit screen - and added the two fields that were missing from Quick Edit: "Vrijedi na dan" (reference date) and "Jedinica mjere" (with the same "Ostalo" free-text option), plus "Akcija" (special sale form name)

= 2.7.6 =
* The "Sidrena cijena (...)" field label in the "Sidrena cijena i Cjenik" box now shows the actual date that applies to that specific product, instead of always showing the fixed 10.09.2026 law date
* Added a "Šifra proizvoda (SKU)" field to the "Sidrena cijena i Cjenik" box, mirroring the SKU field from the Inventory tab - editing it in either place updates both
* "Naziv posebnog oblika prodaje" field relabeled to "Naziv posebnog oblika prodaje (Akcija)" so it's clearer what it's for
* "Jedinica mjere" now has an "Ostalo (upišite)" option that reveals a free-text field, for units not on the built-in list

= 2.7.5 =
* Added an optional "Sidrena cijena vrijedi na dan" date field (in the "Sidrena cijena i Cjenik" box) to manually set the date shown in the reference price label, for cases where the automatic date (the legal date, or the product's creation date) isn't what you want. Leave it empty and nothing changes - the automatic date is still used

= 2.7.4 =
* All product fields related to the reference price and price list (reference price, barcode, unit of measure, special sale form name, price list visibility override) are now grouped together in a single "Sidrena cijena i Cjenik" box in the sidebar of the product edit screen, instead of being spread across the Pricing and Inventory tabs
* Added the barcode field to Quick Edit on the products list, next to the existing reference price field

= 2.7.3 =
* The reference price label now shows the actual date it applies to instead of always saying 10.09.2026: for a product created after that date, it shows that product's own creation date instead (e.g. a product created 27.09.2026 now says "Sidrena cijena na dan 27.09.2026." instead of the fixed law date, since the reference price for a product that didn't exist on 10.09.2026 is naturally the price on the day it was created)
* The reference price now also appears on the Cart and Checkout pages, not just the product/shop pages - previously it was missing there because WooCommerce builds those two pages' prices in a different way that bypassed our display code entirely

= 2.7.2 =
* Fixed Quick Edit on the products list: editing the reference price for one product, then Quick-Editing another without a full page reload, could duplicate the reference price field many times over and silently fail to save the new value. WooCommerce re-adds the field on every Quick Edit click without removing the previous copy once it had been repositioned - now only the newest copy is kept each time

= 2.7.1 =
* Fixed missing barcodes for product variations in the price list. Our own barcode field only ever existed on the main product, not on each variation, so a variation without its own value now falls back to WooCommerce's own built-in "GTIN, UPC, EAN or ISBN" field, which does support per-variation values and is what most stores actually use
* A variation without its own "Jedinica mjere" (unit of measure) now inherits the main product's setting, instead of always defaulting to "kom"
* Added "par" (pair) as a unit of measure option, for products commonly sold in pairs (speakers, shoes, gloves, etc.)

= 2.7.0 =
* Added separate "Generiraj cjenik proizvoda" / "Generiraj cjenik usluga" switches in Postavke - useful for sites that only ever have one of the two (e.g. a services-only site with no WooCommerce and no products), so it stops generating and publicly listing an always-empty price list for the other. Both stay on by default, so nothing changes unless you turn one off

= 2.6.4 =
* Fixed the "list is getting long" warning on the manual services table appearing far too late (it used the wrong field count, so it only warned at ~245 rows when PHP's default `max_input_vars` limit actually starts silently dropping data around row ~199-200)
* Added a clear error message when an entire form submission (e.g. a large CSV upload) is silently discarded because it exceeds the server's `post_max_size` limit - previously this failed with no feedback at all, looking like nothing happened
* CSV import now also recognizes column headers like "Naziv usluge"/"Naziv proizvoda" (as shown elsewhere in the plugin), not just the exact word "naziv", so a CSV built by copying those headers isn't silently rejected

= 2.6.3 =
* Fixed a critical error ("Uncaught ValueError") when importing a CSV on PHP 8, on servers whose mbstring build doesn't recognize the "Windows-1250" encoding name - the encoding auto-detection now only uses names the server actually supports, and CSV import no longer takes down the whole admin page on an unexpected encoding-related error

= 2.6.2 =
* The CSV files now start with the same generation metadata the XML root element already carries (generation date/time, sales outlet name, address, storage number) as key;value rows, before the column header row

= 2.6.1 =
* Fixed all price list timestamps (the archived filename timestamp, the "Generirano"/"Generiran" dates shown in admin, and the XML generation-date attribute) to always use Croatian (Europe/Zagreb) time, instead of partly using UTC (the filename timestamp) or the site's WordPress timezone setting (which many hosts leave at UTC by default)
* Fixed the daily automatic generation time to actually fire at the configured Croatian time - previously, on a server/WordPress install using UTC, "07:30" in the settings could actually run at 08:30 or 09:30 real Zagreb time depending on daylight saving, risking the legal "by 8:00" deadline. The schedule now also self-corrects if a daylight-saving transition shifts it

= 2.6.0 =
* Added support for multiple business locations ("Poslovnice") - a new tab on the Cjenik page lets you define physical locations (name, address, storage number), and each manually entered product/service row (products and services tabs) can optionally be assigned to one. Rows assigned to a location generate their own separate CSV/XML with that location's own address in the filename (Article VI), alongside the existing shared price list
* If you don't add any locations, nothing changes - this is fully opt-in and the existing single shared price list keeps working exactly as before

= 2.5.1 =
* Added proper translation support (Domain Path + a `languages/` folder) so the plugin's text can be translated with Loco Translate or any other .po/.mo tool
* Moved the "Generiraj cjenik sada" button away from the right edge on the Cjenik page, so it doesn't sit flush against the browser edge on wide screens

= 2.5.0 =
* The "Ručni unos usluga" manual entry table now only shows the 4 fields Article IV actually requires (Naziv, Cijena, Naziv akcije, Sidrena cijena), instead of the full product field set (Šifra/Brend/Jed. mjere/Barkod/Dostupno) that was never used for services - the "Ručni unos proizvoda" table is unchanged

= 2.4.3 =
* Fixed the reference price line showing twice on a variable product's selected-variation price, whenever that variation's price differs from the "from" price shown before selection. Both the general price filter and the variation-specific filter were independently appending the line in that case

= 2.4.2 =
* Fixed the reference price not showing at all on a variable product's shop/archive card (the price range shown before a variation is selected) - it only ever showed on the single product page after a variation was chosen. The plugin now shows a min–max reference price range on the card too, built from whichever variations have one set, the same way WooCommerce itself shows the regular price range

= 2.4.1 =
* The `[aplitap_cjenik_usluge]` shortcode table now also shows Šifra, Brend, Jed. mjere, Cijena/jed., Barkod and Dostupnost for manually entered services (in addition to the 4 legally required fields), matching what `[aplitap_cjenik]` already shows for products - the CSV/XML export for services is unaffected and still contains only the 4 fields Article IV requires
* Confirmed the full-width fix from 2.3.2 already covers `[aplitap_cjenik_usluge]` and `[aplitap_cjenik_arhiva]` too (they share the same wrapper); if it still looks narrow, re-save/republish the page after updating

= 2.4.0 =
* Products and services price list files now live in separate, clearer folders/URLs - wp-content/uploads/cjenik-proizvodi/ and wp-content/uploads/cjenik-usluga/ - instead of one shared "cjenik" folder with a "-usluge" suffix in the filename
* The "Arhiva" tab (and the `[aplitap_cjenik_arhiva]` shortcode) now shows a "Vrsta" (Type) column, since products and services archives can otherwise share the same filename in their own folder
* Note: existing links to the old wp-content/uploads/cjenik/ URLs will stop working after this update - update any bookmarks or embedded links to the new URLs shown on the price list tabs

= 2.3.3 =
* The `[aplitap_cjenik]` shortcode table now shows all the fields the Decision requires for products (added Brend, Cijena/jed., Naziv akcije and Barkod) instead of a trimmed 6-column view - it now matches the CSV/XML content

= 2.3.2 =
* Fixed the `[aplitap_cjenik]` / `[aplitap_cjenik_usluge]` / `[aplitap_cjenik_arhiva]` shortcode tables not stretching to the full width of their container on some themes/page builders (the wrapper only had a max-width, not an actual width, so flex/grid layouts could shrink it to fit its content instead)

= 2.3.1 =
* Added a delete button next to each archived file on the "Arhiva" tab, to remove an individual version without waiting for the retention period

= 2.3.0 =
* Split the "Cjenik" admin page into three tabs - "Proizvodi", "Usluge" and "Arhiva" - instead of one long page, so each price list is easier to manage on its own
* The manual entry table (CSV import + row-by-row list, for products/services without WooCommerce) is now two separate tables, one on the "Proizvodi" tab and one on the "Usluge" tab, each saving straight into its matching price list - no more per-row "Type" picker
* "Generiraj cjenik sada" is now a standalone button next to the tabs, so you can regenerate the price list from any tab

= 2.2.0 =
* The manual entry table (for sites without WooCommerce, or for items that aren't WC products) now has a "Tip" (Type) column - mark each row as "Proizvod" or "Usluga" and it's routed into the matching price list with the right fields, instead of everything being treated as a service with a reduced field set
* CSV import now also accepts a "tip" column ("proizvod"/"usluga"); rows without it default to "usluga" (unchanged behaviour)

= 2.1.2 =
* Fixed the reference price ("sidrena cijena") not showing at all on variable products (size/colour variations) - only simple products were displaying it. WooCommerce leaves the variation's price_html empty by default (themes render the price from raw numbers via JS instead), and the plugin was mistakenly skipping variations for exactly that reason.

= 2.1.1 =
* Added a `[aplitap_cjenik_arhiva]` shortcode to publicly list the archived price list versions (date + download link for each), and a matching copyable shortcode field on the admin Arhiva screen

= 2.1.0 =
* Legal correction: "special sale" is now the actual promotion NAME (e.g. "Black Friday"), for both products and services, as literally required by Article III/IV of the Decision - not just a yes/no flag
* Services now get their own, separate price list (CSV/XML/shortcode) instead of being merged into the product price list, matching the different, smaller field set the Decision requires for services
* Added bulk actions to the manual services table: select-all + "Ukloni odabrano", and a one-click "Obriši sve usluge" to clear the whole list
* Fixed CSV import corrupting many rows on files with non-UTF-8 encoding or old-style (Mac) line endings; the importer now normalizes both, and rejects the file with a clear error instead of silently creating garbled rows if the delimiter doesn't match
* Added a warning when the manual services table is large enough to risk exceeding the server's max_input_vars limit on save

= 2.0.0 =
* Redesigned the admin screens with a card-based layout, refined tabs, buttons and status badges
* Added an "Arhiva" (archive) section on the Cjenik page listing every generated CSV/XML version with a download link (matches the legally required 30+ day retention)
* Added a one-time "Prebaci redovnu cijenu u sidrenu za sve proizvode" button to bulk-copy each product's regular price into its reference price - disables itself after first use
* Fixed the CSV/XML preview links to bust browser cache after regeneration
* Fixed archive cleanup silently skipping old files when a custom "document name" was set (it only matched the default "cjenik_" filename prefix)

= 1.5.0 =
* Split the admin menu into "Postavke" (configuration) and "Cjenik" (current file, generation, services, data preview) - separates settings from day-to-day price list management
* The price list ("Cjenik") no longer requires WooCommerce - add services/items manually in a table, or bulk-import them from a CSV file
* The manual services table now has separate unit/retail price, a sale flag, a brand column, and a free-text unit of measure field
* Renamed "Oznaka prodajnog mjesta / objekta" to "Naziv dokumenta cjenika" - it now shows a live example of the auto-generated filename, and lets you set the exact file/URL name if filled in
* Added copyable CSV/XML URL fields on the Cjenik page
* Added a manual "Address" field for the price list filename when WooCommerce isn't active
* Admin menu no longer requires the WooCommerce-specific "manage_woocommerce" capability, so it stays accessible without WooCommerce
* Redesigned the admin screens with a cleaner card-based layout, refined tabs, buttons and status badges

= 1.4.0 =
* Added a `[aplitap_cjenik]` shortcode for a styled, human-readable price list page (the legal requirement itself only covers the XML/CSV files)

= 1.3.1 =
* Updated tags for better discoverability
* Rewrote the short description for clarity

= 1.3.0 =
* Declared compatibility with WooCommerce High-Performance Order Storage (HPOS), Cart & Checkout blocks, and the Product Block Editor
* Updated tags for better discoverability

= 1.2.0 =
* Renamed the plugin to lead with the Aplitap brand
* Moved dynamic CSS to wp_enqueue_style/wp_add_inline_style instead of an inline style tag
* Removed the duplicate "Tested up to" header from the main plugin file
* Rewrote this readme in English

= 1.1.0 =
* Added an "About" tab with a short agency description and a feedback/suggestion form

= 1.0.0 =
* Initial public release
* Reference price: field per product and per variation, display below the regular price site-wide, Quick Edit support, customizable text/font/color with separate mobile and desktop settings
* Price list: automatic XML/CSV generation per NN 101/2026, with configurable generation time, format, delimiter, archive retention, error email notifications, and manual product visibility control
* Settings organized into tabs under a dedicated admin menu item

== Upgrade Notice ==

= 1.2.0 =
Plugin renamed and technical fixes for directory compliance - please re-download after updating.
