Magento 2: uvoz proizvoda iz eksternih izvora

Magento je rješenje za e-trgovinu, tj. je više usmjeren na prodaju proizvoda nego na skladištenje, logistiku ili financijsko računovodstvo koje prati prodaju. Druge aplikacije (na primjer, ERP sistemi) su pogodnije za prateće aplikacije. Stoga se vrlo često u praksi korištenja Magenta javlja zadatak integracije trgovine sa ovim drugim sistemima (na primjer, 1C).

Uglavnom, integracija se može svesti na replikaciju podataka:

  • katalog (proizvodi, kategorije);
  • podaci o zalihama (stanja proizvoda u skladištima i cijene);
  • klijenti;
  • naredbe;

Magento nudi posebnu klasu objekata za manipulaciju podacima u bazi podataka - spremišta. Zbog specifičnosti Magenta, dodavanje podataka u bazu podataka preko repozitorija je lako kodirati, ali je, recimo, sporo. U ovoj publikaciji razmatram glavne faze programskog dodavanja proizvoda u Magento 2 na "klasičan" način - korištenjem repo klasa.

Kupci i narudžbe se obično repliciraju u drugom smjeru - od Magenta do eksternih ERP sistema. Stoga je s njima jednostavnije, na Magento strani samo trebate odabrati odgovarajuće podatke, a zatim “meci su izletjeli sa naše strane".

Principi upisivanja podataka u bazu podataka

Trenutno se kreiranje objekata spremljenih u bazi podataka programski u Magentu obavlja kroz tvornica:

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

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

a upisivanje u bazu podataka se vrši kroz Repozitorij:

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

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

Pristup "Fabrika" i "Repozitorijum" se može koristiti za sve glavne modele u Magento 2 domenu.

Osnovne informacije o proizvodu

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

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Ograničen sam na jednu vrstu proizvoda (type_id='simple'), skup zadanih atributa (attribute_set_id=4) i zanemarite atribute has_options и required_options. Pošto su atributi entity_id, created_at и updated_at se generiraju automatski, onda, zapravo, da bismo dodali novi proizvod, samo trebamo postaviti sku. radim ovo:

/** @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 dobijam izuzetak:

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

U zahtjev dodam naziv proizvoda i dobijem poruku da atribut nedostaje Price. Nakon dodavanja cijene, proizvod se dodaje u bazu podataka:

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

Naziv proizvoda je pohranjen u tabeli atributa varchar proizvoda (catalog_product_entity_varchar), cijena - u tabeli catalog_product_entity_decimal. Prije dodavanja proizvoda, preporučljivo je eksplicitno naznačiti da koristimo administrativni izlog za uvoz podataka:

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

Dodatni atributi

Obrada dodatnih atributa proizvoda koristeći Magento je zadovoljstvo. EAV model podataka za glavne entitete (vidi tabelu eav_entity_type) je jedna od ključnih karakteristika ove platforme. Jednostavno dodajemo odgovarajuće atribute modelu proizvoda:

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

i kada spremate model preko repo objekta:

$repoProd->save($prod);

dodatni atributi će također biti pohranjeni u odgovarajućim tablicama baze podataka.

Podaci o zalihama

Jednostavno rečeno - količina proizvoda na zalihama. U Magentu 2.3, strukture u bazi podataka koje opisuju format za pohranjivanje podataka inventara su značajno drugačije od onoga što se desilo ranije. Međutim, dodavanje količine proizvoda na zalihi putem modela proizvoda nije mnogo teže 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);

Mediji

Po pravilu se medijska podrška za proizvod za klijenta u trgovini (e-commerce) razlikuje od medijske podrške za isti proizvod za zaposlenika u internom računovodstvenom sistemu (ERP). U prvom slučaju, preporučljivo je pokazati proizvod licem u lice, u drugom je dovoljno dati opću predstavu o proizvodu. Međutim, prijenos barem primarne slike proizvoda je prilično uobičajen. case prilikom uvoza podataka.

Prilikom dodavanja slike preko admin panela, slika se prvo sprema u privremeni direktorij (./pub/media/tmp/catalog/product) i samo prilikom pohranjivanja proizvod se premješta u medijski direktorij (./pub/media/catalog/product). Takođe, kada se doda preko admin panela, slika je 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 nekog razloga, medij se povezuje tek nakon prvog spremanja proizvoda i ponovnog preuzimanja iz spremišta. I morate navesti atribut label prilikom dodavanja unosa u galeriju medija proizvoda (inače dobijamo izuzetak Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Kategorije

Često se struktura kategorije trgovine i pozadinske aplikacije ili smještaj proizvoda u njima može značajno razlikovati. Strategije za migraciju podataka o kategorijama i proizvodima unutar njih zavise od mnogih faktora. U ovom primjeru držim se sljedećeg:

  • backend i store kategorije se upoređuju po imenu;
  • ako se uvozi kategorija koja nije u prodavnici, onda se kreira pod osnovnom kategorijom (Default Category) a njegovo dalje pozicioniranje u katalogu trgovine se pretpostavlja ručno;
  • proizvod se dodjeljuje kategoriji samo kada je kreiran u prodavnici (prvi uvoz);

Osnovne informacije o kategoriji nalaze se u tabeli catalog_category_entity (katalog kategorija). Kreiranje kategorije u Magento:

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

Povezivanje proizvoda sa kategorijom vrši se pomoću ID-a kategorije i SKU proizvoda:

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

Ukupno

Pisanje koda za programsko dodavanje proizvoda u Magento 2 je prilično jednostavno. Kombinovao sam sve gore navedeno u demo modul “flancer32/mage2_ext_demo_import". Postoji samo jedna konzolna komanda u modulu fl32:import:prod, koji uvozi proizvode opisane u JSON datoteci "./etc/data/products.json":

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

Slike za uvoz su u katalogu ./etc/data/img.

Vrijeme za uvoz 10 proizvoda pomoću ove metode je oko 10 sekundi na mom laptopu. Ako ovu ideju dalje razvijamo, lako je doći do zaključka da se na sat može uvesti oko 3600 proizvoda, a za uvoz 100 proizvoda može biti potrebno oko 30 sati. Zamjena laptopa serverom omogućava vam da donekle izgladite situaciju. Možda čak i nekoliko puta. Ali ne po redovima veličine. Možda je ta brzina i sporost u određenoj mjeri jedan od razloga za nastanak projekta magento/async-import.

Radikalno rješenje za povećanje brzine uvoza mogao bi biti direktan ulazak u bazu podataka, ali u ovom slučaju se gube sve "dobrote" u vezi sa proširivosti Magenta - sve ćete morati sami učiniti "napredno". Međutim, isplati se. Ako uspije, razmotrit ću pristup s direktnim pisanjem u bazu podataka u sljedećem članku.

izvor: www.habr.com

Dodajte komentar