Import produktů#
Hromadné založení nebo aktualizace produktů a jejich variant jedním souborem (XML, CSV nebo JSON). Hodí se na první naplnění katalogu, pravidelné dodávky dat od dodavatele nebo hromadnou úpravu cen a skladu z Excelu.
Najdete v Eshop → Import produktů. Na obrazovkách nahrání i přehledu je i přímý odkaz „Nápověda – manuál formátu", který vás na tuto stránku přivede přímo z administrace.
Co import umí a co neumí#
Import zakládá a aktualizuje produkty a produktové sety — nikdy je
nemaže. Zboží, které chcete z nabídky stáhnout, v souboru deaktivujte
(activated="0"), smazání dělejte ručně v gridu.
Číselníky se v souboru jen párují podle názvu — pokud název v systému neexistuje, import ho ve většině případů nezaloží a hodnotu jen vynechá:
| Číselník | Chová se jak |
|---|---|
| Výrobce | zakládá se automaticky (přepínač „Automaticky zakládat neznámé výrobce“, výchozí zapnuto) |
| Kategorie | jen párování; založení podle path je možné, ale musíte ho zapnout (výchozí vypnuto) |
| Volba parametru (SELECT/RADIO/MULTISELECT) | jen párování; založení je možné, ale musíte ho zapnout (výchozí vypnuto) |
| Parametr, jednotka, měna, sklad, stav produktu, DPH, štítek, typ produktu | jen párování — nezaloží se nikdy, i kdyby v souboru byly sebečastěji |
Proč jsou volby a kategorie ve výchozím stavu vypnuté
Je to vědomá pojistka proti překlepům. Kdyby se cizí soubor s chybně napsaným názvem kategorie „Mobilní Telefony“ místo „Mobilní telefony“ zakládal automaticky, katalog by po pár importech měl desítky skoro stejných duplicitních větví. Dokud přepínač nezapnete, import jen upozorní a vy založíte kategorii/volbu ručně, jak ji chcete mít.
Produktová karta (<product>) se nepáruje přímo — páruje se přes kódy svých
variant. Víc kódů v jednom bloku <product> proto musí v databázi patřit témuž
produktu, jinak se celá karta odmítne (viz tabulka chyb).
Krok za krokem#
1. Nahrání a nastavení#
- V menu Eshop → Import produktů klikněte na přidat.
- Přetáhněte soubor (
.xml,.csvnebo.json) do nahrávacího pole, nebo ho vyberte kliknutím. Nahrát jde jeden soubor na job. -
Vyplňte nastavení jobu:
Pole Význam Výchozí Režim upsertzakládá i aktualizuje;createodmítne existující kód jako chybu;updateneexistující kód jen přeskočíZaložit i aktualizovat Párovací klíč podle čeho se varianta hledá v databázi — code, neboeanKód Výchozí jazyk jazyk, ve kterém se čtou texty bez atributu langcsKolekce (výchozí režim) jak se chovají kategorie/tagy/parametry/obrázky/příslušenství, pokud blok v souboru sám neřekne jinak — merge(přidat/upravit) neboreplace(přesně podle souboru)Sloučit Automaticky zakládat neznámé výrobce zapnuto Automaticky zakládat neznámé volby parametrů vypnuto Automaticky zakládat neznámé kategorie zakládá jen podle path, bez SEO textůvypnuto Zastavit běh na první chybě ostrý běh se zastaví hned při první tvrdé chybě položky, ne až na konci souboru vypnuto -
Klikněte Nahrát a pokračovat.
Limit velikosti souboru: XML 100 MB, CSV/JSON 20 MB. Nad limit formulář nahrání odmítne.
2. Validace nanečisto (automaticky)#
Hned po nahrání systém sám spustí validaci a otevře detail jobu s reportem. Do katalogu se v tomto kroku nic nezapisuje — jde jen o kontrolu nanečisto (dry-run).
V reportu najdete souhrn:
| Řádek reportu | Význam |
|---|---|
| Založí se | nové varianty, které import vytvoří |
| Aktualizuje se | existující varianty, které import přepíše podle souboru |
| Přeskočí se | položky s action="skip", nebo update na kód, který v databázi neexistuje |
| Nezapíše se (tvrdé chyby) | položky s chybou, která je zablokuje úplně — nezapíšou se vůbec |
| Zapíše se neúplně (měkké chyby) | položky, které se zapíší, ale bez části dat (neznámý číselník, nedostupný obrázek…) |
Pod souhrnem je stránkovaný řádkový log s filtrem úrovně (Chyby / Varování / Informace) a odkazem Stáhnout log na celý soubor najednou. Každý řádek nese číslo řádku v souboru, kód položky, zprávu a — u měkkých chyb — i hodnotu, kterou se import neúspěšně pokusil použít, abyste podle ní číselník doplnili.
Tvrdá chyba versus měkká chyba
Tvrdá chyba (úroveň Chyba) znamená, že se položka nezapíše vůbec — špatná struktura souboru, chybějící nebo duplicitní kód, konflikt párování, pokus vynulovat povinné pole. Měkká chyba (úroveň Varování) znamená, že se položka zapíše bez té jedné části — typicky neznámá kategorie, volba parametru, sklad, měna, stav nebo nedostupný obrázek. Sada se pak v gridu Sady produktů označí štítkem „Neúplný import“ (sloupec Import, má i vlastní filtr) — víte tak, které karty stojí za doplnění ručně.
Pokud report ukazuje chyby, které chcete opravit v nastavení jobu (např. změnit párovací klíč nebo zapnout automatické zakládání kategorií), formulář nastavení je na stejné stránce a po uložení tlačítko Validovat znovu spustí kontrolu nanečisto znovu. Pokud je problém v samotném souboru, opravte ho, smažte tento job a nahrajte soubor jako nový (import žádné přepisování nahraného souboru neumí).
Nastavení <settings> ze souboru je jen návrh
Pokud soubor obsahuje vlastní blok <settings>, report ho neignoruje, ale ani
ho automaticky nepoužije — rozhoduje vždy nastavení jobu z formuláře. Rozdíly
najdete v logu jako informační řádky, takže víte, že něco v souboru neodpovídá
tomu, co se doopravdy stane.
3. Spuštění#
Jakmile je job ve stavu Zvalidováno, na detailu se objeví tlačítka:
- Spustit — zařadí job do fronty, cron ho vezme do minuty. Použijte pro jakkoli velký soubor.
- Spustit hned — spustí ostrý zápis rovnou v tomto požadavku, jen do 200 položek. Nad limit se tlačítko nezobrazí, použijte frontu.
- Zrušit — u jobu, který ještě neběží.
- Smazat — smaže job i nahraný soubor; jde jen o joby, které právě neběží.
Oba spouštěcí kroky zapisují ostro — potvrzovací dialog na to výslovně upozorňuje, protože dev i produkce sdílí jednu databázi.
4. Průběh a výsledek#
Stránka Průběh (odkaz Stav v gridu i na detailu) ukazuje ukazatel postupu
(zpracováno / celkem), průběžné počty a posledních pár chyb a varování; stránka se
sama obnovuje, dokud běh neskončí. Po doběhnutí se v detailu jobu objeví druhá
záložka reportu — Report ostrého běhu — stejně stránkovaná a filtrovatelná jako
dry-run report, jen popisuje, co se doopravdy zapsalo. Když bylo zapnuté „Zastavit
běh na první chybě", report to řekne přímo — zbytek souboru se v tom případě
nezpracoval.
5. Doplnění neúplných položek#
Sady označené štítkem „Neúplný import“ najdete v gridu Sady produktů filtrem sloupce Import. Štítek zmizí:
- dalším čistým importem téhož kódu (bez měkkých chyb), nebo
- ručně v editaci sady — dole ve formuláři se objeví zaškrtávátko „Naimportováno neúplně (vyžaduje ruční dořešení)" (zobrazí se jen u sad, které štítek mají); odškrtnutím a uložením ho smažete.
Vzorový soubor#
Nejrychlejší cesta, jak zjistit, jak má soubor pro váš katalog vypadat, je nechat si ho vygenerovat, prohlédnout a upravit — roundtrip export → import je nejlepší učební pomůcka formátu.
- V gridu Eshop → Produkty nebo Eshop → Sady produktů filtrem zúžíte výběr (např. na jednu kategorii), zaškrtnete řádky a hromadnou akcí „Exportovat do XML" stáhnete soubor přesně ve formátu importu.
- Nebo na stránce Eshop → Import produktů použijte formulář „Export
katalogu" pod tabulkou historie — vyexportuje se celý katalog (do bezpečného
limitu položek), s volbou jazyků, sekcí (kategorie, texty, parametry, štítky,
ceny, sklad, obrázky, příslušenství) a přepínačem „Zahrnout id“ — zapnuté (výchozí)
přidá do souboru
id, takže zpětný import míří přesně na tutéž kartu i po případném přejmenování kódu. - Stažený soubor upravte (změňte ceny, zkopírujte blok
<variant>pro nový produkt, smažte sekce, které nepotřebujete) a nahrajte zpět přes přidat — validace nanečisto ukáže přesně to, co se se souborem stane, dřív než cokoli zapíšete ostro.
Export čte jen aktuální stav katalogu, nikdy nic nezapisuje. Export existuje jen jako XML (nejúplnější formát) — pro CSV ani JSON export není.
Formát XML#
XML je kanonický formát — jediný, který umí úplně všechno (včetně bundlů a příslušenství). CSV a JSON jsou z něj odvozené, viz níže.
Obálka a nastavení#
<import version="1.0">
<settings>
<mode>upsert</mode>
<matchBy>code</matchBy>
<defaultLang>cs</defaultLang>
<collectionMode>merge</collectionMode>
<autoCreateProducers>1</autoCreateProducers>
<autoCreateOptions>0</autoCreateOptions>
<autoCreateCategories>0</autoCreateCategories>
<stopOnError>0</stopOnError>
</settings>
<products>…</products>
<bundles>…</bundles>
</import>
version je povinný atribut kořenového elementu, dnes se podporuje jen "1.0".
<settings> je celý volitelný — chybějící tag = platí výchozí hodnota; hodnoty
souboru jsou navíc jen návrh (viz výše, rozhoduje nastavení jobu). <bundles>
je taky volitelný a smí být v souboru i bez <products>.
Konvence hodnot#
| Konvence | Pravidlo |
|---|---|
| Kódování | čisté UTF-8, bez BOM (soubor s BOM se odmítne) |
| Desetinná čísla | tečka kanonicky (0.170), čárka se toleruje |
| Datum a čas | Y-m-d H:i:s (2026-08-16 14:30:00), nebo jen Y-m-d |
| Časová zóna | Europe/Prague |
| Booleovské hodnoty | 1/0 kanonicky, true/false se toleruje (atributy remove/main navíc přijímají yes) |
| Neznámý tag/atribut uvnitř karty/varianty/bundlu | tvrdá chyba té položky — zbytek souboru se zpracuje dál |
Neznámý tag na úrovni <import>/<settings>, špatný kořen, nepodporovaná verze |
odmítnutí celého souboru |
<product> — produktová karta#
| Element/atribut | Význam |
|---|---|
id (atribut) |
explicitní cíl — číselné id existující karty; jediná cesta, jak přejmenovat kód přes <variant> a přitom mířit na tutéž kartu |
action (atribut) |
create/update/upsert/skip — přebíjí režim jobu pro tuhle kartu (a dědí se na varianty, které vlastní action nemají) |
<name lang=""> |
název karty; ve výchozím jazyce povinný u nové karty |
<description lang=""> |
popis, doporučeno v <![CDATA[…]]> |
<producer> |
název výrobce (auto-zakládání dle nastavení) |
<productType> |
typ produktu (jen párování) |
<activated> |
0/1, NOT NULL — prázdný tag je tvrdá chyba |
<image src=""> |
foto karty, jen http(s) adresa |
<categories collectionMode=""> |
<category href=""/> nebo <category path="" remove=""/> |
<variants> |
jedna nebo víc <variant> — karta bez varianty je tvrdá chyba |
<variant> — prodejní varianta (ProductSet)#
| Element/atribut | Význam |
|---|---|
id, action |
stejně jako u karty, ale na úrovni varianty |
<code> |
povinné vždy, i při aktualizaci — je to párovací klíč, max 20 znaků |
<ean>, <isbn> |
max 45 znaků, nullable (prázdný tag vynuluje) |
<name lang=""> |
povinné ve výchozím jazyce u nové varianty, max 255 znaků |
<longName lang="">, <shortDescription lang="">, <description lang=""> |
volitelné texty |
<unit code=""> |
kód jednotky, výchozí ks, pokud tag chybí u nové varianty |
<weight> |
kg, desetinné číslo 0 ≤ x < 10 000 000, 3 des. místa |
<warranty> |
celé číslo měsíců, 0–255 |
<freeDelivery>, <freePayment> |
0/1, výchozí 0 |
<publishTime>, <unpublishTime> |
okno zveřejnění, nullable |
<activated> |
0/1, výchozí 1, NOT NULL |
<vat> |
sazba DPH v %, jen párování |
<state> |
stav produktu, jen párování |
<tags> |
<tag remove="">Název</tag> |
<parameters> |
viz tabulka parametrů níže |
<prices> |
viz ceny níže |
<stock warehouse=""> |
viz sklad níže |
<images> |
viz obrázky níže |
<accessories> |
<accessory code="" remove=""/> — kód cílí i na variantu založenou v témže souboru; neznámý kód je jen měkká chyba (nepřipojí se) |
<links>, <fees>, <vats> |
rezervováno pro budoucí verzi — použití je tvrdá chyba položky |
Pole, která jdou vynulovat prázdným tagem (<ean/>): ean, isbn,
publishTime, unpublishTime, vat, state. Pole, kde je prázdný tag tvrdá
chyba (sloupec je NOT NULL): code, unit, weight, warranty, freeDelivery,
freePayment, activated u varianty, activated u karty. description a
shortDescription jsou taky NOT NULL, ale prázdný text je u nich legitimní hodnota
(vyprázdnění popisu dává smysl), takže se nezakazuje.
Parametry#
<parameters>
<parameter key="barva" option="cerna"/> <!-- SELECT/RADIO podle interního klíče volby -->
<parameter key="barva">Černá</parameter> <!-- nebo podle NÁZVU volby, case-insensitive -->
<parameter key="velikosti" option="s"/> <!-- MULTISELECT — opakujte element pro víc voleb -->
<parameter key="velikosti" option="m"/>
<parameter key="vaha-rozsah" value="1" value2="5"/> <!-- RANGE — value + value2 -->
<parameter key="material">Bavlna</parameter> <!-- TEXT/NUMBER/DATE — jen obsah elementu -->
<parameter key="stary-parametr" remove="1"/> <!-- smaže hodnotu tohoto klíče -->
</parameters>
key je povinný. Tvar hodnoty musí odpovídat typu parametru — option/text na
parametru typu RANGE, nebo value/value2 na parametru typu SELECT, je tvrdá
chyba položky. Neznámý parametr nebo neznámá volba je měkká chyba (nepřiřadí
se), pokud nemáte zapnuté automatické zakládání voleb.
Ceny#
<prices>
<price currency="CZK">
<amountWithVat>25990</amountWithVat>
<originalAmountWithVat>27990</originalAmountWithVat>
</price>
<price currency="CZK" fromAmount="5"><amountWithVat>24990</amountWithVat></price>
</prices>
Ceny se zapisují po osách měna × množstevní pásmo (fromAmount, celé číslo od 0 výš;
výchozí 0 = základní pásmo „od 1 kusu“, stejně ho zapisuje ceník v administraci i export
katalogu — 1 znamená totéž pásmo). Pro každou cenu (aktuální i původní) zvolte právě jeden
z páru — buď cenu bez DPH (<amount>), nebo s DPH (<amountWithVat>, ze
které se sazbou varianty dopočítá základ). Uloží se vždycky základ bez DPH, ať
posíláte kterýkoli z nich — viz Ceníky a DPH. Oba tagy z jednoho
páru zároveň je tvrdá chyba —
import by nevěděl, který platí. Neznámá měna nebo <price> bez ceny je jen měkká
chyba, cenový řádek se přeskočí. Nepovinný <points> (celé nezáporné číslo)
zapisuje body věrnostního programu.
Sklad#
warehouse je volitelný — pokud chybí, musí být v systému právě jeden aktivní
sklad, jinak se pohyb nezapíše (měkká chyba). mode="set" nastaví cílový fyzický
stav (nesmí být záporný), mode="add" k aktuálnímu stavu přičte/odečte. Neznámý
sklad je měkká chyba.
Obrázky#
<images collectionMode="merge">
<image src="https://example.com/img/foto-1.jpg" main="1">
<alt>Popisek</alt>
<alt lang="en">Caption</alt>
</image>
<image assetId="482" remove="1"/>
</images>
src (jen http(s), jinak tvrdá chyba) nebo assetId (odkaz na už nahraný
soubor — neexistující id je jen měkká chyba, obrázek se nepřipojí). Max 20
obrázků na variantu, nad limit je tvrdá chyba celé položky.
Bundly — sada za zvýhodněnou cenu#
<bundles> zakládá a aktualizuje sety typu „bundl“ (více zboží v jedné sadě za
společnou cenu) — bez vlastní karty, varianty ani skladu.
<bundles>
<bundle code="SET-IP16-KRYT">
<name>iPhone 16 128 GB + kryt zdarma</name>
<activated>1</activated>
<vat>21</vat>
<prices>
<price currency="CZK"><amountWithVat>25990</amountWithVat></price>
</prices>
<items>
<item code="IP16-128-BLK" count="1"/>
<item code="KRYT-IP16" count="2"/>
</items>
</bundle>
</bundles>
Na rozdíl od varianty je code u bundlu atribut, ne child element. Bundl sdílí
s variantou texty, <tags>, <prices> a <images> — stejná gramatika. Bundl
nemá <parameters>, <stock> ani <accessories> (žádný fyzický sklad ani
vlastní parametrizaci). <items> popisuje složení — code smí cílit na cokoli v
databázi i v témže souboru (variantu i jiný bundl), count je povinné celé číslo
≥ 1. Neznámá položka je tvrdá chyba celého bundlu (na rozdíl od příslušenství,
kde je to jen měkká chyba) — bundl bez rozpoznatelného složení nedává smysl.
<items> nemá collectionMode — každý import přepíše celé složení bundlu tím,
co je v souboru, i kdyby chyběl jen jeden <item>.
Kompletní příklad#
<import version="1.0">
<settings>
<mode>upsert</mode>
<defaultLang>cs</defaultLang>
</settings>
<products>
<product>
<name>iPhone 16</name>
<name lang="en">iPhone 16</name>
<description><![CDATA[<p>Popis celé produktové řady…</p>]]></description>
<producer>Apple</producer>
<image src="https://example.com/img/iphone16-karta.jpg"/>
<categories>
<category href="mobilni-telefony"/>
<category path="Elektro / Apple"/>
</categories>
<variants>
<variant>
<code>IP16-128-BLK</code>
<ean>194253001234</ean>
<name>iPhone 16 128 GB černý</name>
<name lang="en">iPhone 16 128 GB Black</name>
<shortDescription>Kompaktní vlajková loď v černé.</shortDescription>
<unit code="ks"/>
<weight>0.170</weight>
<warranty>24</warranty>
<vat>21</vat>
<state>Novinka</state>
<tags>
<tag>Novinka</tag>
</tags>
<parameters>
<parameter key="barva" option="cerna"/>
<parameter key="kapacita">128 GB</parameter>
</parameters>
<prices>
<price currency="CZK">
<amountWithVat>25990</amountWithVat>
<originalAmountWithVat>27990</originalAmountWithVat>
</price>
<price currency="CZK" fromAmount="5"><amountWithVat>24990</amountWithVat></price>
</prices>
<stock warehouse="hlavni">
<quantity mode="set">12</quantity>
<minQuantity>2</minQuantity>
</stock>
<images>
<image src="https://example.com/img/ip16-blk-1.jpg" main="1">
<alt>iPhone 16 černý – přední strana</alt>
<alt lang="en">iPhone 16 Black – front</alt>
</image>
<image src="https://example.com/img/ip16-blk-2.jpg"/>
</images>
<accessories>
<accessory code="KRYT-IP16"/>
</accessories>
</variant>
<variant>
<code>IP16-128-PNK</code>
<name>iPhone 16 128 GB růžový</name>
<parameters>
<parameter key="barva" option="ruzova"/>
<parameter key="kapacita">128 GB</parameter>
</parameters>
<prices>
<price currency="CZK"><amountWithVat>25990</amountWithVat></price>
</prices>
<stock><quantity>4</quantity></stock>
</variant>
</variants>
</product>
</products>
</import>
Minimální příklad — jen cena a sklad#
Tenhle soubor nezmění nic jiného — texty, kategorie, parametry i obrázky zůstávají tak, jak jsou. Tri-state pravidlo: co v souboru není, to se nemění.
<import version="1.0">
<products>
<product>
<variants>
<variant>
<code>IP16-128-BLK</code>
<prices><price currency="CZK"><amountWithVat>23990</amountWithVat></price></prices>
<stock><quantity>30</quantity></stock>
</variant>
</variants>
</product>
</products>
</import>
Formát CSV#
CSV je plochá podmnožina XML — rychlé hromadné úpravy z Excelu, 1 řádek = 1 varianta. Neumí bundly, příslušenství, přejmenování kódu ani plnou paletu obrázků — na to použijte XML nebo JSON.
Hlavička je case-insensitive, oddělovač ; (autodetekce ,, když se ; v
hlavičce vůbec nevyskytuje), BOM se toleruje. Soubor, který není platné UTF-8, se
automaticky zkusí převést z Windows-1250 (běžný export z českého Excelu) — o
převodu se zapíše informace do logu. Prázdná buňka znamená „nedotčeno“ (stejně
jako chybějící XML tag), literál #NULL (case-insensitive) znamená „vynuluj“.
Seskupení řádků do karty#
Sloupec product seskupuje řádky patřící jedné produktové kartě — libovolná
společná hodnota (ip16, 1, cokoli). Sloupce karty (productName:*,
productDescription:*, producer, productType, categories, productImage)
se berou jen z prvního řádku skupiny — na dalších řádcích musí být buď prázdné,
nebo shodné se sloupcem karty, jinak je to chyba struktury dané karty.
Sloupce#
| Sloupec | Význam |
|---|---|
code |
párovací kód varianty (povinný) |
product |
seskupení řádků do karty |
action |
create/update/upsert/skip na úrovni řádku (na kartu CSV action nemá) |
name:<lang>, longName:<lang>, shortDescription:<lang>, description:<lang> |
texty varianty |
productName:<lang>, productDescription:<lang> |
texty karty (jen z 1. řádku skupiny) |
ean, isbn, unit, weight, warranty, vat |
stejný význam jako v XML |
freeDelivery, freePayment, activated |
0/1 |
publishTime, unpublishTime |
Y-m-d H:i:s / Y-m-d |
producer, productType |
texty karty |
state |
stav produktu |
categories |
href hodnoty oddělené \| (jen href, ne path) |
tags |
názvy oddělené \| |
param:<klíč> |
hodnota1\|hodnota2 pro multiselect, od..do pro rozsah, jinak jedna hodnota — výhradně názvem volby, ne interním klíčem |
price:<CUR>, priceWithVat:<CUR> |
cena bez/s DPH v dané měně — vyplňte jen jeden z páru |
originalPrice:<CUR>, originalPriceWithVat:<CUR> |
původní cena, stejné pravidlo |
stock, stockMode, minQuantity, warehouse |
sklad |
image1 … image5 |
až 5 URL obrázků, jen src, bez main/assetId/alt textů |
productImage |
foto karty |
Co CSV neumí#
| Chybí oproti XML | Poznámka |
|---|---|
| Bundly | <bundles> je jen v XML/JSON |
| Příslušenství | <accessories> je jen v XML/JSON |
Atribut id |
žádné explicitní cílení, žádné přejmenování kódu |
action na kartě |
jen na řádku (variantě), ne na produktové kartě |
Kategorie podle path |
jen href, takže autoCreateCategories v CSV nikdy nezaloží novou kategorii |
| Cenová pásma a skupiny uživatelů | vždy jen základní pásmo (fromAmount=0), žádný userGroupId |
| Volba parametru podle interního klíče | jen podle názvu (case-insensitive) |
Víc než 5 obrázků, main, assetId, alt texty |
jen 5 URL sloupců bez metadat |
Příklad#
code;product;productName:cs;productDescription:cs;producer;categories;name:cs;name:en;shortDescription:cs;unit;weight;warranty;vat;state;tags;param:barva;param:kapacita;priceWithVat:CZK;originalPriceWithVat:CZK;price:EUR;stock;stockMode;minQuantity;warehouse;image1;image2;productImage
IP16-128-BLK;ip16;iPhone 16;"<p>Popis cele produktove rady.</p>";Apple;mobilni-telefony|elektro;iPhone 16 128 GB cerny;iPhone 16 128 GB Black;Kompaktni vlajkova lod v cerne.;ks;0.170;24;21;Novinka;Novinka;Cerna;128 GB;25990;27990;;12;set;2;hlavni;https://example.com/img/ip16-blk-1.jpg;https://example.com/img/ip16-blk-2.jpg;https://example.com/img/iphone16-karta.jpg
IP16-128-PNK;ip16;;;;;iPhone 16 128 GB ruzovy;iPhone 16 128 GB Pink;;;;;;;;Ruzova;128 GB;25990;;859.50;4;set;;;;;
Druhý řádek je druhá varianta téže karty (stejná hodnota ip16 ve sloupci
product) — sloupce karty (productName:*, producer, categories) jsou tam
prázdné, protože se berou z prvního řádku.
Formát JSON#
JSON je zrcadlo XML — umí úplně všechno, co umí XML (včetně bundlů,
příslušenství, id i obrázků s assetId/main/alt texty), jen jiným zápisem:
| XML | JSON |
|---|---|
| element | klíč objektu |
opakovatelný element (<tag>) |
pole hodnot |
text s lang (<name lang="en">) |
objekt {"cs": "…", "en": "…"} |
text bez lang |
zkráceně prostý řetězec (platí pro výchozí jazyk) |
kolekce (výchozí collectionMode) |
prosté pole […] |
kolekce s explicitním collectionMode |
{"mode": "merge"\|"replace", "items": […]} |
| vynulování (prázdný tag) | null (u textů i "") |
Neznámý klíč je stejně přísná chyba jako neznámý XML tag. Jediný rozdíl oproti
XML: číslo řádku v logu chyb není skutečný řádek souboru (JSON ho nemá), ale
1-based pozice položky v poli (products[2] → line=3) — log proto vždy nese i
kód položky, aby šly rozlišit i položky se stejnou pozicí v různých kartách.
Příklad#
{
"version": "1.0",
"settings": { "mode": "upsert", "defaultLang": "cs" },
"products": [
{
"name": { "cs": "iPhone 16", "en": "iPhone 16" },
"description": { "cs": "<p>Popis cele produktove rady.</p>" },
"producer": "Apple",
"image": "https://example.com/img/iphone16-karta.jpg",
"categories": [
{ "href": "mobilni-telefony" },
{ "path": "Elektro / Apple" }
],
"variants": [
{
"code": "IP16-128-BLK",
"ean": "194253001234",
"name": { "cs": "iPhone 16 128 GB cerny", "en": "iPhone 16 128 GB Black" },
"shortDescription": { "cs": "Kompaktni vlajkova lod v cerne." },
"unit": "ks",
"weight": 0.170,
"warranty": 24,
"vat": 21,
"state": "Novinka",
"tags": ["Novinka"],
"parameters": [
{ "key": "barva", "option": "cerna" },
{ "key": "kapacita", "text": "128 GB" }
],
"prices": [
{ "currency": "CZK", "amountWithVat": "25990", "originalAmountWithVat": "27990" },
{ "currency": "CZK", "fromAmount": 5, "amountWithVat": "24990" }
],
"stock": { "quantity": 12, "mode": "set", "minQuantity": 2, "warehouse": "hlavni" },
"images": [
{ "src": "https://example.com/img/ip16-blk-1.jpg", "main": true, "alt": { "cs": "iPhone 16 cerny - predni strana", "en": "iPhone 16 Black - front" } },
{ "src": "https://example.com/img/ip16-blk-2.jpg" }
],
"accessories": ["KRYT-IP16"]
},
{
"code": "IP16-128-PNK",
"name": { "cs": "iPhone 16 128 GB ruzovy" },
"parameters": [
{ "key": "barva", "option": "ruzova" },
{ "key": "kapacita", "text": "128 GB" }
],
"prices": [
{ "currency": "CZK", "amountWithVat": "25990" }
],
"stock": { "quantity": 4 }
}
]
}
]
}
Chyby a jejich řešení#
Nejčastější hlášky z validačního reportu a co s nimi udělat. Tvrdá = položka se vůbec nezapíše, měkká = zapíše se bez té části.
| Hláška (zkráceně) | Typ | Co udělat |
|---|---|---|
Varianta nemá <code> / prázdný <code> |
tvrdá | kód je povinný vždy, i při aktualizaci — doplňte ho |
| Kód přesahuje 20 znaků | tvrdá | zkraťte kód (limit je pevný, DB sloupec) |
| Tentýž párovací klíč je v souboru podruhé | tvrdá | v souboru je duplicitní kód/EAN — sloučte řádky nebo jeden smažte |
| Kód už patří jiné sadě | tvrdá | kód je v systému jedinečný — použijte jiný kód, nebo id k explicitnímu přejmenování |
| Kódy jedné karty patří v databázi různým produktům | tvrdá | varianty v jednom <product> musí patřit stejné kartě — rozdělte je do dvou karet |
Nová varianta musí mít <name> ve výchozím jazyce |
tvrdá | u založení je název v defaultním jazyce povinný |
Pole X nelze vynulovat — sloupec je NOT NULL |
tvrdá | pole jako code, unit, weight, activated nejde vyprázdnit — smažte celý tag místo prázdného |
| Hmotnost/záruka je mimo rozsah sloupce | tvrdá | hmotnost 0–10 000 000 kg (3 des. místa), záruka 0–255 měsíců |
Cena má zároveň <amount> i <amountWithVat> |
tvrdá | vyplňte jen jeden z páru (bez DPH, nebo s DPH) |
Množstevní pásmo fromAmount musí být celé číslo od 0 výš |
tvrdá | opravte hodnotu atributu fromAmount |
Obrázek/foto lze stáhnout jen z http(s) adresy |
tvrdá | žádné file://, ftp:// ani relativní cesty |
| Varianta má víc obrázků, než je limit | tvrdá | max 20 na variantu (XML/JSON), max 5 (CSV) |
| Neznámý tag/atribut, neznámý sloupec v CSV hlavičce | tvrdá (CSV: celý soubor) | opravte překlep v názvu tagu/sloupce podle formátu výše |
| Neznámý výrobce | měkká (info, pokud je zapnuté auto-zakládání) | založí se sám, nebo zapněte „Automaticky zakládat neznámé výrobce“ |
| Neznámá kategorie | měkká | doplňte kategorii ručně, nebo zapněte auto-zakládání a použijte path |
| Neznámá volba parametru | měkká | doplňte volbu ručně, nebo zapněte „Automaticky zakládat neznámé volby parametrů“ |
| Neznámá měna / neznámý sklad / neznámý stav / neznámý štítek | měkká | číselník je jen párovací — založte hodnotu ručně v příslušné administraci a importujte znovu |
Obrázek assetId v databázi neexistuje |
měkká | ověřte, že id patří už nahranému souboru |
Text v jazyce X se nezapíše — chybí <name lang> |
měkká | u nového překladu doplňte i název v tom jazyce, ne jen popis |
| Tag je rezervovaný pro budoucí verzi | tvrdá | <links>, <fees>, <vats> zatím nejsou podporované — odstraňte je ze souboru |
| Neznámá položka bundlu | tvrdá (celý bundl) | kód v <items> musí existovat v databázi nebo jinde v témže souboru |
Automatický běh#
Tlačítko Spustit zařadí job do fronty — bere ho cron úloha
/cron/eshop/product-import/run, která se spouští každou minutu a vždy jen
nejstarší čekající job. Podrobnosti o naplánovaných úlohách a jak se spouští cron
najdete v kapitole Naplánované úlohy.
Statistiky#
Stránka Eshop → Import produktů → Statistiky ukazuje souhrn běhů za zvolené období (7/30/90 dní): počty jobů podle stavu, součty založených/aktualizovaných/ přeskočených/chybných položek, graf „Běhy v čase“ a tabulku posledních běhů s odkazem na jejich detail.
Omezení#
| Omezení | Hodnota |
|---|---|
| Velikost souboru XML | 100 MB |
| Velikost souboru CSV/JSON | 20 MB |
| Velikost jednoho obrázku | 10 MB |
| Obrázků na variantu | 20 (XML/JSON), 5 (CSV) |
| „Spustit hned“ (synchronní běh) | jen do 200 položek |
| CSV | neumí bundly, příslušenství, id, kategorie podle path, cenová pásma, volbu podle interního klíče |
| Bundly | bez skladu, parametrů a příslušenství — jen texty, aktivace, DPH, štítky, ceny, obrázky a složení |
| Obrázky obecně | stahují se jen z http(s) adres; soubory se ukládají podle URL, takže stejná adresa nahraná víckrát se nezdvojí |