# dfomnibus: zgodność z dyrektywą Omnibus w PrestaShop

> Moduł dfomnibus dostosowuje twój sklep PrestaShop do europejskiej dyrektywy 2019/2161, zwanej Omnibus, obowiązującej w całej Unii Europejskiej od 28 maja 2022. Buduje automatycznie historię cen każdego produktu i wyświetla, gdy…

- Strona: <https://www.datafirefly.com/pl/documentation/dfomnibus/>
- Język: pl
- Zaktualizowano: 2026-08-01
- Inne języki: [fr](https://www.datafirefly.com/documentation/dfomnibus/index.md), [en](https://www.datafirefly.com/en/documentation/dfomnibus/index.md), [es](https://www.datafirefly.com/es/documentation/dfomnibus/index.md), [de](https://www.datafirefly.com/de/documentation/dfomnibus/index.md), [it](https://www.datafirefly.com/it/documentation/dfomnibus/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfomnibus/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfomnibus/index.md)
- Indeks: <https://www.datafirefly.com/pl/documentation/llms.txt>

Moduł **dfomnibus** dostosowuje twój sklep PrestaShop do europejskiej dyrektywy 2019/2161, zwanej Omnibus, obowiązującej w całej Unii Europejskiej od 28 maja 2022. Buduje automatycznie historię cen każdego produktu i wyświetla, gdy tylko aktywna jest promocja, najniższą cenę odnotowaną w ciągu 30 dni poprzedzających.

**Wdrożenie w Polsce**: dyrektywa została przeniesiona do ustawy o informowaniu o cenach towarów i usług, ze zmianami obowiązującymi od 1 stycznia 2023. Wymagany komunikat brzmi „Najniższa cena z 30 dni przed obniżką”, a nad jego przestrzeganiem czuwają Inspekcja Handlowa i UOKiK.

**Zgodność:** PrestaShop od 8.0 do 9.x. PHP od 7.4 do 8.3. Multisklep, wielowalutowość i warianty obsługiwane natywnie. Bez komponentów zewnętrznych, bez CDN, przyjazny RODO.

## Instalacja

Instalacja zajmuje mniej niż pięć minut.

1. Pobierz plik `dfomnibus_v1.0.1.zip` ze swojego konta klienta DataFirefly.
2. W back office PrestaShop przejdź do **Moduły → Menedżer modułów → Zainstaluj moduł**.
3. Wgraj ZIP. PrestaShop tworzy tabele, generuje token cron i rejestruje potrzebne hooki.
4. Kliknij **Konfiguruj**, aby otworzyć ekran ustawień.

**Dwie utworzone tabele:** `ps_dfomnibus_price_history` na migawki i `ps_dfomnibus_compliance_log` na zdarzenia zgodności (zarezerwowana pod przyszłe rozszerzenia). Prefiks `ps_` jest automatycznie zastępowany twoim własnym.

## Ustawienie codziennego crona

Cron inicjuje historię twojego katalogu i gwarantuje ciągłość codziennych migawek, także dla produktów, których cena nigdy się nie zmienia. Bez aktywnego crona moduł działa, ale jego historia ogranicza się do produktów zmienianych ręcznie.

### Pobranie tokenu

Otwórz stronę konfiguracji modułu. Wyświetlony token cron jest unikalny dla twojej instalacji. Otrzymujesz adres w postaci:

```
https://twoj-sklep.pl/modules/dfomnibus/cron.php?token=TWOJ_TOKEN
```

### Ustawienie przez crona uniksowego

Dodaj do swojego crontaba poniższą linię i dostosuj godzinę do swojego ruchu, najlepiej w porze o niskim obciążeniu:

```
15 3 * * * curl -s "https://twoj-sklep.pl/modules/dfomnibus/cron.php?token=TWOJ_TOKEN" > /dev/null
```

### Ustawienie przez CLI

Jeśli wolisz uniknąć jakiejkolwiek ekspozycji po HTTP, uruchamiaj crona wprost z linii poleceń:

```
php /sciezka/do/twojego-sklepu/modules/dfomnibus/cron.php token=TWOJ_TOKEN
```

**Bezpieczeństwo tokenu:** moduł porównuje tokeny funkcją `hash_equals()`, co chroni przed atakami czasowymi. Nigdy nie udostępniaj tego tokenu i wygeneruj go ponownie przy podejrzeniu wycieku (przycisk _Wygeneruj token ponownie_ w konfiguracji).

## Konfiguracja opcji

### Włączenie wyświetlania

Przełącznik **Włącz wyświetlanie** steruje wstawianiem komunikatu zgodności pod ceną produktu. Możesz go tymczasowo wyłączyć, żeby zbierać historię bez pokazywania komunikatu na froncie, co przydaje się przy wdrożeniu albo w czasie testów.

### Tryb obliczania

Dostępne są dwa tryby:

- **Ścisły**: ceną odniesienia jest minimum odnotowane w ciągu 30 dni poprzedzających faktyczny początek trwającej promocji. Odpowiada literze dyrektywy.
- **Zachowawczy** (domyślnie zalecany): ceną odniesienia jest minimum z ostatnich 30 dni liczonych w oknie kroczącym. Interpretacja mniej korzystna dla sprzedawcy, ale bezpieczniejsza w razie kontroli.

**Który tryb wybrać?** Jeśli twój sklep ma klarowną politykę promocyjną, z dobrze udokumentowanymi datami początku i końca, tryb ścisły sprawdzi się idealnie. W razie wątpliwości, albo jeśli twoje reguły SpecificPrice są często zmieniane bez wyraźnej przerwy między okresami promocyjnymi i niepromocyjnymi, tryb zachowawczy jest bezpieczniejszy.

### Okres odniesienia

Okres wynosi domyślnie 30 dni, zgodnie z dyrektywą. Możesz go wydłużyć (60, 90 dni), żeby zachować jeszcze większą ostrożność, ale wartość minimalna pozostaje na poziomie 30 dni.

### Wykluczenie nowych produktów

Opcja **Wyklucz produkty młodsze niż X dni** ukrywa komunikat na zbyt świeżych produktach. Wartość domyślna: 30 dni. Jest to spójne z duchem dyrektywy, która dotyczy produktów o istotnej historii cenowej.

### Ograniczenie do UE

Jeśli sprzedajesz w UE i poza nią, zaznacz **Ogranicz wyświetlanie do Unii Europejskiej**. Moduł wykrywa kraj klienta w następującej kolejności:

1. Adres dostawy zalogowanego klienta
2. Adres z bieżącego koszyka
3. Domyślny kraj sklepu

Jeśli żadna z tych informacji nie jest dostępna, wyświetlanie pozostaje domyślnie aktywne, żeby uniknąć ryzyka nieumyślnej niezgodności.

### Ukryj przy równej cenie

Opcja **Ukryj, jeśli cena identyczna** usuwa komunikat, gdy bieżąca cena dokładnie odpowiada najniższej cenie z ostatnich 30 dni. Przydatna, żeby nie wyświetlać informacji bez wartości dla konsumenta.

### Rzeczywista obniżka

Włącz **Pokaż rzeczywistą obniżkę**, aby uzupełnić komunikat o procent liczony względem ceny Omnibus, a nie ceny przekreślonej. Przykład: produkt za 389 zł, w promocji za 259 zł, z ceną Omnibus 285 zł, pokaże _-9,1%_ rzeczywistej obniżki zamiast -33% liczonych od ceny przekreślonej. Jest to uczciwsze, ale każdy sprzedawca decyduje sam.

### Wykres

Wykres z 30 dni może wyświetlać się w osobnej zakładce karty produktu albo w linii pod ceną. Jest ładowany leniwie przez IntersectionObserver i uruchamia się dopiero po wejściu w widok, co gwarantuje zerowy wpływ na Core Web Vitals twoich kart produktu.

### Śledzenie per wariant

Zaznacz **Śledź warianty**, jeśli twoje produkty mają różne ceny per kombinacja (na przykład rozmiary XL z dopłatą). Historia jest wtedy dzielona według `id_product_attribute`, a komunikat Omnibus dostosowuje się do ceny wybranego wariantu.

### Retencja

Domyślny czas przechowywania to 365 dni. Starsza historia jest automatycznie czyszczona przy uruchomieniu crona. Wartość minimalna to 60 dni, co gwarantuje zapas bezpieczeństwa wobec ustawowego okna 30 dni.

## Pulpit zgodności

Pulpit dostępny przez **Moduły → Pulpit DataFirefly Omnibus** zbiera:

- Liczbę śledzonych produktów
- Łączną liczbę zapisanych migawek
- Datę i godzinę ostatniego przejścia crona
- Listę produktów z datą pierwszej migawki, datą ostatniej migawki, najniższą ceną z 30 dni i wskaźnikiem aktywnej promocji

Dla każdego produktu dostępne są trzy akcje:

- **Zobacz historię**: wyświetla do 1000 migawek ze znacznikami czasu
- **Migawka ręczna**: wymusza natychmiastowy zapis
- **Usuń historię**: resetuje śledzenie tego produktu (używaj ostrożnie)

### Eksport CSV

W widoku historii produktu przycisk **Eksportuj do CSV** generuje plik ze wszystkimi kolumnami opatrzonymi znacznikiem czasu (data, cena netto, cena brutto, waluta, sklep, wariant, wskaźnik promocji, źródło migawki). Format gotowy do archiwizacji albo przekazania kontrolerowi Inspekcji Handlowej.

## Zachowanie na froncie

Na karcie produktu, gdy tylko aktywna jest promocja, pod ceną wyświetla się automatycznie komunikat:

> Najniższa cena z 30 dni przed obniżką: 285,00 zł

Komunikat jest tłumaczony zgodnie z językiem sklepu (francuski, angielski, hiszpański, niemiecki). Wyświetlanie korzysta ze standardowego hooka `displayProductPriceBlock` i działa ze wszystkimi szablonami przestrzegającymi standardów PrestaShop (Classic, Hummingbird, Warehouse, Transformer, Panda).

**Jedno renderowanie na stronę:** moduł zawiera zabezpieczenie `static $rendered`, które gwarantuje, że komunikat pojawia się tylko raz na stronę, nawet jeśli hook `displayProductPriceBlock` jest wywoływany wielokrotnie (bloki podsumowań, sticky i tak dalej).

## Multisklep i wielowalutowość

Historia jest zapisywana per unikalna kombinacja `(id_product, id_product_attribute, id_shop, id_currency)`. Każdy sklep w twojej instalacji zachowuje więc własną historię, a każda aktywna waluta ma własną krzywą cenową. Bez przeliczeń w locie: wyświetlane kwoty odpowiadają dokładnie temu, co zapisano w chwili wykonania migawki.

## Rozwiązywanie problemów

### Komunikat nie pojawia się na karcie produktu

Sprawdź po kolei:

1. Czy opcja **Włącz wyświetlanie** jest zaznaczona w konfiguracji?
2. Czy cron wykonał się co najmniej raz? Jeśli nie, historia nie istnieje.
3. Czy ograniczenie do UE jest włączone, podczas gdy testujesz z kraju spoza UE?
4. Czy opcja **Ukryj, jeśli cena identyczna** jest włączona, a bieżąca cena odpowiada cenie minimalnej?
5. Czy produkt ma mniej niż 30 dni, przy włączonej opcji wykluczania nowości?

### Wykres się nie ładuje

Otwórz konsolę przeglądarki. Moduł oczekuje punktu wejścia AJAX udostępnianego przez kontroler frontowy `pricehistory`. Sprawdź, czy żaden system cache ani firewall nie przechwytuje tej trasy. Jeśli używasz CDN, dopuść wprost adresy `/module/dfomnibus/pricehistory`.

### Cron zwraca błąd 403 albo 401

Token w adresie nie odpowiada temu zapisanemu. Wróć do konfiguracji modułu i skopiuj aktualny token. Przy podejrzeniu wycieku kliknij **Wygeneruj token ponownie** i zaktualizuj swojego crona uniksowego.

### Błąd SQL w chwili wykonania migawki

Jeśli używasz wersji 1.0.0, zaktualizuj do 1.0.1. Pierwsza wersja miała wadę w trzech zapytaniach `Db::getRow()`, które dopisywały ręczne `LIMIT 1`, podczas gdy PrestaShop dodaje je już automatycznie, co dawało nieprawidłowe w SQL `LIMIT 1 LIMIT 1`. Zobacz historię zmian.

## FAQ

### Czy moduł jest obowiązkowy dla mojego sklepu?

Tak, jeśli sprzedajesz konsumentom w Unii Europejskiej i wyświetlasz ceny obniżone, promocje, kody rabatowe, wyprzedaże albo jakąkolwiek wzmiankę o obniżce. Dyrektywa Omnibus obowiązuje bez progu obrotu.

### Czym to się różni od CartRule?

Moduł śledzi wyłącznie ceny wynikające z `SpecificPrice` w PrestaShop (rabaty produktowe, rabaty ilościowe, rabaty grup klientów). Reguły koszyka (`CartRule`) działają na etapie zamówienia i nie zmieniają ceny jednostkowej pokazywanej na karcie produktu, więc pozostają poza zakresem dyrektywy.

### Jak dokładnie działa tryb ścisły?

Moduł szuka w historii ostatniej migawki bez promocji, a następnie pierwszej migawki promocyjnej po niej. Ta data stanowi początek trwającej promocji. Oknem odniesienia jest wtedy 30 dni poprzedzających tę datę. Jeśli przejścia z braku promocji do promocji nie da się wykryć, moduł przełącza się automatycznie na tryb zachowawczy.

### Czy mogę ukryć komunikat na wybranych produktach?

Moduł działa globalnie, ale opcja wykluczania nowych produktów i opcja ukrywania przy równej cenie pokrywają większość sytuacji, w których komunikat nie wnosi użytecznej informacji.

### Czy działa z cenami netto i brutto?

Tak. Moduł zapisuje przy każdej migawce obie kwoty (`price_tax_excl` i `price_tax_incl`) i wyświetla tę używaną przez sklep. Jeśli przełączysz się z jednego trybu na drugi, historia pozostaje użyteczna.

## Historia zmian

### 1.0.1, 14 maja 2026

- Poprawka: usunięcie ręcznego `LIMIT 1` z trzech zapytań `Db::getRow()`, które dawały nieprawidłowe w SQL `LIMIT 1 LIMIT 1`. Dotyczyło zabezpieczenia idempotencji zapisu i wykrywania początku promocji w trybie ścisłym.

### 1.0.0, 14 maja 2026

- Pierwsze wydanie
- Automatyczne zbieranie historii cen przez hooki i codzienny cron
- Wyświetlanie najniższej ceny z 30 dni na karcie produktu
- Wykres z 30 dni w czystym canvasie, ładowany leniwie, około 3 KB
- Pulpit zgodności ze statystykami i eksportem CSV
- Tryby obliczania ścisły i zachowawczy
- Obsługa multisklepu, wielu walut i wariantów
- Konfigurowalne ograniczenie do UE, wykluczanie nowych produktów, opcja ukrywania przy identycznej cenie
- Tłumaczenia FR, EN, ES, DE
