Magento 2: Termékek importálása külső forrásokból

A Magento egy e-kereskedelmi megoldás, i.e. inkább a termékek értékesítésére irányul, mint az értékesítést kísérő raktározásra, logisztikára vagy pénzügyi elszámolásra. Más alkalmazások (például ERP-rendszerek) jobban megfelelnek a kísérő alkalmazásoknak. Ezért a Magento használatának gyakorlatában gyakran felmerül az a feladat, hogy egy üzletet integráljanak ezekkel a többi rendszerrel (például 1C).

Általában véve az integráció adatreplikációra redukálható:

  • katalógus (termékek, kategóriák);
  • készletadatok (termékegyenlegek a raktárakban és árak);
  • ügyfelek;
  • megrendelések;

A Magento az objektumok külön osztályát kínálja az adatbázisban lévő adatok kezeléséhez - adattárak. A Magento sajátosságaiból adódóan az adatok tárolókon keresztül történő felvétele az adatbázisba könnyen kódolható, de mondjuk lassú. Ebben a kiadványban megvizsgálom a termék Magento 2-höz való programozott hozzáadásának főbb szakaszait „klasszikus” módon - repo osztályok használatával.

Az ügyfelek és a rendelések általában a másik irányba replikálódnak – a Magentótól a külső ERP-rendszerekig. Ezért velük egyszerűbb, a Magento oldalon csak ki kell választani a megfelelő adatokat, majd "golyók repültek ki az oldalunkról”.

Az adatok adatbázisba rögzítésének elvei

Jelenleg az adatbázisba programozottan mentett objektumok Magento-ban történő létrehozása megtörtént Gyár:

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

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

és az adatbázisba írás megtörténik raktár:

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

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

A "Gyár" és a "Laktár" megközelítés a Magento 2 tartomány összes főbb modelljéhez használható.

Alapvető termékinformációk

Olyan adatstruktúrát keresek, amely megfelel a Magento 2.3-as verziójának. A termékkel kapcsolatos legalapvetőbb információk a táblázatban találhatók catalog_product_entity (terméknyilvántartás):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Egyetlen terméktípusra korlátozódok (type_id='simple'), alapértelmezett attribútumok készlete (attribute_set_id=4) és figyelmen kívül hagyja az attribútumokat has_options и required_options. Mivel az attribútumok entity_id, created_at и updated_at automatikusan generálódnak, akkor valójában egy új termék hozzáadásához csak be kell állítani sku. Ezt csinálom:

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

és kapok egy kivételt:

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

Hozzáadom a termék nevét a kéréshez, és üzenetet kapok, hogy az attribútum hiányzik Price. Az ár megadása után a termék bekerül az adatbázisba:

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

A termék nevét a termék varchar attribútumtáblázata tárolja (catalog_product_entity_varchar), ár - a táblázatban catalog_product_entity_decimal. Termék hozzáadása előtt célszerű kifejezetten jelezni, hogy az adminisztratív kirakatot használjuk az adatok importálására:

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

További attribútumok

További termékattribútumok feldolgozása a Magento használatával öröm. EAV adatmodell a fő entitásokhoz (lásd a táblázatot eav_entity_type) ennek a platformnak az egyik legfontosabb funkciója. Egyszerűen hozzáadjuk a megfelelő attribútumokat a termékmodellhez:

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

és amikor a modellt a repo objektumon keresztül menti:

$repoProd->save($prod);

további attribútumok is tárolódnak a megfelelő adatbázistáblákban.

Leltári adatok

Egyszerűen fogalmazva - a raktáron lévő termék mennyisége. A Magento 2.3-ban az adatbázis struktúrái, amelyek leírják a készletadatok tárolásának formátumát jelentősen különbözik attól, ami korábban történt. Azonban a raktáron lévő termék mennyiségének hozzáadása a termékmodell segítségével nem sokkal nehezebb, mint más attribútumok hozzáadása:

/** @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

Általános szabály, hogy egy termék médiatámogatása egy üzletben lévő ügyfél számára (e-kereskedelem) eltér a belső könyvelési rendszerben (ERP) alkalmazott ugyanazon termék médiatámogatásától. Az első esetben célszerű szemtől szemben bemutatni a terméket, a második esetben elegendő általános képet adni a termékről. Mindazonáltal elég gyakori, hogy legalább a termék elsődleges arculatát átadják. case adatok importálásakor.

Ha képet ad hozzá az adminisztrációs panelen keresztül, a kép először egy ideiglenes könyvtárba kerül (./pub/media/tmp/catalog/product) és csak a termék mentésekor a médiakönyvtárba kerül (./pub/media/catalog/product). Ezenkívül az adminisztrációs panelen keresztül hozzáadva a kép meg van címkézve 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);

Valamilyen oknál fogva az adathordozó csak a termék első mentése és a tárból való újbóli lekérése után kapcsolódik hozzá. És meg kell adnia az attribútumot label amikor bejegyzést adunk a termék médiagalériájához (különben kivételt kapunk Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

Gyakran előfordul, hogy az áruház és a háttéralkalmazás kategóriastruktúrája, illetve a bennük lévő termékek elhelyezése jelentősen eltérhet egymástól. A kategóriákra és a rajtuk belüli termékekre vonatkozó adatok migrálására vonatkozó stratégiák számos tényezőtől függenek. Ebben a példában a következőkhöz ragaszkodom:

  • a háttér és az áruház kategóriáit név szerint hasonlítják össze;
  • ha olyan kategóriát importálunk, amely nincs az áruházban, akkor a gyökérkategória alatt jön létre (Default Category) és további elhelyezése az üzlet katalógusában manuálisan történik;
  • egy termék csak akkor kerül besorolásra, ha az üzletben létrejön (első importálás);

A kategóriával kapcsolatos alapvető információk a táblázatban találhatók catalog_category_entity (kategóriakatalógus). Kategória létrehozása Magentoban:

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

A termék kategóriához kapcsolása a kategóriaazonosító és a termék cikkszáma használatával történik:

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

Összességében

A termék Magento 2-höz programozott hozzáadásához nagyon egyszerű kódot írni. A fent leírtakat egy demó modulba kombináltam.flancer32/mage2_ext_demo_import". Csak egy konzolparancs van a modulban fl32:import:prod, amely a JSON fájlban leírt termékeket importálja "./etc/data/products.json„:

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

Az importálandó képek a katalógusban találhatók ./etc/data/img.

10 termék importálási ideje ezzel a módszerrel körülbelül 10 másodperc a laptopomon. Ha tovább fejlesztjük ezt az elképzelést, könnyen arra a következtetésre juthatunk, hogy óránként körülbelül 3600 termék importálható, és 100 ezer termék behozatala körülbelül 30 óráig tarthat. A laptop szerverre cseréje némileg kisimítja a helyzetet. Talán többször is. De nem nagyságrendekkel. Talán ez a gyorsaság és lassúság bizonyos mértékig az egyik oka a projekt megjelenésének magento/async-import.

Az importálás sebességének növelésére radikális megoldás lehet az adatbázisba való közvetlen belépés, de ebben az esetben a Magento bővíthetőségével kapcsolatos összes „jó” elveszik - mindent „fejlett” magának kell megtennie. Azonban megéri. Ha beválik, a következő cikkben megvizsgálom az adatbázisba való közvetlen írásmódot.

Forrás: will.com

Hozzászólás