Omnibus, Price History and Anchor Price
Version 1.3.4
October 22, 2026
Fixed
- On a Commerce install with a second store, the price history took any store's save: it has no store column, and the lowest price in the last 30 days reads all of it. Saving a product on the retail site propagated it to a trade store whose variants sit at 0.00, and that wrote one 0.00 row per variant; a save from the trade store wrote its own price. History is now written only for variant saves in the primary store, never for propagating saves (before and after save), and the old price a save is compared with is the variant's price in its own store instead of the lowest-numbered one.
omnibus/anchor/backfilltakes the primary store's price unless--storenames another. Rows already written for a second store are not removed: look for variants whose history has a row at the other store's price (usually 0.00) and delete those rows.
Version 1.3.3
October 21, 2026
Fixed
- The price list and the lowest price before a reduction could carry a customer's own catalog price (a pricing rule with a customer condition). Commerce prices a variant for the signed-in user unless told otherwise, and Craft's web queue runner (
runQueueAutomatically) runs jobs inside a visitor's request, with that visitor's identity: a price list published while a customer with their own price browsed listed that price asmaloprodajna_cijena, withposebni_oblik_prodajeDA. Variants are now loaded withforCustomer(false); a Variant passed togetVariantLowestBefore()is re-priced for a guest when someone is signed in. The CP price history shows the guest's current price too.
Version 1.3.2
October 21, 2026
Fixed
- A product created together with its variants in one save (any importer) recorded no price history: the first-save handler listened to
Product::EVENT_AFTER_SAVE, but Commerce 5 saves the variants after it, so they had no ids yet. The first price is now recorded on the variant's own first save, under its primary owner. Drafts, revisions and propagation to other sites are skipped; a variant added in a product draft gets its row when the draft is applied. Variants imported with 1.3.1 or earlier and not saved since have no rows: runomnibus/anchor/backfill. product_price_historyhad no index for the per-variant lookups (lowest price in a window, the duplicate check on every save), which scanned the whole table on large catalogues. A migration adds one on (variantId,dateChanged).
Version 1.3.1
October 17, 2026
Fixed
- The lowest price before a reduction was empty for every variant on a Commerce promotional price or catalog pricing rule. The history records base prices only, so the latest row (usually the regular price, e.g. a backfill) was taken as the start of the reduction and the window before it was empty. The window now closes at the history row that lowered the price, or, when the selling price is below the latest recorded price, at the start (
dateFrom) of the active guest catalog price that gives it, else now; the regular price then counts as the price in force. - The window is compared in UTC, like the history rows: an explicit
saleStartin the site's time zone, or the default "now", moved it by the offset.
Changed
AnchorService::getVariantLowestBefore()takes a Variant as well as an id (the parameter is now$variant; named-argument callers usingvariantId:need updating). The id alone costs a variant query, for the selling price.
Version 1.3.0
October 17, 2026
Added
- A reference day per product: the
anchorDateRulessetting (CP table orconfig/omnibus.php) gives product types, or products related to a category or entry (subcategories included), another day thananchorDate, for the 2.5.2025 of food, drink, cosmetics, cleaning, toiletries and household goods (NN 101/2026-1212 t. IV; draft Pravilnik o isticanju bazne cijene, čl. 3(1)).AnchorService::EVENT_DEFINE_ANCHOR_DATEdecides it in code.AnchorService::anchorDateFor(),anchorDayFor()andanchorDates(). craft omnibus/anchor/import <file> --as-of=Y-m-d [--dry-run]writes the prices of a past reference day from asku;priceCSV; a second run with the same day updates its rows. Variants without history after that day are skipped (runanchor/backfillfirst), so an old price never stands in for the prices since.- The
anchorOverrideFieldsetting: a number or money field whose value, when filled, is the anchor (sourceoverride), for the draft Pravilnik's čl. 3(3) case the history cannot compute. - Price list columns
neto_kolicina(fromnetQuantityFieldor a row handler; draft Pravilnik o načinu objave cjenika, čl. 3(2)) andnaziv_posebnog_oblika_prodaje(NN 101/2026-1213 t. III): the name of the catalog pricing rule behind the sale price, else thesaleNamesetting (default "Sniženje"). Rules with a customer condition are not named. - Each XML
proizvodhas asidreni_datumattribute, its own reference day; rows carry it asPriceListService::ROW_ANCHOR_DATE. craft.productPriceHistory.anchorDate(variant).
Changed
- The CSV and XML gain two columns:
neto_kolicinaaftermarka,naziv_posebnog_oblika_prodajeafterposebni_oblik_prodaje. Readers that go by position rather than header need updating. AnchorService::getVariantAnchor()takes a Variant as well as an id (the parameter is now$variant; named-argument callers usingvariantId:need updating); with rules, a date handler or an override field, the id alone costs a variant query.omnibus/anchor/showno longer lists the--as-ofand--storeoptions it ignored.- The anchor's
dateis the variant's own reference day. The XML rootsidreni_datumstays the default day, and the public index names every configured day.
Version 1.2.1
October 17, 2026
Fixed
price-list/publishwritesindex.htmland the web shop's name in the primary site's language. From cron it used the console's language (usually English).
Version 1.2.0
October 17, 2026
Added
- One price-list file per outlet ("prodajni objekt", NN 101/2026): sites with physical stores register them on
PriceListService::EVENT_REGISTER_OUTLETS, each aPriceListOutletwith its own form, address and code in the file name (čl. VI). The web shop from the plugin settings stays the first outlet. - An outlet with
inventoryLocationIdpublishesnedostupnofor variants the web sells only from stock when that location has none; otherwise it keeps the web shop'sdostupnost(backorderable variants stay available). PriceListService::EVENT_DEFINE_ROWchanges or drops one row of one outlet (a store price, a product the store does not carry).craft omnibus/price-list/outlets;publishandpreviewtake--outlet=<code>. An outlet that is invalid or repeats another's file prefix is skipped, listed inPriceListService::$skippedOutlets, and makespublishexit with an error so cron monitoring sees it.- The public index groups the files by day, then outlet.
Changed
PriceListService::publish()returns['files' => [...per outlet], 'index', 'pruned', 'skipped'],rows()takes aPriceListOutlet, andxml()takes the outlet as a third argument.PriceListService::fileBase()is deprecated (it names the web shop's file); usePriceListFiles::base().broj pohranecounts runs per outlet and day (it counted every file of the day).- File-name parts are transliterated to ASCII (
Šubićevabecomessubiceva). A store whose old names kept diacritics starts a new prefix:broj pohranerestarts at 1 and the index lists the old files as a separate outlet until retention removes them. - The
--storeoption ofprice-list/publishis deprecated and ignored; it never changed the prices.
Version 1.1.6
October 13, 2026
Changed
- No functional changes. The source now passes PHPStan (level 4) and ECS, and
phpstan/phpstanis a dev dependency socomposer installprovidesvendor/bin/phpstan.
Version 1.1.5
October 13, 2026
Fixed
- Price history is recorded under the variant's primary product. When a product draft re-saved its live variants (for example after a variant was added in the draft), the rows were recorded under the draft's id and deleted along with the draft when it was applied. Rows lost that way before this release cannot be recovered by the plugin.
Version 1.1.4
October 11, 2026
Fixed
- Saving a product whose product type has versioning enabled no longer fails with
TypeError: addProductHistoryPrice(): Argument #2 ($variantId) must be of type int, null givenwhen a variant changed since the last revision. Variant revisions are no longer passed to the price history. - A variant without a store price row no longer records a 0.00 price as its first history entry.
Version 1.1.3
September 20, 2026
Changed
- Plugin handle is
omnibus(wascraft-product-price-history). Console commands are nowcraft omnibus/anchor/...andcraft omnibus/price-list/..., the translation category isomnibus. Theproduct_price_historytable and thecraft.productPriceHistoryvariable are unchanged. Sites on the old handle uninstall it and installomnibus, then runanchor/backfill --as-of=2026-09-10.
Version 1.1.2
September 20, 2026
Changed
- Plugin renamed to "Omnibus, Price History and Anchor Price".
- Anchor label setting is optional; when empty the translated default is used ("Anchor price", Croatian "Sidrena cijena").
- Control-panel headings and the generated price-list index no longer carry Croatian source strings; Croatian comes from translations.
Version 1.1.1
September 20, 2026
Changed
- Plugin renamed to "Omnibus and Anchor Price"; every control-panel label and the public price-list page are now English source strings with Croatian translations.
- Price-list index date printed as d.m.Y.
Version 1.1.0
September 20, 2026
Added
- Anchor price ("sidrena / dodatna cijena", NN 101/2026): the price applicable on the reference day (default 10 September 2026), or the first recorded price for products listed later.
craft.productPriceHistory.anchor(variant|product|id). - Lowest price in the N days before a reduction started, the reduced price itself excluded (Zakon o zaštiti potrošača čl. 19, EU Omnibus).
craft.productPriceHistory.lowestBefore(variant). - Daily machine-readable price list (Odluka o objavi cjenika proizvoda i usluga, NN 101/2026): CSV and XML with the čl. III columns, file name per čl. VI, retention per čl. VII, public index page.
craft omnibus/price-list/publish. - Console commands
anchor/backfill(with--as-of),anchor/show,price-list/publish,price-list/preview. - Plugin settings: reference day, label, lowest-price window, store identity for the file name, publish directory and route, retention, CSV delimiter, field mapping for brand, barcode and unit of measure.
- Croatian translations for the control panel.
Changed
- Package renamed to
wmd/craft-omnibus; the plugin handleomnibusand theproduct_price_historytable are unchanged, so existing installs update in place.