Magento 2: kanpoko iturrietatik produktuak inportatzea

Magento merkataritza elektronikoko irtenbide bat da, hau da. produktuak saltzera zuzenduta dago biltegira, logistika edo finantza-kontabilitate salmentarekin batera baino. Beste aplikazio batzuk (adibidez, ERP sistemak) hobeto egokitzen dira horrekin batera dauden aplikazioetarako. Horregatik, sarritan Magento erabiltzeko praktikan denda bat beste sistema hauekin (adibidez, 1C) integratzeko zeregina sortzen da.

Orokorrean, integrazioa datuen erreplikaziora murriztu daiteke:

  • katalogoa (produktuak, kategoriak);
  • inbentarioaren datuak (biltegietako produktuen balantzeak eta prezioak);
  • bezeroak;
  • aginduak;

Magentok objektu-klase bereizi bat eskaintzen du datu-baseko datuak manipulatzeko - biltegiak. Magentoren berezitasunak direla eta, datu-baseari biltegien bidez gehitzea erraza da kodetzea, baina, demagun, motela da. Argitalpen honetan, Magento 2-ri produktu bat modu "klasikoan" programatikoki gehitzeko etapa nagusiak kontuan hartzen ditut: repo klaseak erabiliz.

Bezeroak eta eskaerak beste norabide batean errepikatu ohi dira - Magentotik kanpoko ERP sistemetara. Hori dela eta, errazagoa da haiekin, Magento aldean datu egokiak hautatu besterik ez duzu behar, eta gero "balak atera ziren gure albotik".

Datuak datu-base batean erregistratzeko printzipioak

Momentuz, Magento-n datu-basean gordetako objektuak programatikoki sortzearen bidez egiten da Factory:

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

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

eta datu basera idaztea bidez egiten da Biltegi:

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

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

"Factory" eta "Repository" ikuspegia Magento 2 domeinuko modelo nagusi guztietan erabil daiteke.

Produktuaren oinarrizko informazioa

Magento 2.3 bertsioarekin bat datorren datu-egitura bat aztertzen ari naiz. Produktuari buruzko informazio oinarrizkoena taulan dago catalog_product_entity (produktuen erregistroa):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Produktu mota batera mugatzen naiz (type_id='simple'), atributu lehenetsien multzoa (attribute_set_id=4) eta ez ikusi atributuak has_options ΠΈ required_options. Atributuak geroztik entity_id, created_at ΠΈ updated_at automatikoki sortzen dira, orduan, hain zuzen ere, produktu berri bat gehitzeko, ezarri besterik ez dugu behar sku. Hau egiten dut:

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

eta salbuespen bat jasotzen dut:

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

Produktuaren izena gehitzen diot eskaerari eta atributua falta dela dioen mezua jasotzen dut Price. Prezioa gehitu ondoren, produktua datu-basera gehitzen da:

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

Produktuaren izena produktuaren varchar atributuen taulan gordetzen da (catalog_product_entity_varchar), prezioa - taulan catalog_product_entity_decimal. Produktu bat gehitu aurretik, gomendagarria da esplizituki adieraztea administrazio erakusleihoa erabiltzen ari garela datuak inportatzeko:

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

Atributu gehigarriak

Produktu-atributu gehigarriak Magento erabiliz prozesatzea plazer bat da. Entitate nagusien EAV datu-eredua (ikus taula eav_entity_type) plataforma honen ezaugarri nagusietako bat da. Produktu ereduari atributu egokiak gehitzen dizkiogu:

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

eta eredua repo objektuaren bidez gordetzean:

$repoProd->save($prod);

atributu gehigarriak dagozkien datu-base tauletan ere gordeko dira.

Inbentarioaren datuak

Termino sinpleetan - stockean dagoen produktuaren zenbatekoa. Magento 2.3-n, inbentario-datuak gordetzeko formatua deskribatzen duten datu-baseko egiturak dira nabarmen desberdinak aurretik gertatu zenetik. Hala ere, produktuaren ereduaren bidez stockean dagoen produktuaren kantitatea gehitzea ez da beste atributu batzuk gehitzea baino zailagoa:

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

media

Oro har, denda bateko bezero batentzako produktu baten euskarria (merkataritza elektronikoa) barneko kontabilitate sistemako (ERP) langile baten produktu beraren euskarria desberdina da. Lehenengo kasuan, produktua aurrez aurre erakustea komeni da; bigarrenean, nahikoa da produktuaren ideia orokorra ematea. Hala ere, produktu baten lehen irudia gutxienez transferitzea nahiko ohikoa da. case datuak inportatzerakoan.

Irudi bat administrazio panelaren bidez gehitzean, irudia behin-behineko direktorio batean gordetzen da lehenik (./pub/media/tmp/catalog/product) eta produktua gordetzean soilik mugitzen da multimedia direktoriora (./pub/media/catalog/product). Gainera, administrazio panelaren bidez gehitzen denean, irudia etiketatu egiten da 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);

Arrazoiren batengatik, euskarria lehenik produktua gorde eta biltegitik berriro berreskuratu ondoren soilik lotzen da. Eta atributua zehaztu behar duzu label produktuaren multimedia galerian sarrera bat gehitzean (bestela salbuespen bat jasoko dugu Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

ΠšΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΠΈ

Askotan, dendaren kategoria-egitura eta backend aplikazioa edo produktuen kokapena nabarmen desberdina izan daiteke. Kategoriei eta produktuei buruzko datuak migratzeko estrategiak faktore askoren araberakoak dira. Adibide honetan honako hauei eusten diot:

  • backend eta denda kategoriak izenarekin alderatzen dira;
  • dendan ez dagoen kategoria bat inportatzen bada, erro kategorian sortuko da (Default Category) eta denda katalogoan gehiago kokatzea eskuz hartzen da;
  • produktu bat kategoria bati esleitzen zaio soilik dendan sortzen denean (lehen inportazioa);

Kategoriari buruzko oinarrizko informazioa taulan dago catalog_category_entity (kategorien katalogoa). Kategoria bat sortzea Magento-n:

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

Produktu bat kategoria bati lotzea kategoriako IDa eta produktuaren SKUa erabiliz egiten da:

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

Guztira

Magento 2-ra produktu bat programatikoki gehitzeko kodea idaztea nahiko erraza da. Goian esandako guztia demo modulu batean konbinatu dut "flancer32/mage2_ext_demo_import". Moduluan kontsola komando bakarra dago fl32:import:prod, JSON fitxategian deskribatutako produktuak inportatzen dituena "./etc/data/products.json':

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

Inportatzeko argazkiak katalogoan daude ./etc/data/img.

Metodo hau erabiliz 10 produktu inportatzeko denbora 10 segundo ingurukoa da nire ordenagailu eramangarrian. Ideia hau gehiago garatzen badugu, erraza da ondorioztatzea orduko 3600 produktu inguru inporta daitezkeela eta 100 ordu inguru behar direla 30K produktu inportatzeko. Ordenagailu eramangarri bat zerbitzari batekin ordezkatzeak egoera zertxobait leuntzen du. Agian hainbat aldiz ere bai. Baina ez magnitude-ordenaren arabera. Agian, abiadura eta moteltasun hori da, neurri batean, proiektuaren sorreraren arrazoietako bat magento/async-import.

Inportazio-abiadura handitzeko irtenbide erradikala datu-basean sartzea izan liteke, baina kasu honetan Magentoren hedagarritasunari buruzko "on" guztiak galtzen dira - zuk zeuk egin beharko duzu dena "aurreratuta". Hala ere, merezi du. Funtzionatzen badu, hurrengo artikuluan datu-baserako idazketa zuzenaren planteamendua kontuan hartuko dut.

Iturria: www.habr.com

Gehitu iruzkin berria