Magento 2: produktų importavimas iš išorinių šaltinių

Magento yra elektroninės prekybos sprendimas, t.y. labiau orientuota į produkcijos pardavimą, o ne į sandėliavimą, logistiką ar pardavimus lydinčią finansinę apskaitą. Kitos programos (pavyzdžiui, ERP sistemos) geriau tinka papildomoms programoms. Todėl gana dažnai naudojant Magento iškyla užduotis integruoti parduotuvę su šiomis kitomis sistemomis (pavyzdžiui, 1C).

Apskritai integraciją galima sumažinti iki duomenų replikacijos:

  • katalogas (produktai, kategorijos);
  • atsargų duomenys (produktų likučiai sandėliuose ir kainos);
  • klientai;
  • užsakymai;

„Magento“ siūlo atskirą objektų klasę duomenų bazėje esančiais duomenimis manipuliuoti – saugyklos. Dėl Magento specifikos duomenų įtraukimas į duomenų bazę per saugyklas yra lengvai užkoduojamas, bet, tarkime, lėtas. Šiame leidinyje apžvelgiu pagrindinius programinio produkto įtraukimo į Magento 2 etapus „klasikiniu“ būdu - naudojant repo klases.

Klientai ir užsakymai dažniausiai atkartojami kita kryptimi – nuo ​​Magento iki išorinių ERP sistemų. Todėl su jais paprasčiau, „Magento“ pusėje tereikia pasirinkti tinkamus duomenis, o tada „iš mūsų pusės išskrido kulkos"

Duomenų įrašymo į duomenų bazę principai

Šiuo metu duomenų bazėje įrašytų objektų kūrimas programiškai Magento yra baigtas Gamykla:

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

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

ir rašoma į duomenų bazę Saugykla:

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

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

„Gamyklos“ ir „Saugyklos“ metodus galima naudoti visiems pagrindiniams „Magento 2“ srities modeliams.

Pagrindinė produkto informacija

Aš žiūriu į duomenų struktūrą, atitinkančią Magento 2.3 versiją. Pagrindinė informacija apie produktą pateikta lentelėje catalog_product_entity (produktų registras):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Aš apsiriboju vieno tipo gaminiais (type_id='simple'), numatytųjų atributų rinkinys (attribute_set_id=4) ir nepaisyti atributų has_options и required_options. Kadangi atributai entity_id, created_at и updated_at yra generuojami automatiškai, tada, iš tikrųjų, norėdami pridėti naują produktą, tereikia nustatyti sku. Aš darau tai:

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

ir aš gaunu išimtį:

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

Prie užklausos pridedu prekės pavadinimą ir gaunu pranešimą, kad trūksta atributo Price. Pridėjus kainą prekė įtraukiama į duomenų bazę:

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

Produkto pavadinimas saugomas produkto varchar atributų lentelėje (catalog_product_entity_varchar), kaina – lentelėje catalog_product_entity_decimal. Prieš pridedant produktą, patartina aiškiai nurodyti, kad duomenims importuoti naudojame administracinį parduotuvės filialą:

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

Papildomi atributai

Apdoroti papildomus produkto atributus naudojant Magento yra vienas malonumas. Pagrindinių objektų EAV duomenų modelis (žr. lentelę eav_entity_type) yra viena iš pagrindinių šios platformos savybių. Tiesiog pridedame atitinkamus atributus prie gaminio modelio:

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

ir išsaugant modelį per atpirkimo objektą:

$repoProd->save($prod);

papildomi atributai taip pat bus saugomi atitinkamose duomenų bazės lentelėse.

Inventorizacijos duomenys

Paprasčiau tariant – prekės kiekis sandėlyje. „Magento 2.3“ yra duomenų bazės struktūros, apibūdinančios atsargų duomenų saugojimo formatą žymiai skiriasi nuo to, kas nutiko anksčiau. Tačiau pridėti prekės kiekį sandėlyje naudojant prekės modelį nėra daug sudėtingiau nei pridėti kitų atributų:

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

Žiniasklaida

Paprastai žiniasklaidos palaikymas produktui klientui parduotuvėje (el. prekyba) skiriasi nuo žiniasklaidos palaikymo tam pačiam produktui darbuotojui vidinėje apskaitos sistemoje (ERP). Pirmuoju atveju patartina prekę parodyti akis į akį, antruoju pakanka susidaryti bendrą gaminio idėją. Tačiau bent jau pirminio prekės įvaizdžio perkėlimas yra gana įprastas dalykas. case importuojant duomenis.

Pridedant vaizdą per administratoriaus skydelį, vaizdas pirmiausia išsaugomas laikinajame kataloge (./pub/media/tmp/catalog/product) ir tik išsaugant gaminį perkeliamas į medijos katalogą (./pub/media/catalog/product). Be to, pridėjus per administratoriaus skydelį vaizdas pažymimas 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);

Dėl tam tikrų priežasčių laikmena susiejama tik pirmą kartą išsaugojus produktą ir dar kartą paėmus jį iš saugyklos. Ir reikia nurodyti atributą label pridedant įrašą į produkto medijos galeriją (kitaip gauname išimtį Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

Dažnai parduotuvės ir užpakalinės programos kategorijų struktūra arba prekių išdėstymas jose gali labai skirtis. Duomenų apie kategorijas ir produktus perkėlimo strategijos priklauso nuo daugelio veiksnių. Šiame pavyzdyje aš laikausi šių dalykų:

  • backend ir parduotuvių kategorijos lyginamos pagal pavadinimą;
  • jei importuojama kategorija, kurios nėra parduotuvėje, tada ji sukuriama pagal šakninę kategoriją (Default Category) ir jo tolesnė padėtis parduotuvės kataloge daroma rankiniu būdu;
  • prekė priskiriama kategorijai tik tada, kai ji sukuriama parduotuvėje (pirmasis importas);

Pagrindinė informacija apie kategoriją pateikta lentelėje catalog_category_entity (kategorijų katalogas). Kategorijos kūrimas Magento:

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

Produkto susiejimas su kategorija vykdomas naudojant kategorijos ID ir produkto SKU:

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

Iš viso

Rašyti kodą norint programiškai pridėti produktą prie Magento 2 yra gana paprasta. Aš sujungiau viską, kas išdėstyta aukščiau, į demonstracinį modulį “flancer32/mage2_ext_demo_import“. Modulyje yra tik viena konsolės komanda fl32:import:prod, kuri importuoja JSON faile aprašytus produktus./etc/data/products.json":

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

Importuoti nuotraukos yra kataloge ./etc/data/img.

Laikas importuoti 10 produktų naudojant šį metodą mano nešiojamajame kompiuteryje yra apie 10 sekundžių. Jei šią idėją plėtosime toliau, nesunku prieiti prie išvados, kad per valandą galima įvežti apie 3600 produktų, o 100 tūkst. produktų importuoti gali užtrukti apie 30 valandų. Nešiojamojo kompiuterio pakeitimas serveriu leidžia šiek tiek išlyginti situaciją. Gal net kelis kartus. Bet ne pagal dydį. Galbūt šis greitis ir lėtumas tam tikru mastu yra viena iš projekto atsiradimo priežasčių magento/async-import.

Radikalus sprendimas padidinti importo greitį galėtų būti tiesioginis įėjimas į duomenų bazę, tačiau tokiu atveju prarandamos visos „gėrybės“, susijusios su „Magento“ išplėtimu - viską turėsite padaryti „pažangiai“. Tačiau tai verta. Jei tai pasiteisins, kitame straipsnyje apsvarstysiu tiesioginio rašymo į duomenų bazę metodą.

Šaltinis: www.habr.com

Добавить комментарий