Magento 2: importado de produktoj el eksteraj fontoj

Magento estas e-komerca solvo, t.e. estas pli celita al vendado de produktoj ol al stokado, loĝistiko aŭ financa kontado akompananta vendon. Aliaj aplikoj (ekzemple, ERP-sistemoj) pli taŭgas por akompanaj aplikoj. Tial, sufiĉe ofte en la praktiko uzi Magento la tasko integri vendejon kun ĉi tiuj aliaj sistemoj (ekzemple, 1C) ŝprucas.

Ĝenerale, integriĝo povas esti reduktita al datenreproduktado per:

  • katalogo (produktoj, kategorioj);
  • stokregistraj datumoj (produktaj ekvilibroj en magazenoj kaj prezoj);
  • klientoj;
  • mendoj;

Magento ofertas apartan klason de objektoj por manipuli datumojn en la datumbazo - deponejoj. Pro la specifaĵoj de Magento, aldoni datumojn al la datumbazo per deponejoj estas facile kodigi, sed ĝi estas, ni diru, malrapida. En ĉi tiu publikigo, mi konsideras la ĉefajn stadiojn de programe aldoni produkton al Magento 2 en la "klasika" maniero - uzante repo-klasojn.

Klientoj kaj mendoj estas kutime reproduktitaj en la alia direkto - de Magento ĝis eksteraj ERP-sistemoj. Sekve, estas pli simple kun ili, ĉe la flanko de Magento vi nur bezonas elekti la taŭgajn datumojn, kaj poste "kugloj elflugis de nia flanko".

Principoj de registrado de datumoj en datumbazon

Nuntempe, kreado de objektoj konservitaj en la datumbazo programe en Magento estas farita fabriko:

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

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

kaj skribi al la datumbazo estas farita tra Repository:

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

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

La "Fabriko" kaj "Deponejo" aliro povas esti uzata por ĉiuj ĉefaj modeloj en la Magento 2 domajno.

Bazaj Produktaj Informoj

Mi rigardas datuman strukturon, kiu kongruas kun Magento 2.3-versio. La plej bazaj informoj pri la produkto estas en la tabelo catalog_product_entity (produkta registro):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Mi estas limigita al unu speco de produkto (type_id='simple'), aro de defaŭltaj atributoj (attribute_set_id=4) kaj ignori atributojn has_options и required_options. Ekde la atributoj entity_id, created_at и updated_at estas generitaj aŭtomate, tiam, fakte, por aldoni novan produkton, ni nur bezonas agordi sku. Mi faras ĉi tion:

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

kaj mi ricevas escepton:

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

Mi aldonas la produktonomon al la peto kaj ricevas mesaĝon, ke la atributo mankas Price. Post aldoni la prezon, la produkto estas aldonita al la datumbazo:

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

La produktnomo estas konservita en la produkta varchar-atributa tabelo (catalog_product_entity_varchar), prezo - en la tabelo catalog_product_entity_decimal. Antaŭ ol aldoni produkton, estas konsilinde eksplicite indiki, ke ni uzas la administran vendejon por importi datumojn:

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

Pliaj Atributoj

Pretigi pliajn produktajn atributojn uzante Magento estas plezuro. EAV-datummodelo por ĉefaj unuoj (vidu tabelon eav_entity_type) estas unu el la ĉefaj trajtoj de ĉi tiu platformo. Ni simple aldonas la taŭgajn atributojn al la produkta modelo:

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

kaj dum konservado de la modelo per la repobjekto:

$repoProd->save($prod);

kromaj atributoj ankaŭ estos konservitaj en la respondaj datumbazaj tabeloj.

Invenraj datumoj

En simplaj terminoj - la kvanto de produkto en stoko. En Magento 2.3, strukturoj en la datumbazo, kiuj priskribas la formaton por stoki stokajn datumojn, estas signife malsamaj de tio, kio okazis antaŭe. Tamen, aldoni la kvanton de produkto en stoko per la produkta modelo ne estas multe pli malfacila ol aldoni aliajn atributojn:

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

Amaskomunikilaro

Kiel regulo, amaskomunikila subteno por produkto por kliento en vendejo (e-komerco) diferencas de amaskomunikila subteno por la sama produkto por dungito en interna kontada sistemo (ERP). En la unua kazo, estas konsilinde montri la produkton vizaĝo kontraŭ vizaĝo; en la dua, sufiĉas doni ĝeneralan ideon pri la produkto. Tamen, transdoni almenaŭ la primaran bildon de produkto estas sufiĉe ofta. case dum importado de datumoj.

Aldonante bildon tra la administra panelo, la bildo unue estas konservita en provizora dosierujo (./pub/media/tmp/catalog/product) kaj nur dum konservado la produkto estas movita al la amaskomunikila dosierujo (./pub/media/catalog/product). Ankaŭ, kiam aldonite per la administra panelo, la bildo estas etikedita 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);

Ial, la amaskomunikilaro estas ligita nur post unue konservi la produkton kaj repreni ĝin el la deponejo. Kaj vi devas specifi la atributon label aldonante eniron al la produkta amaskomunikilaro galerio (alie ni ricevas escepton Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Kategorioj

Ofte, la kategoriostrukturo de la vendejo kaj la backend-apliko aŭ la lokigo de produktoj en ili povas signife diferenci. Strategioj por migrado de datumoj pri kategorioj kaj produktoj ene de ili dependas de multaj faktoroj. En ĉi tiu ekzemplo mi restas al la sekvanta:

  • backend kaj vendej kategorioj estas komparitaj per nomo;
  • se kategorio estas importita kiu ne estas en la vendejo, tiam ĝi estas kreita sub la radika kategorio (Default Category) kaj ĝia plua poziciigo en la butikkatalogo estas supozita permane;
  • produkto estas atribuita al kategorio nur kiam ĝi estas kreita en la vendejo (unua importo);

Bazaj informoj pri la kategorio estas en la tabelo catalog_category_entity (katalogo de kategorioj). Krei kategorion en Magento:

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

Ligi produkton al kategorio estas farita per la kategorio-identigilo kaj produkta SKU:

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

Tuta

Skribi kodon por aldoni produkton programe al Magento 2 estas sufiĉe facila. Mi kombinis ĉion supre menciitan en demonstran modulon "flancer32/mage2_ext_demo_import". Estas nur unu konzola komando en la modulo fl32:import:prod, kiu importas la produktojn priskribitajn en la JSON-dosiero "./etc/data/products.json":

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

Bildoj por importo estas en la katalogo ./etc/data/img.

La tempo por importi 10 produktojn per ĉi tiu metodo estas ĉirkaŭ 10 sekundoj sur mia tekkomputilo. Se ni disvolvas ĉi tiun ideon plu, estas facile veni al la konkludo, ke proksimume 3600 produktoj povas esti importitaj hore, kaj ĝi povas daŭri ĉirkaŭ 100 horojn por importi 30K produktojn. Anstataŭigi tekkomputilon per servilo ebligas al vi iom mildigi la situacion. Eble eĉ plurfoje. Sed ne laŭ grandordoj. Eble ĉi tiu rapideco kaj malrapideco estas iagrade unu el la kialoj de la apero de la projekto magento/async-import.

Radikala solvo por pliigi la rapidecon de importo povus esti rekta eniro en la datumbazon, sed ĉi-kaze ĉiuj "bonaĵoj" rilate al la etendebleco de Magento estas perditaj - vi mem devos fari ĉion "altnivele". Tamen, ĝi valoras ĝin. Se ĝi funkcias, mi konsideros la aliron kun rekta skribado al la datumbazo en la sekva artikolo.

fonto: www.habr.com

Aldoni komenton