Magento 2: impurtà prudutti da fonti esterni

Magento hè una suluzione di e-commerce, i.e. hè più destinatu à a vendita di prudutti chè à u magazzinu, a logistica o a contabilità finanziaria chì accumpagna a vendita. Altre applicazioni (per esempiu, sistemi ERP) sò più adattati per l'applicazioni accumpagnate. Per quessa, abbastanza spessu in a pratica di utilizà Magento u compitu di integrà una tenda cù questi altri sistemi (per esempiu, 1C).

In generale, l'integrazione pò esse ridutta à a replicazione di dati da:

  • catalogu (prudutti, categurie);
  • dati d'inventariu (equilibri di i prudutti in magazzini è prezzi);
  • i clienti;
  • ordini;

Magento offre una classe separata di oggetti per manipulà e dati in a basa di dati - repository. A causa di e specificità di Magento, aghjunghje dati à a basa di dati per mezu di repositori hè faciule di codificà, ma hè, dicemu, lento. In questa publicazione, cunsiderà e tappe principali di l'aghjunzione programmatica di un pruduttu à Magento 2 in u modu "classicu" - usendu classi repo.

I clienti è l'ordine sò generalmente replicati in l'altra direzzione - da Magento à i sistemi ERP esterni. Per quessa, hè più faciule cun elli, da u latu Magento vi basta à selezziunà i dati apprupriati, è dopu "e palle volavanu da u nostru latu".

Principii di arregistramentu di dati in una basa di dati

À u mumentu, a creazione d'uggetti salvate in a basa di dati in u prugramma in Magento hè fatta Factory:

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

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

è scrive à a basa di dati hè fatta attraversu Repository:

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

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

L'approcciu "Factory" è "Repository" pò esse usatu per tutti i mudelli maiò in u duminiu Magento 2.

Informazioni basiche di u produttu

Fighjulendu una struttura di dati chì currisponde à a versione 2.3 di Magento. L'infurmazioni più basi nantu à u pruduttu hè in a tavula catalog_product_entity (registru di u produttu):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Sò limitatu à un tipu di pruduttu (type_id='simple'), un inseme di attributi predeterminati (attribute_set_id=4) è ignora l'attributi has_options и required_options. Dapoi l'attributi entity_id, created_at и updated_at sò generati in autumàticu, allora, in fattu, per aghjunghje un novu pruduttu, avemu solu bisognu di stabilisce sku. Facciu questu:

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

è aghju un'eccezzioni:

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

Aghju aghjunghje u nome di u produttu à a dumanda è riceve un missaghju chì l'attributu manca Price. Dopu avè aghjustatu u prezzu, u pruduttu hè aghjuntu à a basa di dati:

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

U nome di u produttu hè guardatu in a tabella di attributi varchar di u produttu (catalog_product_entity_varchar), prezzu - in a tavula catalog_product_entity_decimal. Prima di aghjunghje un pruduttu, hè cunsigliu di indicà esplicitamente chì usemu a vetrina amministrativa per impurtà dati:

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

Attributi addiziunali

Trattamentu di attributi supplementari di u produttu cù Magento hè un piacè. U mudellu di dati EAV per entità principali (vede a tavula eav_entity_type) hè una di e caratteristiche chjave di sta piattaforma. Avemu solu aghjunghje l'attributi adatti à u mudellu di produttu:

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

è quandu salvate u mudellu via l'ughjettu repo:

$repoProd->save($prod);

attributi supplementari seranu ancu almacenati in e tabelle di basa di dati currispundenti.

Dati di l'inventariu

In termini simplici - a quantità di pruduttu in stock. In Magento 2.3, strutture in a basa di dati chì descrizanu u formatu per almacenà e dati d'inventariu sò significativamente differente da ciò chì hè accadutu prima. In ogni casu, aghjunghje a quantità di un pruduttu in stock via u mudellu di u produttu ùn hè micca assai più difficiule di aghjunghje altre attributi:

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

Media

In regula, u supportu media per un pruduttu per un cliente in una tenda (e-commerce) difiere da u supportu media per u stessu pruduttu per un impiigatu in un sistema di cuntabilità internu (ERP). In u primu casu, hè cunsigliu per vede u pruduttu in faccia in u sicondu, hè abbastanza per dà una idea generale di u pruduttu. Tuttavia, trasfiriri almenu l 'imagine primariu di un pruduttu hè abbastanza cumuna. case quandu importate dati.

Quandu aghjunghje una maghjina attraversu u pannellu di amministrazione, l'imaghjini hè prima salvatu in un repertoriu tempurale (./pub/media/tmp/catalog/product) è solu quandu salvate u pruduttu hè spustatu in u cartulare media (./pub/media/catalog/product). Inoltre, quandu aghjunghje via u pannellu admin, l'imaghjini hè tagged 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);

Per una certa ragione, i media hè ligatu solu dopu avè prima salvatu u pruduttu è ritruvà da u repositoriu di novu. È avete bisognu di specificà l'attributu label quandu aghjunghje una entrata à a galeria media di u produttu (altrimenti avemu una eccezzioni Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Categurie

Spessu, a struttura di categuria di a tenda è l'applicazione backend o a piazza di i prudutti in elli pò differisce significativamente. Strategie per a migrazione di dati nantu à categurie è prudutti in elli dipendenu da parechji fatturi. In questu esempiu, aghju seguitu i seguenti:

  • e categurie backend è store sò paragunate per nome;
  • se una categuria hè impurtata chì ùn hè micca in a tenda, allora hè creata sottu a categuria radicali (Default Category) è u so posizionamentu ulteriore in u catalogu di a tenda hè presumitu manualmente;
  • un pruduttu hè attribuitu à una categuria solu quandu hè creatu in a tenda (prima importazione);

L'infurmazione basica nantu à a categuria hè in a tavula catalog_category_entity (catalogue di categurie). Crià una categuria in Magento:

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

U ligame di un pruduttu à una categuria hè realizatu utilizendu l'ID di categuria è u SKU di u produttu:

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

Tuttu

Scrivite codice per aghjunghje un pruduttu programmaticu à Magento 2 hè abbastanza faciule. Aghju cumminatu tuttu ciò chì dice sopra in un modulu demo "flancer32/mage2_ext_demo_import". Ci hè solu un cumandamentu di cunsola in u modulu fl32:import:prod, chì importa i prudutti descritti in u schedariu JSON "./etc/data/products.json":

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

I ritratti per l'impurtazione sò in u catalogu ./etc/data/img.

U tempu per impurtà 10 prudutti cù stu metudu hè di circa 10 seconde nantu à u mo laptop. Se avemu sviluppatu sta idea più, hè faciule per vene à a cunclusione chì circa 3600 prudutti ponu esse impurtati per ora, è pò piglià circa 100 ore per impurtà i prudutti 30K. A rimpiazzà un laptop cù un servitore permette di liscia a situazione un pocu. Forse ancu parechje volte. Ma micca per ordini di grandezza. Forsi sta rapidità è lentezza hè in una certa misura una di e ragiuni di l'emergenza di u prugettu magento/async-import.

Una suluzione radicali per aumentà a vitezza di l'importazione puderia esse l'entrata diretta in a basa di dati, ma in questu casu tutti i "buoni" in quantu à l'estensibilità di Magento sò persi - avete da fà tuttu "avanzatu" sè stessu. Tuttavia, vale a pena. Se funziona, cunsiderà l'approcciu cù scrittura diretta à a basa di dati in u prossimu articulu.

Source: www.habr.com

Add a comment