Magento 2: invoer van produkte van eksterne bronne

Magento is 'n e-handel oplossing, d.w.s. is meer gerig op die verkoop van produkte as op pakhuise, logistiek of finansiële rekeningkunde wat met verkope gepaard gaan. Ander toepassings (byvoorbeeld ERP-stelsels) is beter geskik vir gepaardgaande toepassings. Daarom, in die praktyk van die gebruik van Magento, ontstaan ​​die taak om 'n winkel met hierdie ander stelsels (byvoorbeeld 1C) te integreer.

In die algemeen kan integrasie tot data-replikasie verminder word deur:

  • katalogus (produkte, kategorieë);
  • voorraaddata (produkbalanse in pakhuise en pryse);
  • kliënte;
  • bestellings;

Magento bied 'n aparte klas voorwerpe vir die manipulering van data in die databasis - bewaarplekke. As gevolg van die besonderhede van Magento, is die byvoeging van data tot die databasis deur bewaarplekke maklik om te kodeer, maar dit is, kom ons sê, stadig. In hierdie publikasie oorweeg ek die hoofstadia van die programmaties byvoeging van 'n produk by Magento 2 op die "klassieke" manier - met behulp van repo-klasse.

Kliënte en bestellings word gewoonlik in die ander rigting gerepliseer – van Magento tot eksterne ERP-stelsels. Daarom is dit eenvoudiger met hulle, aan die Magento-kant hoef jy net die toepaslike data te kies, en dan "koeëls het van ons kant af uitgevlieg«.

Beginsels om data in 'n databasis aan te teken

Op die oomblik word die skep van voorwerpe wat in die databasis gestoor is, programmaties in Magento gedoen Factory:

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

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

en skryf na die databasis word deur gedoen bewaarplek:

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

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

Die "Factory" en "Repository" benadering kan gebruik word vir alle groot modelle in die Magento 2-domein.

Basiese produkinligting

Ek kyk na 'n datastruktuur wat ooreenstem met Magento 2.3-weergawe. Die mees basiese inligting oor die produk is in die tabel catalog_product_entity (produkregister):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Ek is beperk tot een tipe produk (type_id='simple'), 'n stel verstekkenmerke (attribute_set_id=4) en ignoreer eienskappe has_options и required_options. Aangesien die eienskappe entity_id, created_at и updated_at word outomaties gegenereer, dan, in werklikheid, om 'n nuwe produk by te voeg, moet ons net instel sku. Ek doen dit:

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

en ek kry 'n uitsondering:

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

Ek voeg die produknaam by die versoek en kry 'n boodskap dat die kenmerk ontbreek Price. Nadat die prys bygevoeg is, word die produk by die databasis gevoeg:

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

Die produknaam word in die produk varchar kenmerktabel gestoor (catalog_product_entity_varchar), prys - in die tabel catalog_product_entity_decimal. Voordat 'n produk bygevoeg word, is dit raadsaam om uitdruklik aan te dui dat ons die administratiewe winkelfront gebruik om data in te voer:

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

Bykomende eienskappe

Die verwerking van bykomende produkkenmerke met Magento is 'n plesier. EAV-datamodel vir hoofentiteite (sien tabel eav_entity_type) is een van die sleutelkenmerke van hierdie platform. Ons voeg eenvoudig die toepaslike eienskappe by die produkmodel:

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

en wanneer die model via die repo-voorwerp gestoor word:

$repoProd->save($prod);

addisionele eienskappe sal ook in die ooreenstemmende databasistabelle gestoor word.

Voorraaddata

In eenvoudige terme - die hoeveelheid produk in voorraad. In Magento 2.3 is strukture in die databasis wat die formaat vir die stoor van voorraaddata beskryf aansienlik verskil van wat voorheen gebeur het. Die byvoeging van die hoeveelheid van 'n produk in voorraad via die produkmodel is egter nie veel moeiliker as om ander eienskappe by te voeg nie:

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

media

As 'n reël verskil media-ondersteuning vir 'n produk vir 'n kliënt in 'n winkel (e-handel) van media-ondersteuning vir dieselfde produk vir 'n werknemer in 'n interne rekeningkundige stelsel (ERP). In die eerste geval is dit raadsaam om die produk van aangesig tot aangesig te wys; in die tweede geval is dit genoeg om 'n algemene idee van die produk te gee. Die oordrag van ten minste die primêre beeld van 'n produk is egter redelik algemeen. case wanneer data invoer.

Wanneer 'n prent deur die administrasiepaneel bygevoeg word, word die prent eers in 'n tydelike gids gestoor (./pub/media/tmp/catalog/product) en slegs wanneer dit gestoor word, word die produk na die mediagids geskuif (./pub/media/catalog/product). Ook, wanneer dit via die administrasiepaneel bygevoeg word, word die prent gemerk 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);

Om een ​​of ander rede word die media eers gekoppel nadat die produk eers gestoor en weer uit die bewaarplek gehaal is. En jy moet die kenmerk spesifiseer label wanneer 'n inskrywing by die produkmediagalery gevoeg word (anders kry ons 'n uitsondering Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

Dikwels kan die kategoriestruktuur van die winkel en die backend-toepassing of die plasing van produkte daarin aansienlik verskil. Strategieë om data oor kategorieë en produkte binne hulle te migreer, hang van baie faktore af. In hierdie voorbeeld hou ek by die volgende:

  • backend- en winkelkategorieë word volgens naam vergelyk;
  • as 'n kategorie ingevoer word wat nie in die winkel is nie, word dit onder die wortelkategorie geskep (Default Category) en die verdere posisionering daarvan in die winkelkatalogus word met die hand aanvaar;
  • 'n produk word slegs aan 'n kategorie toegeken wanneer dit in die winkel geskep word (eerste invoer);

Basiese inligting oor die kategorie is in die tabel catalog_category_entity (katalogus van kategorieë). Skep 'n kategorie in Magento:

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

Die koppeling van 'n produk aan 'n kategorie word uitgevoer deur die kategorie-ID en produk-SKU te gebruik:

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

In totaal

Dit is redelik maklik om kode te skryf om 'n produk programmaties by Magento 2 te voeg. Ek het alles wat hierbo genoem is gekombineer in 'n demo-module "flancer32/mage2_ext_demo_import". Daar is net een konsole-opdrag in die module fl32:import:prod, wat die produkte invoer wat in die JSON-lêer beskryf word "./etc/data/products.json":

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

Prente vir invoer is in die katalogus ./etc/data/img.

Die tyd om 10 produkte met hierdie metode in te voer, is ongeveer 10 sekondes op my skootrekenaar. As ons hierdie idee verder ontwikkel, is dit maklik om tot die gevolgtrekking te kom dat ongeveer 3600 produkte per uur ingevoer kan word, en dit kan ongeveer 100 uur neem om 30K produkte in te voer. Deur 'n skootrekenaar met 'n bediener te vervang, kan jy die situasie ietwat glad maak. Miskien selfs 'n paar keer. Maar nie in ordes van grootte nie. Miskien is hierdie spoed en traagheid tot 'n mate een van die redes vir die ontstaan ​​van die projek magento/async-invoer.

'n Radikale oplossing om die spoed van invoer te verhoog kan direkte toegang tot die databasis wees, maar in hierdie geval gaan al die "goedjies" met betrekking tot die uitbreidbaarheid van Magento verlore - jy sal alles "gevorderd" self moet doen. Dit is egter die moeite werd. As dit uitwerk, sal ek die benadering met direkte skryf aan die databasis in die volgende artikel oorweeg.

Bron: will.com

Voeg 'n opmerking