Magento 2: Importimi i produkteve nga burime të jashtme

Magento është një zgjidhje e-commerce, d.m.th. ka për qëllim më shumë shitjen e produkteve sesa deponimin, logjistikën apo kontabilitetin financiar që shoqëron shitjet. Aplikacionet e tjera (për shembull, sistemet ERP) janë më të përshtatshme për aplikacionet shoqëruese. Prandaj, mjaft shpesh në praktikën e përdorimit të Magento lind detyra e integrimit të një dyqani me këto sisteme të tjera (për shembull, 1C).

Në përgjithësi, integrimi mund të reduktohet në përsëritjen e të dhënave duke:

  • katalog (produkte, kategori);
  • të dhënat e inventarit (balancat e produkteve në magazina dhe çmimet);
  • klientët;
  • porositë;

Magento ofron një klasë të veçantë objektesh për manipulimin e të dhënave në bazën e të dhënave - depove. Për shkak të specifikave të Magento, shtimi i të dhënave në bazën e të dhënave përmes depove është i lehtë për t'u koduar, por është, le të themi, i ngadalshëm. Në këtë botim, unë konsideroj fazat kryesore të shtimit programatik të një produkti në Magento 2 në mënyrën "klasike" - duke përdorur klasa repo.

Klientët dhe porositë zakonisht përsëriten në drejtimin tjetër - nga Magento në sistemet ERP të jashtme. Prandaj, është më e lehtë me ta, në anën Magento thjesht duhet të zgjidhni të dhënat e duhura, dhe më pas "plumbat dolën nga ana jonë".

Parimet e regjistrimit të të dhënave në një bazë të dhënash

Për momentin, krijimi i objekteve të ruajtura në bazën e të dhënave në mënyrë programore në Magento bëhet përmes fabrikë:

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

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

dhe shkrimi në bazën e të dhënave bëhet përmes depo:

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

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

Qasja "Fabrika" dhe "Depoja" mund të përdoren për të gjitha modelet kryesore në domenin Magento 2.

Informacioni bazë i produktit

Po shikoj një strukturë të dhënash që përputhet me versionin Magento 2.3. Informacioni më bazë për produktin është në tabelë catalog_product_entity (regjistri i produktit):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Unë jam i kufizuar në një lloj produkti (type_id='simple'), një grup atributesh të paracaktuar (attribute_set_id=4) dhe injoroni atributet has_options и required_options. Që nga atributet entity_id, created_at и updated_at gjenerohen automatikisht, atëherë, në fakt, për të shtuar një produkt të ri, ne vetëm duhet të vendosim sku. Unë e bëj këtë:

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

dhe kam një përjashtim:

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

Unë shtoj emrin e produktit në kërkesë dhe marr një mesazh që atributi mungon Price. Pas shtimit të çmimit, produkti shtohet në bazën e të dhënave:

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

Emri i produktit ruhet në tabelën e atributeve të produktit varchar (catalog_product_entity_varchar), çmimi - në tabelë catalog_product_entity_decimal. Përpara se të shtoni një produkt, këshillohet të tregoni në mënyrë eksplicite se ne po përdorim vitrinën administrative për të importuar të dhëna:

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

Atribute shtesë

Përpunimi i atributeve shtesë të produktit duke përdorur Magento është një kënaqësi. Modeli i të dhënave EAV për entitetet kryesore (shih tabelën eav_entity_type) është një nga veçoritë kryesore të kësaj platforme. Ne thjesht i shtojmë atributet e duhura modelit të produktit:

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

dhe kur ruani modelin përmes objektit repo:

$repoProd->save($prod);

atributet shtesë do të ruhen gjithashtu në tabelat përkatëse të bazës së të dhënave.

Të dhënat e inventarit

Me fjalë të thjeshta - sasia e produktit në magazinë. Në Magento 2.3, strukturat në bazën e të dhënave që përshkruajnë formatin për ruajtjen e të dhënave të inventarit janë dukshëm të ndryshme nga ajo që ndodhi më parë. Megjithatë, shtimi i sasisë së një produkti në magazinë nëpërmjet modelit të produktit nuk është shumë më i vështirë sesa shtimi i atributeve të tjera:

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

media

Si rregull, mbështetja mediatike për një produkt për një klient në një dyqan (e-commerce) ndryshon nga mbështetja mediatike për të njëjtin produkt për një punonjës në një sistem të brendshëm të kontabilitetit (ERP). Në rastin e parë, këshillohet që produkti të tregohet ballë për ballë; në të dytin, mjafton të jepet një ide e përgjithshme e produktit. Megjithatë, transferimi i të paktën imazhit primar të një produkti është mjaft i zakonshëm. case kur importoni të dhëna.

Kur shtoni një imazh përmes panelit të administratorit, imazhi së pari ruhet në një direktori të përkohshme (./pub/media/tmp/catalog/product) dhe vetëm kur ruani produktin zhvendoset në drejtorinë e mediave (./pub/media/catalog/product). Gjithashtu, kur shtohet përmes panelit të administratorit, imazhi është etiketuar 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);

Për disa arsye, media lidhet vetëm pasi të ruhet fillimisht produkti dhe të merret përsëri nga depoja. Dhe ju duhet të specifikoni atributin label kur shtojmë një hyrje në galerinë e mediave të produktit (përndryshe marrim një përjashtim Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

Kategoritë

Shpesh, struktura e kategorisë së dyqanit dhe aplikacioni i backend-it ose vendosja e produkteve në to mund të ndryshojnë ndjeshëm. Strategjitë për migrimin e të dhënave për kategoritë dhe produktet brenda tyre varen nga shumë faktorë. Në këtë shembull i përmbahem sa vijon:

  • kategoritë e backend dhe të dyqaneve krahasohen me emër;
  • nëse importohet një kategori që nuk është në dyqan, atëherë ajo krijohet nën kategorinë rrënjë (Default Category) dhe pozicionimi i tij i mëtejshëm në katalogun e dyqaneve supozohet manualisht;
  • një produkt i caktohet një kategorie vetëm kur krijohet në dyqan (importi i parë);

Informacioni bazë për kategorinë është në tabelë catalog_category_entity (katalog i kategorive). Krijimi i një kategorie në Magento:

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

Lidhja e një produkti me një kategori kryhet duke përdorur ID-në e kategorisë dhe SKU të produktit:

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

Në total

Shkrimi i kodit për të shtuar një produkt në mënyrë programore në Magento 2 është mjaft i lehtë. Unë kam kombinuar gjithçka që u tha më sipër në një modul demo "flancer32/mage2_ext_demo_import". Ekziston vetëm një komandë e konsolës në modul fl32:import:prod, i cili importon produktet e përshkruara në skedarin JSON "./etc/data/products.json':

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

Fotot për import janë në katalog ./etc/data/img.

Koha për të importuar 10 produkte duke përdorur këtë metodë është rreth 10 sekonda në laptopin tim. Nëse e zhvillojmë këtë ide më tej, është e lehtë të arrijmë në përfundimin se mund të importohen rreth 3600 produkte në orë dhe mund të duhen rreth 100 orë për të importuar 30 mijë produkte. Zëvendësimi i një laptopi me një server ju lejon të zbutni disi situatën. Ndoshta edhe disa herë. Por jo sipas urdhrave të përmasave. Ndoshta kjo shpejtësi dhe ngadalësi është deri diku një nga arsyet e shfaqjes së projektit magento/async-import.

Një zgjidhje radikale për të rritur shpejtësinë e importit mund të jetë hyrja e drejtpërdrejtë në bazën e të dhënave, por në këtë rast të gjitha "të mirat" në lidhje me shtrirjen e Magento humbasin - do të duhet të bëni gjithçka "të avancuar" vetë. Megjithatë, ia vlen. Nëse funksionon, do të shqyrtoj qasjen me shkrim të drejtpërdrejtë në bazën e të dhënave në artikullin tjetër.

Burimi: www.habr.com

Shto një koment