Magento 2: import produktů z externích zdrojů

Magento je řešení pro e-commerce, tzn. se více zaměřuje na prodej produktů než na skladování, logistiku nebo finanční účetnictví doprovázející prodej. Jiné aplikace (například ERP systémy) jsou vhodnější pro doprovodné aplikace. Proto v praxi používání Magento často vyvstává úkol integrovat obchod s těmito jinými systémy (například 1C).

Celkově lze integraci zredukovat na replikaci dat:

  • katalog (produkty, kategorie);
  • inventární údaje (zůstatky produktů ve skladech a ceny);
  • klienti;
  • objednávky;

Magento nabízí samostatnou třídu objektů pro manipulaci s daty v databázi - úložišť. Vzhledem ke specifikům Magenta se přidávání dat do databáze přes úložiště snadno kóduje, ale je to, řekněme, pomalé. V této publikaci zvažuji hlavní fáze programového přidávání produktu do Magento 2 „klasickým“ způsobem – pomocí repo tříd.

Zákazníci a objednávky se obvykle replikují opačným směrem – od Magenta k externím ERP systémům. Proto je to s nimi jednodušší, na straně Magento stačí vybrat příslušná data a poté „kulky vylétly z naší strany".

Principy záznamu dat do databáze

V současné době je vytváření objektů uložených v databázi programově v Magentu provedeno prostřednictvím Továrna:

function __construct (MagentoCmsModelBlockFactory $blockFactory) {
    $this->blockFactory = $blockFactory;
}

/** @var MagentoCmsModelBlock $block */
$block = $this->blockFactory->create();

a zápis do databáze se provádí přes sklad:

function __construct (MagentoCmsApiBlockRepositoryInterface $blockRepo) {
    $this->blockRepo = $blockRepo;
}

$this->blockRepo->save($block);

Přístup „Factory“ a „Repository“ lze použít pro všechny hlavní modely v doméně Magento 2.

Základní informace o produktu

Dívám se na datovou strukturu, která odpovídá verzi Magento 2.3. Nejzákladnější informace o produktu jsou v tabulce catalog_product_entity (registr produktů):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Jsem omezen na jeden typ produktu (type_id='simple'), sada výchozích atributů (attribute_set_id=4) a ignorovat atributy has_options и required_options. Od atributů entity_id, created_at и updated_at jsou generovány automaticky, pak ve skutečnosti pro přidání nového produktu stačí nastavit sku. Dělám to:

/** @var MagentoCatalogApiDataProductInterfaceFactory $factProd */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogApiDataProductInterface $prod */
$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$repoProd->save($prod);

a dostávám výjimku:

The "Product Name" attribute value is empty. Set the attribute and try again.

Do požadavku přidám název produktu a zobrazí se mi zpráva, že atribut chybí Price. Po přidání ceny je produkt přidán do databáze:

$prod = $factProd->create();
$prod->setAttributeSetId(4);
$prod->setTypeId('simple');
$prod->setSku($sku);
$prod->setName($name);
$prod->setPrice($price);
$repoProd->save($prod);

Název produktu je uložen v tabulce atributů varchar produktu (catalog_product_entity_varchar), cena - v tabulce catalog_product_entity_decimal. Před přidáním produktu je vhodné výslovně uvést, že k importu dat používáme administrativní výlohu:

/** @var MagentoStoreModelStoreManagerInterface $manStore */
$manStore->setCurrentStore(0);

Další atributy

Zpracování dalších atributů produktu pomocí Magento je potěšením. Datový model EAV pro hlavní entity (viz tabulka eav_entity_type) je jednou z klíčových funkcí této platformy. Jednoduše přidáme příslušné atributy do modelu produktu:

$prodEntity->setData('description', $desc);
$prodEntity->setData('short_description', $desc_short);
// или
$prodEntity->setDescription($desc);
$prodEntity->setShortDescription($desc_short);

a při ukládání modelu přes objekt repo:

$repoProd->save($prod);

další atributy budou také uloženy v odpovídajících databázových tabulkách.

Údaje o zásobách

Jednoduše řečeno - množství produktu na skladě. V Magento 2.3 jsou struktury v databázi, které popisují formát pro ukládání skladových dat výrazně odlišné z toho, co se stalo předtím. Přidání množství produktu na skladě prostřednictvím modelu produktu však není o mnoho obtížnější než přidání dalších atributů:

/** @var MagentoCatalogModelProduct $prodEntity */
/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
$inventory = [
    'is_in_stock' => true,
    'qty' => 1234
];
$prodEntity->setData('quantity_and_stock_status', $inventory);
$repoProd->save($prodEntity);

média

Mediální podpora produktu pro klienta na prodejně (e-commerce) se zpravidla liší od mediální podpory stejného produktu pro zaměstnance v interním účetním systému (ERP). V prvním případě je vhodné ukázat produkt tváří v tvář, ve druhém stačí poskytnout obecnou představu o produktu. Přenést alespoň primární image produktu je však zcela běžné. case při importu dat.

Při přidávání obrázku přes admin panel se obrázek nejprve uloží do dočasného adresáře (./pub/media/tmp/catalog/product) a pouze při ukládání se produkt přesune do adresáře médií (./pub/media/catalog/product). Po přidání prostřednictvím panelu administrátora je obrázek také označen image, small_image, thumbnail, swatch_image.

/** @var MagentoCatalogApiProductRepositoryInterface $repoProd */
/** @var MagentoCatalogModelProductGalleryCreateHandler $hndlGalleryCreate */
/* $imagePath = '/path/to/file.png';  $imagePathRelative = '/f/i/file.png' */
$imagePathRelative = $this->imagePlaceToTmpMedia($imagePath);
/* reload product with gallery data */
$product = $repoProd->get($sku);
/* add image to product's gallery */
$gallery['images'][] = [
    'file' => $imagePathRelative,
    'media_type' => 'image'
    'label' => ''
];
$product->setData('media_gallery', $gallery);
/* set usage areas */
$product->setData('image', $imagePathRelative);
$product->setData('small_image', $imagePathRelative);
$product->setData('thumbnail', $imagePathRelative);
$product->setData('swatch_image', $imagePathRelative);
/* create product's gallery */
$hndlGalleryCreate->execute($product);

Z nějakého důvodu je médium propojeno až po prvním uložení produktu a jeho opětovném načtení z úložiště. A musíte zadat atribut label při přidávání záznamu do galerie médií produktu (jinak dostaneme výjimku Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

kategorie

Často se může výrazně lišit struktura kategorií obchodu a backendové aplikace nebo umístění produktů v nich. Strategie migrace dat o kategoriích a produktech v nich závisí na mnoha faktorech. V tomto příkladu se držím následujícího:

  • kategorie backend a store jsou porovnány podle názvu;
  • pokud je importována kategorie, která není v obchodě, pak je vytvořena pod kořenovou kategorií (Default Category) a jeho další umístění v katalogu prodejen se předpokládá ručně;
  • produkt je zařazen do kategorie až při jeho vytvoření v obchodě (první import);

Základní informace o kategorii jsou v tabulce catalog_category_entity (katalog kategorií). Vytvoření kategorie v Magento:

/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);

Propojení produktu s kategorií se provádí pomocí ID kategorie a SKU produktu:

/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);

Celkem

Psaní kódu pro programové přidání produktu do Magento 2 je docela snadné. Vše výše uvedené jsem spojil do demo modulu “flancer32/mage2_ext_demo_import". V modulu je pouze jeden konzolový příkaz fl32:import:prod, který importuje produkty popsané v souboru JSON "./etc/data/products.json„:

[
  {
    "sku": "...",
    "name": "...",
    "desc": "...",
    "desc_short": "...",
    "price": ...,
    "qty": ...,
    "categories": ["..."],
    "image_path": "..."
  }
]

Obrázky pro import jsou v katalogu ./etc/data/img.

Čas na import 10 produktů pomocí této metody je na mém notebooku asi 10 sekund. Pokud tuto myšlenku dále rozvineme, snadno dojdeme k závěru, že lze dovézt asi 3600 produktů za hodinu a import 100 30 produktů může trvat asi XNUMX hodin. Nahrazení notebooku serverem vám umožní situaci poněkud vyhladit. Možná i několikrát. Ale ne řádově. Možná je tato rychlost a pomalost do jisté míry jedním z důvodů vzniku projektu magento/async-import.

Radikálním řešením pro zvýšení rychlosti importu by mohl být přímý vstup do databáze, ale v tomto případě jsou všechny „dobroty“ ohledně rozšiřitelnosti Magenta ztraceny – vše budete muset udělat „pokročile“ sami. Nicméně to stojí za to. Pokud to vyjde, budu uvažovat o přístupu s přímým zápisem do databáze v příštím článku.

Zdroj: www.habr.com

Přidat komentář