Import produktů z FlexiBee do Shoptetu

Jistě jste již přemýšleli o tom, že byste si ke svému FlexiBee pořídili e-shop. Mohu doporučit Shoptet. Chcete vědět jak do něho nahrát produkty?

Hlavní evidencí, kterou potřebujeme mít synchronizovánu mezi e-shopem a FlexiBee, je ceník. Jsou zde totiž evidovány všechny produkty a služby, které můžeme na e-shopu prodávat. Takže v podstatě tou nejdůležitější věcí je tyto produkty přenést do e-shopu. Pokud možno s minimálním úsilím :-).

Je ale důležité si rozmyslet, kde budeme mít primární zdroj dat. Jestli budeme produkty udržovat ve FlexiBee a do Shoptetu je budeme nahrávat a nebo opačně.

V předchozím článku o produktech jsem doporučoval mít hlavní zdroj dat v e-shopu. Většina e-shopů a Shoptet není výjimkou, má pro správu produktů mnohem lepší nástroje než FlexiBee.

Nezáleží na tom, jaké produkty ve FlexiBee evidujete
Nezáleží na tom, jaké produkty ve FlexiBee evidujete


XSLT transformace pro převod FlexiBee XML na Shoptet XML

Opět jako v předchozích článcích si pomůžeme XSLT transformací. Pomocí této novinky ve FlexiBee (od verze 2017.2) převedeme standardní FlexiBee XML na XML, které požaduje Shoptet.

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:java="http://xml.apache.org/xalan/java" exclude-result-prefixes="java">
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <!-- /cenik.xml?detail=full&includes=/cenik/skupZboz&limit=0&relations=atributy,prilohy&format=code:FLEXIBEE-PRODUKTY -->

  <!-- oddělovač podle kterého poznáme master a variantní produkty -->
  <!-- shoptet standardně používá / -->
  <xsl:variable name="variantDelimeter" select="'-'" />

  <!-- obrázky jsou přímo uložené ve FlexiBee a tak je potřeba seskládat si správnou adresu, aby se k nim dokázal Shoptet dostat -->
  <xsl:variable name="imageProxyUrlPrefix" select="'https://username:password@server:port/c/firma/priloha/'" />
  <xsl:variable name="imageProxyUrlPostfix" select="'/content'" />

  <xsl:key name="masterProduct" match="winstrom/cenik" use="java:flexibee.Tool.substring3(kod, 0, java:flexibee.Tool.indexOf(kod, $variantDelimeter))" />

  <xsl:template match="winstrom">
    <SHOP>
      <!-- java:flexibee.Tool.substring3 je použit protože substring-before při nenalezení delimeteru nevrací nic -->
      <xsl:apply-templates select="cenik[generate-id(.)=generate-id(key('masterProduct', java:flexibee.Tool.substring3(kod, 0, java:flexibee.Tool.indexOf(kod, $variantDelimeter)))[1])]"/>
    </SHOP>
  </xsl:template>

  <xsl:template match="cenik">
    <xsl:choose>
      <xsl:when test="count(key('masterProduct', java:flexibee.Tool.substring3(kod, 0, java:flexibee.Tool.indexOf(kod, $variantDelimeter)))) > 1">
        <!-- produkt s variantami -->
        <SHOPITEM>
          <xsl:call-template name="CENIK-MASTER"/>
          <VARIANTS>
            <xsl:for-each select="key('masterProduct', java:flexibee.Tool.substring3(kod, 0, java:flexibee.Tool.indexOf(kod, $variantDelimeter)))">
              <xsl:if test="contains(kod, $variantDelimeter)">
                <VARIANT>
                  <xsl:call-template name="CENIK-BEZ-VARIANT-NEBO-VARIANTA">
                    <xsl:with-param name="variant" select="true()" />
                  </xsl:call-template>
                </VARIANT>
              </xsl:if>
            </xsl:for-each>
          </VARIANTS>
        </SHOPITEM>
      </xsl:when>
      <xsl:otherwise>
        <!-- produkt bez variant -->
        <xsl:for-each select="key('masterProduct', java:flexibee.Tool.substring3(kod, 0, java:flexibee.Tool.indexOf(kod, $variantDelimeter)))">
          <SHOPITEM>
            <xsl:call-template name="CENIK-MASTER"/>
            <xsl:choose>
              <xsl:when test="atributy and atributy/atribut and atributy/atribut/hodnota">
                <!-- produkt bez variant ale s atributy musí mít alespoň jednu variantu -->
                <VARIANTS>
                  <VARIANT>
                    <xsl:call-template name="CENIK-BEZ-VARIANT-NEBO-VARIANTA">
                      <xsl:with-param name="variant" select="false()" />
                    </xsl:call-template>
                  </VARIANT>
                </VARIANTS>
              </xsl:when>
              <xsl:otherwise>
                <xsl:call-template name="CENIK-BEZ-VARIANT-NEBO-VARIANTA">
                  <xsl:with-param name="variant" select="false()" />
                </xsl:call-template>
              </xsl:otherwise>
            </xsl:choose>
          </SHOPITEM>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template name="CENIK-MASTER">
    <NAME><xsl:value-of select="nazev"/></NAME>
    <xsl:choose>
      <xsl:when test="kratkyPopis != ''"><SHORT_DESCRIPTION><xsl:value-of select="kratkyPopis"/></SHORT_DESCRIPTION></xsl:when>
      <xsl:when test="popis != ''"><SHORT_DESCRIPTION><xsl:value-of select="popis"/></SHORT_DESCRIPTION></xsl:when>
      <xsl:otherwise></xsl:otherwise>
    </xsl:choose>

    <xsl:if test="popis != ''">
      <DESCRIPTION><xsl:value-of select="popis"/></DESCRIPTION>
    </xsl:if>

    <ITEM_TYPE>
      <xsl:choose>
        <xsl:when test="typZasobyK = 'typZasoby.sluzba'">service</xsl:when>
        <xsl:otherwise>product</xsl:otherwise>
      </xsl:choose>
    </ITEM_TYPE>

    <xsl:if test="vyrobce != ''">
      <MANUFACTURER><xsl:value-of select="java:flexibee.Tool.substring(vyrobce, 5)"/></MANUFACTURER>
    </xsl:if>

    <xsl:if test="skupZboz and skupZboz/skupina-zbozi and skupZboz/skupina-zbozi/nazev">
      <CATEGORIES>
        <CATEGORY><xsl:value-of select="skupZboz/skupina-zbozi/nazev"/></CATEGORY>
      </CATEGORIES>
    </xsl:if>

    <xsl:if test="prilohy and prilohy/priloha and (prilohy/priloha/contentType = 'image/png' or prilohy/priloha/contentType = 'image/jpeg')">
      <IMAGES>
        <xsl:for-each select="prilohy/priloha[contentType = 'image/png' or contentType = 'image/jpeg']">
          <xsl:choose>
            <xsl:when test="typK = 'typPrilohy.odkaz'">
              <IMAGE><xsl:value-of select="link"/></IMAGE>
            </xsl:when>
            <xsl:when test="typK = 'typPrilohy.obrazek'">
              <IMAGE><xsl:value-of select="$imageProxyUrlPrefix"/><xsl:value-of select="id"/><xsl:value-of select="$imageProxyUrlPostfix"/></IMAGE>
            </xsl:when>
            <xsl:otherwise>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each>
      </IMAGES>
    </xsl:if>

    <!-- odkomentováním následujících řádků a jejich správným vyplněním je možné vyplnit i další vlastnosti -->
    <!--FLAGS></FLAGS-->
    <!--WARRANTY></WARRANTY-->
    <!--ALTERNATIVE_PRODUCTS>
      <CODE></CODE>
    </ALTERNATIVE_PRODUCTS-->
    <!--RELATED_PRODUCTS>
      <CODE></CODE>
    </RELATED_PRODUCTS-->
    <!--VISIBILITY></VISIBILITY-->
    <!--TEXT_PROPERTIES></TEXT_PROPERTIES-->
    <!--INFORMATION_PARAMETERS></INFORMATION_PARAMETERS-->

  </xsl:template>

  <xsl:template name="CENIK-BEZ-VARIANT-NEBO-VARIANTA">
    <xsl:param name="variant"/>

    <CODE><xsl:value-of select="kod"/></CODE>
    <PRICE><xsl:value-of select="java:flexibee.Tool.round(cenaZaklBezDph, 2)"/></PRICE>
    <PRICE_VAT><xsl:value-of select="java:flexibee.Tool.round(cenaZaklVcDph, 2)"/></PRICE_VAT>
    <PURCHASE_PRICE><xsl:value-of select="java:flexibee.Tool.round(nakupCena, 2)"/></PURCHASE_PRICE>
    <STANDARD_PRICE><xsl:value-of select="java:flexibee.Tool.round(cenaBezna, 2)"/></STANDARD_PRICE>
    <CURRENCY>CZK</CURRENCY>

    <xsl:if test="skladove = 'true'">
      <STOCK>
        <!--MAXIMAL_AMOUNT></MAXIMAL_AMOUNT-->
        <MINIMAL_AMOUNT>1</MINIMAL_AMOUNT>
        <AMOUNT><xsl:value-of select="sumDostupMj"/></AMOUNT>
      </STOCK>
    </xsl:if>

    <xsl:if test="mj1 != ''">
      <UNIT><xsl:value-of select="java:flexibee.Tool.substring(mj1, 5)"/></UNIT>
    </xsl:if>

    <AVAILABILITY>
      <xsl:choose>
        <xsl:when test="sumStavMj > 0.0">Skladem</xsl:when>
        <xsl:otherwise>Není skladem</xsl:otherwise>
      </xsl:choose>
    </AVAILABILITY>

    <WEIGHT><xsl:value-of select="hmotMj"/></WEIGHT>

    <xsl:choose>
      <xsl:when test="atributy and atributy/atribut and atributy/atribut/hodnota">
        <PARAMETERS>
          <xsl:for-each select="atributy/atribut">
            <PARAMETER>
              <NAME><xsl:value-of select="substring-after(typAtributu, 'code:')"/></NAME>
              <VALUE><xsl:value-of select="hodnota"/></VALUE>
            </PARAMETER>
          </xsl:for-each>
        </PARAMETERS>
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="$variant">
          <PARAMETERS>
            <PARAMETER>
              <NAME>parametr</NAME>
              <VALUE><xsl:value-of select="id"/></VALUE>
            </PARAMETER>
          </PARAMETERS>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>

    <!-- odkomentováním následujících řádků a jejich správným vyplněním je možné vyplnit i další vlastnosti -->
    <!--FREE_SHIPPING></FREE_SHIPPING-->
    <!--FREE_BILLING></FREE_BILLING-->
  </xsl:template>

</xsl:stylesheet>

Transformaci nahrajeme do FlexiBee do evidence Uživatelské transformace (horní menu Nástroje → Uživatelské transformace). Klikneme na tlačítko Nový a vyplníme zkratku (např. FLEXIBEE-PRODUKTY) a název. Do pole Dotaz vložíme zdrojový kód XSLT transformace a klikneme na tlačítko Uložit a zavřít.

Zkratku, kterou jsme zadali, si zapamatujeme. Budeme ji totiž potřebovat při sestavování adresy pro export produktů.


Jednorázový export produktů z FlexiBee

Pro vyzkoušení není potřeba přenos jakkoliv automatizovat a tak si vystačíme se stažením XML souboru z FlexiBee a jeho "ručním" importem do Shoptetu.

XML soubor z FlexiBee je dostupný na adrese https://{server}:{port}/c/{identifikátor firmy}/cenik.xml?detail=full&includes=/cenik/skupZboz&format=code:{zkratka transformace}&limit=0
Reálná adresa bude tedy například: https://demo.flexibee.eu/c/demo/cenik.xml?detail=full&includes=/cenik/skupZboz&format=code:FLEXIBEE-PRODUKTY&limit=0
Data z této adresy můžeme zkusit zobrazit v internetovém prohlížeči nebo si je stáhnout pomocí curl. Data si uložíme do souboru. Tento soubor následně nahrajeme do Shoptetu.

Nahrání do e-shopu se provádí v menu PRODUKTY → Import. Klikneme na tlačítko VYBERTE SOUBOR a vybereme XML soubor vyexportovaný z FlexiBee. Musíme zvolit jednu ze tří variant importu. Myslím, že nejlepší je první volba "Neměnit produkty a varianty, které nejsou obsaženy v importovaném souboru".

Import produktů v Shoptetu
Import produktů v Shoptetu

Kliknutím na tlačítko IMPORTOVAT spustíme import.

Pokud je všechno v pořádku, můžeme si zkontrolovat, zda se nám produkty na e-shopu objevily.

Automatický import produktů z FlexiBee

Další možností je automatický import. Stejně jako při přenosu stavu skladů je možné Shoptet nastavit tak, aby si data stahoval sám. Proč ne :-).

Co je potřeba udělat ručně?

Ručně je potřeba produkty roztřídit do kategorií. Zatím jsem totiž nevymyslel postup, jak přenášet i zatřídění do kategorií :-(. No co, možná mě ještě časem něco napadne.

Obrázky produktů je potřeba nahrávat přímo do Shoptetu. Z FlexiBee není možné je jednoduše vyexportovat tak, jak by Shoptet potřeboval.

Aktualizace 27. 6. 2018 - Kategorie

Dnes jsem lehce zaktualizoval adresu, kterou se z FlexiBee získávají produkty. Úprava byla nutná abychom mohli pokračovat v rozšiřování vlastností plněných z FlexiBee.

Seznam změn

  • Kategorie v Shoptetu jsou plněny názvem skupiny zboží. Tato změna umožňuje jednoduché zařazení produktů do potřebných kategorií.
  • Přenáší se váha zboží zadaná ve FlexiBee.


Aktualizace 2. 7. 2018 - Varianty a obrázky

Doplnil jsem do transformace podporu pro varianty produktů a obrázky.

Seznam změn

  • Varianty produktů
  • Obrázky


Závěr

Pokud používáte FlexiBee a přemýšlíte o tom, že si k němu pořídíte e-shopové řešení, mohu Shoptet doporučit. Produkty již máte nejspíš připraveny a je tedy potřeba je jen do e-shopu přenést. Není nutné zadávat všechno znovu.

Otevírá se vám zcela nový směr podnikání :-).

ABRA FlexiBee, E-Shop, REST API, Shoptet

- (2. 7. 2018)
Kája z Norska
Kája z Norska

Jsem programátor, horolezec a tak trochu FlexiBee fanatik :-).
Na CharlieBlogu sepisuji své nápady a poznatky už od roku 2006.

Powered by CharlieBlog Engine v2.0