Magento 2: import produktov z externých zdrojov

Magento je e-commerce riešenie, t.j. je viac zameraný na predaj produktov ako na skladovanie, logistiku alebo finančné účtovníctvo sprevádzajúce predaj. Iné aplikácie (napríklad ERP systémy) sú vhodnejšie pre sprievodné aplikácie. Preto pomerne často v praxi používania Magento vzniká úloha integrácie obchodu s týmito inými systémami (napríklad 1C).

Celkovo možno integráciu zredukovať na replikáciu údajov:

  • katalóg (produkty, kategórie);
  • údaje o zásobách (stavy produktov v skladoch a ceny);
  • klientov;
  • objednávky;

Magento ponúka samostatnú triedu objektov na manipuláciu s údajmi v databáze - úložiská. Vzhľadom na špecifiká Magenta sa pridávanie údajov do databázy prostredníctvom repozitárov ľahko kóduje, ale je, povedzme, pomalé. V tejto publikácii sa zaoberám hlavnými fázami programového pridávania produktu do Magento 2 „klasickým“ spôsobom – pomocou repo tried.

Zákazníci a objednávky sa zvyčajne replikujú opačným smerom – od Magenta k externým ERP systémom. Preto je to s nimi jednoduchšie, na strane Magento stačí vybrať príslušné údaje a potom „z našej strany vyleteli guľky".

Princípy zaznamenávania údajov do databázy

V súčasnosti je vytváranie objektov uložených v databáze programovo v Magento realizované cez továreň:

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

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

a zápis do databázy sa vykonáva cez sklad:

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

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

Prístup „Factory“ a „Repository“ možno použiť pre všetky hlavné modely v doméne Magento 2.

Základné informácie o produkte

Pozerám sa na dátovú štruktúru, ktorá zodpovedá verzii Magento 2.3. Najzákladnejšie informácie o produkte sú v tabuľke catalog_product_entity (registre produktov):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Som obmedzený na jeden typ produktu (type_id='simple'), súbor predvolených atribútov (attribute_set_id=4) a ignorovať atribúty has_options и required_options. Od atribútov entity_id, created_at и updated_at sa generujú automaticky, potom v skutočnosti na pridanie nového produktu stačí nastaviť sku. Robí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 dostanem výnimku:

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

Do žiadosti pridám názov produktu a zobrazí sa mi správa, že atribút chýba Price. Po pridaní ceny sa produkt pridá do databázy:

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

Názov produktu je uložený v tabuľke atribútov varchar produktu (catalog_product_entity_varchar), cena - v tabuľke catalog_product_entity_decimal. Pred pridaním produktu sa odporúča výslovne uviesť, že na import údajov používame administratívny výklad:

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

Ďalšie atribúty

Spracovanie ďalších atribútov produktu pomocou Magento je potešením. Dátový model EAV pre hlavné entity (pozri tabuľku eav_entity_type) je jednou z kľúčových funkcií tejto platformy. Do modelu produktu jednoducho pridáme príslušné atribúty:

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

a pri ukladaní modelu cez objekt repo:

$repoProd->save($prod);

ďalšie atribúty budú tiež uložené v príslušných tabuľkách databázy.

Údaje o zásobách

Zjednodušene povedané - množstvo produktu na sklade. V Magento 2.3 sú štruktúry v databáze, ktoré popisujú formát na ukladanie údajov o zásobách výrazne odlišné z toho, čo sa stalo predtým. Pridanie množstva produktu na sklade prostredníctvom modelu produktu však nie je oveľa zložitejšie ako pridanie ďalších atribútov:

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

Médiá

Mediálna podpora produktu pre klienta na predajni (elektronický obchod) sa spravidla líši od mediálnej podpory rovnakého produktu pre zamestnanca v internom účtovnom systéme (ERP). V prvom prípade je vhodné ukázať produkt tvárou v tvár, v druhom prípade stačí poskytnúť všeobecnú predstavu o produkte. Preniesť aspoň primárny imidž produktu je však celkom bežné. case pri importe údajov.

Pri pridávaní obrázka cez admin panel sa obrázok najprv uloží do dočasného adresára (./pub/media/tmp/catalog/product) a iba pri ukladaní sa produkt presunie do adresára médií (./pub/media/catalog/product). Po pridaní cez panel správcu sa obrázok označí 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 nejakého dôvodu je médium prepojené až po prvom uložení produktu a jeho opätovnom načítaní z úložiska. A musíte zadať atribút label pri pridávaní záznamu do mediálnej galérie produktu (inak dostaneme výnimku Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

Často sa štruktúra kategórií obchodu a backendovej aplikácie či umiestnenie produktov v nich môže výrazne líšiť. Stratégie migrácie údajov o kategóriách a produktoch v nich závisia od mnohých faktorov. V tomto príklade sa držím nasledovného:

  • kategórie backendu a obchodu sa porovnávajú podľa názvu;
  • ak sa importuje kategória, ktorá nie je v obchode, potom sa vytvorí v koreňovej kategórii (Default Category) a jeho ďalšie umiestnenie v katalógu predajne sa predpokladá manuálne;
  • produkt je zaradený do kategórie až pri vytvorení v obchode (prvý import);

Základné informácie o kategórii sú v tabuľke catalog_category_entity (katalóg kategórií). Vytvorenie kategórie v Magento:

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

Prepojenie produktu s kategóriou sa vykonáva pomocou ID kategórie a SKU produktu:

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

Celkom

Písanie kódu na programové pridanie produktu do Magento 2 je celkom jednoduché. Všetko uvedené vyššie som skombinoval do demo modulu “flancer32/mage2_ext_demo_import". V module je len jeden príkaz konzoly fl32:import:prod, ktorý importuje produkty opísané v súbore JSON "./etc/data/products.json,:

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

Obrázky na import sú v katalógu ./etc/data/img.

Čas na import 10 produktov pomocou tejto metódy je na mojom notebooku asi 10 sekúnd. Ak túto myšlienku ďalej rozvinieme, je ľahké dospieť k záveru, že za hodinu sa dá doviezť asi 3600 produktov a import 100 30 produktov môže trvať asi XNUMX hodín. Výmena prenosného počítača serverom vám umožní trochu zmierniť situáciu. Možno aj niekoľkokrát. Nie však rádovo. Možno práve táto rýchlosť a pomalosť je do istej miery jedným z dôvodov vzniku projektu magento/async-import.

Radikálnym riešením na zvýšenie rýchlosti importu by mohol byť priamy vstup do databázy, ale v tomto prípade sa stratia všetky „dobroty“ týkajúce sa rozšíriteľnosti Magenta – všetko budete musieť urobiť „pokročilo“ sami. Stojí to však za to. Ak to vyjde, v ďalšom článku zvážim prístup s priamym zápisom do databázy.

Zdroj: hab.com

Pridať komentár