Magento 2: uvoz izdelkov iz zunanjih virov

Magento je rešitev za e-trgovino, tj. je bolj usmerjen v prodajo izdelkov kot v skladiščenje, logistiko ali finančno računovodstvo, ki spremlja prodajo. Druge aplikacije (na primer sistemi ERP) so bolj primerne za spremljevalne aplikacije. Zato se v praksi uporabe Magenta pogosto pojavi naloga integracije trgovine s temi drugimi sistemi (na primer 1C).

Na splošno je integracijo mogoče zmanjšati na replikacijo podatkov z:

  • katalog (izdelki, kategorije);
  • podatke o zalogah (stanje izdelkov v skladiščih in cene);
  • stranke;
  • naročila;

Magento ponuja ločen razred objektov za manipulacijo podatkov v bazi podatkov - repozitorije. Zaradi specifike Magenta je dodajanje podatkov v bazo prek repozitorijev enostavno kodirati, a je, recimo temu, počasno. V tej publikaciji obravnavam glavne faze programskega dodajanja izdelka v Magento 2 na "klasičen" način - z uporabo repo razredov.

Stranke in naročila se običajno replicirajo v drugo smer – iz Magenta v zunanje ERP sisteme. Zato je z njimi lažje, na Magento strani morate samo izbrati ustrezne podatke, nato pa "krogle so letele z naše strani".

Principi zapisovanja podatkov v bazo podatkov

Trenutno programsko ustvarjanje objektov, shranjenih v bazi podatkov v Magentu, poteka prek Factory:

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

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

in pisanje v bazo podatkov poteka prek Repozitorij:

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

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

Pristop "Factory" in "Repository" je mogoče uporabiti za vse glavne modele v domeni Magento 2.

Osnovne informacije o izdelku

Gledam strukturo podatkov, ki ustreza različici Magenta 2.3. Najosnovnejši podatki o izdelku so v tabeli catalog_product_entity (register izdelkov):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Omejen sem na eno vrsto izdelka (type_id='simple'), niz privzetih atributov (attribute_set_id=4) in prezrite atribute has_options и required_options. Ker atributi entity_id, created_at и updated_at generirajo samodejno, potem moramo pravzaprav za dodajanje novega izdelka samo nastaviti sku. naredim tole:

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

in dobim izjemo:

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

V zahtevo dodam ime izdelka in dobim sporočilo, da atribut manjka Price. Po dodajanju cene se izdelek doda v bazo:

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

Ime izdelka je shranjeno v tabeli atributov varchar izdelka (catalog_product_entity_varchar), cena - v tabeli catalog_product_entity_decimal. Pred dodajanjem izdelka je priporočljivo izrecno označiti, da za uvoz podatkov uporabljamo skrbniško trgovino:

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

Dodatni atributi

Obdelava dodatnih atributov izdelka z uporabo Magenta je užitek. Podatkovni model EAV za glavne subjekte (glejte tabelo eav_entity_type) je ena ključnih lastnosti te platforme. Modelu izdelka preprosto dodamo ustrezne atribute:

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

in pri shranjevanju modela prek objekta repo:

$repoProd->save($prod);

dodatni atributi bodo shranjeni tudi v ustreznih tabelah zbirke podatkov.

Podatki o zalogah

Preprosto povedano - količina izdelka na zalogi. V Magentu 2.3 so strukture v bazi podatkov, ki opisujejo format za shranjevanje podatkov o inventarju bistveno drugačen od tega, kar se je zgodilo prej. Vendar pa dodajanje količine izdelka na zalogi prek modela izdelka ni veliko težje kot dodajanje drugih atributov:

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

Mediji

Medijska podpora za produkt za stranko v trgovini (e-poslovanje) se praviloma razlikuje od medijske podpore za isti produkt za zaposlenega v internem računovodskem sistemu (ERP). V prvem primeru je priporočljivo, da izdelek pokažete iz oči v oči, v drugem pa je dovolj, da podate splošno predstavo o izdelku. Vendar pa je prenos vsaj primarne podobe izdelka precej pogost. case pri uvozu podatkov.

Pri dodajanju slike prek skrbniške plošče se slika najprej shrani v začasni imenik (./pub/media/tmp/catalog/product) in šele pri shranjevanju se izdelek premakne v imenik medijev (./pub/media/catalog/product). Tudi pri dodajanju prek skrbniške plošče je slika označena 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);

Iz neznanega razloga je medij povezan šele po prvem shranjevanju izdelka in ponovnem pridobivanju iz repozitorija. In morate določiti atribut label pri dodajanju vnosa v medijsko galerijo izdelkov (v nasprotnem primeru dobimo izjemo Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Категории

Pogosto se lahko struktura kategorij trgovine in zaledne aplikacije oziroma umeščanje izdelkov v njih bistveno razlikujeta. Strategije za selitev podatkov o kategorijah in izdelkih v njih so odvisne od številnih dejavnikov. V tem primeru se držim naslednjega:

  • kategorije zaledja in trgovine se primerjajo po imenu;
  • če je uvožena kategorija, ki je ni v trgovini, se ustvari pod korensko kategorijo (Default Category) in njegovo nadaljnje pozicioniranje v katalogu trgovine se predpostavlja ročno;
  • izdelek je uvrščen v kategorijo šele, ko je ustvarjen v trgovini (prvi uvoz);

Osnovni podatki o kategoriji so v tabeli catalog_category_entity (katalog kategorij). Ustvarjanje kategorije v Magentu:

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

Povezovanje izdelka s kategorijo se izvede z ID-jem kategorije in SKU izdelka:

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

Skupno

Pisanje kode za programsko dodajanje izdelka v Magento 2 je zelo enostavno. Vse zgoraj navedeno sem združil v demo modul “flancer32/mage2_ext_demo_import". V modulu je samo en ukaz konzole fl32:import:prod, ki uvozi izdelke, opisane v datoteki JSON "./etc/data/products.json":

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

Slike za uvoz so v katalogu ./etc/data/img.

Čas za uvoz 10 izdelkov s to metodo je na mojem prenosniku približno 10 sekund. Če to idejo razvijemo naprej, zlahka pridemo do zaključka, da je mogoče uvoziti približno 3600 izdelkov na uro, uvoz 100K izdelkov pa lahko traja približno 30 ur. Zamenjava prenosnega računalnika s strežnikom vam omogoča, da nekoliko zgladite situacijo. Morda celo večkrat. Vendar ne po velikostih. Morda je prav ta hitrost in počasnost do neke mere eden od razlogov za nastanek projekta magento/asinhroni uvoz.

Radikalna rešitev za povečanje hitrosti uvoza bi lahko bil neposreden vnos v bazo podatkov, vendar se v tem primeru izgubijo vse "dobrote" glede razširljivosti Magenta - vse "napredno" boste morali narediti sami. Vendar je vredno. Če se bo obneslo, bom pristop z neposrednim pisanjem v bazo razmislil v naslednjem članku.

Vir: www.habr.com

Dodaj komentar