Přeskočit obsah
A
Pro administrátory
Obsluha administrace — obsah, uživatelé, e-shop, fakturace a nastavení
E-shop / Import produktů

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í#

  1. V menu Eshop → Import produktů klikněte na přidat.
  2. Přetáhněte soubor (.xml, .csv nebo .json) do nahrávacího pole, nebo ho vyberte kliknutím. Nahrát jde jeden soubor na job.
  3. Vyplňte nastavení jobu:

    Pole Význam Výchozí
    Režim upsert zakládá i aktualizuje; create odmítne existující kód jako chybu; update neexistující kód jen přeskočí Založit i aktualizovat
    Párovací klíč podle čeho se varianta hledá v databázi — code, nebo ean Kód
    Výchozí jazyk jazyk, ve kterém se čtou texty bez atributu lang cs
    Kolekce (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) nebo replace (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
  4. 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.

  1. 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.
  2. 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.
  3. 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#

<stock warehouse="hlavni">
  <quantity mode="set">12</quantity>
  <minQuantity>2</minQuantity>
</stock>

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
image1image5 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í