Search by

wmd / craft-omnibus

wmdhosting

Omnibus and sidrena cijena for Craft Commerce: price history per variant, the lowest price in the 30 days before a reduction, the Croatian anchor price (NN 101/2026), and the daily machine-readable price list.

Package info

github.com/WMD-hosting/craft-omnibus

Documentation

Type:craft-plugin

pkg:composer/wmd/craft-omnibus

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.1.2 2026-09-20 16:36 UTC

This package is auto-updated.

Last update: 2026-09-20 17:12:40 UTC


README

Price history per variant, and the two reference prices EU and Croatian law require next to a selling price:

  • Lowest price in the 30 days before a reduction (Directive (EU) 2019/2161 "Omnibus"; in Croatia Zakon o zaštiti potrošača, čl. 19). Shown while an item sells below its regular price. The reduced price itself never counts as its own reference.
  • Sidrena cijena ("dodatna cijena", Odluka o isticanju dodatne cijene, NN 101/2026, in force 1 October 2026): the price applicable on the reference day, 10 September 2026, shown clearly next to every selling price. Products listed later carry their first price with its date.

Plus the daily price list the same decision package requires from every trader with a website (Odluka o objavi cjenika proizvoda i usluga, NN 101/2026): CSV and XML, prescribed columns, prescribed file name, published on the site, kept 30 days.

Requirements

Craft CMS 5.0+, Craft Commerce 5.0+, PHP 8.2+.

Installation

composer require wmd/craft-omnibus
php craft plugin/install craft-product-price-history

The plugin records a history row whenever a variant's base price changes, and the current price when a product is first saved.

Installing on a store that already has prices

The anchor is read from history. A store that installs the plugin after the reference day has no rows for that day; if its prices have not changed since, assert that once:

php craft craft-product-price-history/anchor/backfill --as-of=2026-09-10

anchor/backfill without --as-of records today's price for variants that have no history at all.

Settings

Settings → Plugins → Omnibus, Price History and Anchor Price

Setting Default Notes
Reference day 2026-09-10 the day the anchor price is read for
Label empty printed next to the selling price; empty uses the translated default ("Anchor price", hr "Sidrena cijena")
Products listed after the reference day use their first price on the anchor then carries the listing date
Lowest-price window 30 days
Publish the daily price list on
Oblik / adresa / oznaka prodajnog objekta parts of the file name (čl. VI)
Publish directory @webroot/cjenik files must be public
Index route cjenik public page listing the files
Retention 30 days čl. VII
CSV delimiter ;
Field mapping brand: productsBrandCategories handles for marka, barkod, jedinica mjere, cijena za jedinicu mjere

Twig

{% set a = craft.productPriceHistory.anchor(variant) %}
{% if a %}
  {{ craft.productPriceHistory.anchorLabel() }} {{ a.price|commerceCurrency(currency) }} ({{ a.date|date('j. n. Y.') }})
{% endif %}

{% if variant.onPromotion or variant.salePrice < variant.basePrice %}
  {% set lowest = craft.productPriceHistory.lowestBefore(variant) %}
  {% if lowest is not null %}
    Najniža cijena u 30 dana prije sniženja: {{ lowest|commerceCurrency(currency) }}
  {% endif %}
{% endif %}

anchor() accepts a Variant, a Product (its default variant) or an id and returns { price, date, source } where source is anchorDate or firstListing. lowestBefore(variant, saleStart = null, days = null) closes the window at saleStart, by default the moment the current price was recorded.

The original API stays: getVariantLowestPrice(id, days, fallback) and getProductLowestPrice(id, days, fallback).

Price list

php craft craft-product-price-history/price-list/publish   # write today's CSV + XML, prune, rebuild the index
php craft craft-product-price-history/price-list/preview   # print the first rows, write nothing

Run publish from cron every day before 08:00 local time:

0 7 * * * cd /path/to/site && php craft craft-product-price-history/price-list/publish >/dev/null 2>&1

Columns, in the order of čl. III: naziv, sifra, marka, jedinica_mjere, cijena_za_jedinicu_mjere, maloprodajna_cijena, posebni_oblik_prodaje (DA/NE), sidrena_cijena, barkod, dostupnost. File name per čl. VI: {oblik}_{adresa}_{oznaka}_{broj-pohrane}_{YYYYMMDD_HHMMSS}.csv|xml. The decision does not prescribe column names or an XSD; adjust if the Ministry publishes a technical specification.

Console

Command Does
anchor/backfill [--as-of=Y-m-d] [--store=id] record the current price for variants with no history
anchor/show <variantId> print the anchor and the lowest price before now
price-list/publish [--store=id] write, prune, index
price-list/preview print rows

Legal references

  • Directive (EU) 2019/2161, art. 6a of Directive 98/6/EC (price reductions).
  • Zakon o zaštiti potrošača, čl. 19 (NN 19/2022, 59/2026).
  • Odluka o isticanju dodatne cijene kao mjera izravne kontrole cijena, NN 101/2026.
  • Odluka o objavi cjenika proizvoda i usluga kao mjera izravne kontrole cijena, NN 101/2026.
  • Zakon o iznimnim mjerama kontrole cijena, NN 40/2025 (penalties).

This plugin implements the rules as published; it is not legal advice.

License

MIT. Developed by WMD.