Magento 2: uvoz izdelkov iz zunanjih virov

Magento je e-commerce rješenje, to jest, više je usmjereno na prodaju proizvoda nego na prateće skladišne, logističke ili financijske evidencije. Za takve svrhe bolje su prikladne druge aplikacije (na primjer, ERP sustavi). Stoga se u praksi korištenja Magento često javlja potreba za integracijom dućana s tim drugim sustavima (na primjer, s 1C).

U osnovi, integraciju možemo svesti na replikaciju podataka po:

  • katalogu (proizvodi, kategorije);
  • inventarima (razina zaliha i cijene proizvoda);
  • kupcima;
  • narudžbama;

Magento nudi poseban razred objekata za manipulaciju podacima u bazi — repozitoriji. Zbog specifičnosti, dodavanje podataka u bazu putem repozitorija je lako kodirati, ali se događa, recimo, ne brzo. U ovom članku razmatram osnovne korake programatskog dodavanja proizvoda u Magento 2 na "klasičan" način — koristeći repo klase.

Kupci i narudžbe se obično replikiraju u suprotnom smjeru — iz Magenta u vanjske ERP sustave. Stoga je s njima lakše, na strani Magenta jednostavno trebate odabrati odgovarajuće podatke, a dalje — "s naše strane metci su ispaljeni«.

Principi zapisivanja podataka u bazu

Trenutno se objekti koji se pohranjuju u bazi programski stvaraju u Magentu putem Factory:

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

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

a zapis u bazu — putem Repository:

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

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

Pristup korištenjem "Factory" i "Repository" može se primijeniti na sve glavne modele u domeni Magento 2.

Osnovne informacije o proizvodu

Razmatram strukturu podataka koja odgovara verziji Magento 2.3. Najosnovnije informacije o proizvodu nalaze se u tablici catalog_product_entity (registar proizvoda):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Ograničavam se na jedan tip proizvoda (type_id='simple'), skupom atributa prema zadanim postavkama (attribute_set_id=4) i zanemarujem atribute has_options in required_options. Budući da se atribute entity_id, created_at in updated_at automatski generiraju, u suštini nam je za dodavanje novog proizvoda dovoljno zadati sku. Radim tako:

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

i dobijem iznimku:

Vrijednost atributa "Naziv proizvoda" je prazna. Postavite atribut i pokušajte ponovo.

Dodajem ime proizvoda u zahtev i dobijam poruku da nedostaje atribut Cena. Nakon dodavanja cene, proizvod se smešta u bazu:

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

Ime proizvoda se čuva u varchar tabeli atributa proizvoda (catalog_product_entity_varchar), cena se čuva u tabeli catalog_product_entity_decimal. Pre dodavanja proizvoda, preporučljivo je izričito navesti da koristimo administrativni interfejs za uvoz podataka:

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

Dodatni atributi

Obrada dodatnih atributa proizvoda pomoću Magento-a je pravi užitak. EAV model podataka za osnovne entitete (vidi tabelu eav_entity_type) — jedna je od ključnih karakteristika ove platforme. Jednostavno dodajemo odgovarajuće atribute modelu proizvoda:

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

i pri čuvanju modela preko repo objekta:

$repoProd->save($prod);

dodatni atributi će takođe biti sačuvani u odgovarajućim BD tabelama.

Inventarni podaci

Prosto rečeno — količina proizvoda na skladištu. U Magento 2.3 strukture u BD, koje opisuju format čuvanja inventarnih podataka, značajno se razlikuju od onog što je bilo ranije. Ipak, dodavanje količine proizvoda na skladištu preko modela proizvoda nije mnogo složenije od dodavanja drugih atributa:

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

Mediјa

Opšte, medijska podrška proizvoda za kupca u prodavnici (e-commerce) se razlikuje od medijske podrške istog proizvoda za zaposlenog u unutrašnjem sistemu evidencije (ERP). U prvom slučaju, želimo da prikažemo "proizvod " licem", dok je u drugom dovoljno dati opšti pregled proizvoda. Ipak, prenos barem primarne slike proizvoda je dovoljno rasprostranjen case prilikom uvoza podataka.

Kada se slika dodaje putem admin panela, slika se prvo čuva u privremenom direktorijumu (./pub/media/tmp/catalog/product) i tek prilikom čuvanja proizvoda se premešta u medij katalog (./pub/media/catalog/product). Takođe, kada se dodaje putem admin panela, slici se dodeljuju oznake 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);

Izgleda da se medija povezuje tek nakon preliminarnog čuvanja proizvoda i ponovnog dobijanja iz repozitorijuma. Takođe je potrebno navesti atribut label Pri dodajanju zapisa v medijsko galerijo produkta (drugače dobimo izjemo Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Kategorije

Struktura kategorij trgovine in backend aplikacije ali postavitev izdelkov v njih se lahko precej razlikujeta. Strategije prenosa podatkov o kategorijah in izdelkih v njih so odvisne od mnogih dejavnikov. V tem primeru sledim naslednjemu:

  • kategorije backend-a in trgovine se primerjajo po imenu;
  • če se uvaža kategorija, ki ne obstaja v trgovini, se ustvari pod osnovno kategorijo (Default Category) in njeno nadaljnje pozicioniranje v katalogu trgovine je predvideno ročno;
  • povezava produkta s kategorijo se zgodi le ob njegovem ustvarjanju v trgovini (pri prvem uvozu);

Osnovni podatki o kategoriji se nahajajo v tabeli catalog_category_entity (katalog kategorij). Ustvarjanje kategorije v Magento:

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

Povezava produkta s kategorijo se izvaja po ID-ju kategorije in SKU produkta:

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

Ukupno

Napisati kodo za dodajanje produkta v Magento 2 programatično ni preveč zapleteno. Vse zgoraj navedeno sem združil v demo-modul «flancer32/mage2_ext_demo_import«. V modulu je le ena konzolna ukazna vrstica fl32:import:prod, ki uvaža produkte, opisane v JSON datoteki «./etc/data/products.json«:

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

Slike za uvoz se nahajajo v direktoriju ./etc/data/img.

Čas uvoza 10 izdelkov na ta način znaša okoli 10 sekund na mojem prenosniku. Če to razširimo, lahko enostavno ugotovimo, da lahko na uro uvozimo okoli 3600 izdelkov, medtem ko bi za uvoz 100K izdelkov potrebovali okoli 30 ur. Zamenjava prenosnika s strežnikom lahko nekoliko izboljša situacijo. Morda celo za nekajkrat. Vendar ne za red velikosti. Morda je ta hitrost počasnosti deloma razlog za pojav projekta magento/async-import.

Drastična rešitev za povečanje hitrosti uvoza je neposredna zapis v bazo, vendar v tem primeru izgubimo vse "bonuse", ki se nanašajo na razširljivost Magento - vse "razširjeno" boste morali narediti sami. Kljub temu je to vredno. Če bo mogoče, bom v naslednjem članku preučil pristop z neposrednim zapisom v BDP.

Izvor: habr.com

Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki 🔥 Kupite zanesljivo gostovanje za spletne strani z zaščito pred DDoS, VPS VDS strežniki | ProHoster