Magento 2: Mahsulotlarni tashqi manbalardan import qilish

Magento - bu elektron tijorat yechimi, ya'ni. saqlash, logistika yoki sotish bilan bog'liq moliyaviy hisobdan ko'ra ko'proq mahsulotni sotishga qaratilgan. Boshqa ilovalar (masalan, ERP tizimlari) qo'shimcha ilovalar uchun ko'proq mos keladi. Shuning uchun, Magento-dan foydalanish amaliyotida ko'pincha do'konni ushbu boshqa tizimlar (masalan, 1C) bilan integratsiya qilish vazifasi paydo bo'ladi.

Umuman olganda, integratsiyani quyidagi yo'llar bilan ma'lumotlar replikatsiyasiga qisqartirish mumkin:

  • katalog (mahsulotlar, toifalar);
  • inventarizatsiya ma'lumotlari (omborlardagi mahsulot qoldiqlari va narxlar);
  • mijozlar;
  • buyurtmalar;

Magento ma'lumotlar bazasidagi ma'lumotlarni manipulyatsiya qilish uchun alohida ob'ektlar sinfini taklif qiladi - omborlar. Magento-ning o'ziga xos xususiyatlaridan kelib chiqqan holda, ma'lumotlar bazasiga omborlar orqali ma'lumotlarni qo'shishni kodlash oson, lekin aytaylik, sekin. Ushbu nashrda men Magento 2-ga mahsulotni "klassik" usulda dasturiy ravishda qo'shishning asosiy bosqichlarini ko'rib chiqaman - repo sinflaridan foydalanish.

Mijozlar va buyurtmalar odatda boshqa yo'nalishda - Magento'dan tashqi ERP tizimlarigacha takrorlanadi. Shuning uchun, ular bilan osonroq, Magento tomonida siz faqat tegishli ma'lumotlarni tanlashingiz kerak va keyin "o'qlar biz tomondan uchib chiqdi".

Ma'lumotlar bazasiga ma'lumotlarni yozib olish tamoyillari

Ayni paytda Magento-da dasturiy ravishda ma'lumotlar bazasida saqlangan ob'ektlarni yaratish orqali amalga oshiriladi zavod:

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

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

va ma'lumotlar bazasiga yozish orqali amalga oshiriladi Axborotlar:

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

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

Magento 2 domenidagi barcha asosiy modellar uchun "Zavod" va "Repository" yondashuvidan foydalanish mumkin.

Mahsulot haqida asosiy ma'lumot

Men Magento 2.3 versiyasiga mos keladigan ma'lumotlar tuzilmasini ko'rib chiqyapman. Mahsulot haqidagi eng asosiy ma'lumotlar jadvalda keltirilgan catalog_product_entity (mahsulot reestri):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Men bir turdagi mahsulot bilan chegaralanganman (type_id='simple'), standart atributlar to'plami (attribute_set_id=4) va atributlarga e'tibor bermang has_options и required_options. Atributlardan beri entity_id, created_at и updated_at avtomatik ravishda yaratiladi, keyin, aslida, yangi mahsulot qo'shish uchun, biz faqat sozlashimiz kerak sku. Men buni qilaman:

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

va men istisno qilaman:

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

Men so'rovga mahsulot nomini qo'shaman va atribut etishmayotganligi haqida xabar olaman Price. Narxni qo'shgandan so'ng, mahsulot ma'lumotlar bazasiga qo'shiladi:

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

Mahsulot nomi mahsulotning varchar atributlari jadvalida saqlanadi (catalog_product_entity_varchar), narx - jadvalda catalog_product_entity_decimal. Mahsulotni qoʻshishdan oldin maʼlumotlarni import qilish uchun maʼmuriy vitrinadan foydalanayotganimizni aniq koʻrsatish tavsiya etiladi:

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

Qo'shimcha atributlar

Magento yordamida qo'shimcha mahsulot atributlarini qayta ishlash juda yoqimli. Asosiy ob'ektlar uchun EAV ma'lumotlar modeli (jadvalga qarang eav_entity_type) ushbu platformaning asosiy xususiyatlaridan biridir. Biz shunchaki mahsulot modeliga tegishli atributlarni qo'shamiz:

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

va modelni repo ob'ekti orqali saqlashda:

$repoProd->save($prod);

qo'shimcha atributlar ham tegishli ma'lumotlar bazasi jadvallarida saqlanadi.

Inventarizatsiya ma'lumotlari

Oddiy qilib aytganda - stokdagi mahsulot miqdori. Magento 2.3 da, inventarizatsiya ma'lumotlarini saqlash formatini tavsiflovchi ma'lumotlar bazasidagi tuzilmalar sezilarli darajada farq qiladi oldin sodir bo'lgan narsadan. Biroq, mahsulot modeli orqali stokdagi mahsulot miqdorini qo'shish boshqa atributlarni qo'shishdan ko'ra qiyinroq emas:

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

axborot vositalari

Qoidaga ko'ra, do'kondagi (elektron tijorat) mijoz uchun mahsulotni ommaviy axborot vositalarida qo'llab-quvvatlash ichki buxgalteriya tizimidagi (ERP) xodim uchun bir xil mahsulotni ommaviy axborot vositalarida qo'llab-quvvatlashdan farq qiladi. Birinchi holda, mahsulotni yuzma-yuz ko'rsatish tavsiya etiladi, ikkinchidan, mahsulot haqida umumiy tasavvur berish kifoya. Biroq, mahsulotning hech bo'lmaganda asosiy tasvirini uzatish juda keng tarqalgan. case ma'lumotlarni import qilishda.

Administrator paneli orqali rasm qo'shilganda, rasm avval vaqtinchalik katalogda saqlanadi (./pub/media/tmp/catalog/product) va faqat mahsulot saqlanganda media katalogiga ko'chiriladi (./pub/media/catalog/product). Bundan tashqari, administrator paneli orqali qo'shilganda, rasm teglanadi 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);

Ba'zi sabablarga ko'ra, ommaviy axborot vositalari faqat mahsulotni birinchi marta saqlagandan va uni ombordan qaytadan olgandan keyingina ulanadi. Va siz atributni ko'rsatishingiz kerak label mahsulot media galereyasiga yozuv qo'shganda (aks holda biz istisno qilamiz Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

kategoriya

Ko'pincha, do'konning kategoriya tuzilishi va backend ilovasi yoki ulardagi mahsulotlarni joylashtirish sezilarli darajada farq qilishi mumkin. Ulardagi toifalar va mahsulotlar haqidagi ma'lumotlarni ko'chirish strategiyalari ko'plab omillarga bog'liq. Ushbu misolda men quyidagilarga amal qilaman:

  • backend va do'kon toifalari nomi bo'yicha taqqoslanadi;
  • agar do'konda bo'lmagan toifa import qilingan bo'lsa, u ildiz toifasi ostida yaratiladi (Default Category) va uning do'kon katalogida keyingi joylashuvi qo'lda qabul qilinadi;
  • mahsulot do'konda yaratilgandagina toifaga tayinlanadi (birinchi import);

Kategoriya haqida asosiy ma'lumotlar jadvalda keltirilgan catalog_category_entity (toifalar katalogi). Magento'da kategoriya yaratish:

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

Mahsulotni toifaga ulash toifa identifikatori va mahsulot SKU yordamida amalga oshiriladi:

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

jami

Magento 2 ga dasturiy ravishda mahsulotni qo'shish uchun kod yozish juda oson. Men yuqorida aytilganlarning barchasini demo modulga birlashtirdim "flancer32/mage2_ext_demo_import". Modulda faqat bitta konsol buyrug'i mavjud fl32:import:prodJSON faylida tasvirlangan mahsulotlarni import qiluvchi "./etc/data/products.json":

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

Import uchun rasmlar katalogda ./etc/data/img.

Ushbu usul yordamida 10 ta mahsulotni import qilish vaqti mening noutbukimda taxminan 10 soniya. Agar biz ushbu g'oyani yanada rivojlantiradigan bo'lsak, soatiga 3600 ga yaqin mahsulotni import qilish mumkin, 100 ming mahsulotni import qilish uchun taxminan 30 soat vaqt ketishi mumkin degan xulosaga kelish oson. Noutbukni server bilan almashtirish vaziyatni biroz yumshatish imkonini beradi. Ehtimol, hatto bir necha marta. Lekin kattalik buyrug'i bilan emas. Ehtimol, bu tezlik va sekinlik qaysidir ma'noda loyihaning paydo bo'lishining sabablaridan biridir magento/async-import.

Import tezligini oshirish uchun radikal yechim ma'lumotlar bazasiga to'g'ridan-to'g'ri kirish bo'lishi mumkin, ammo bu holda Magento-ning kengayishi bilan bog'liq barcha "yaxshiliklar" yo'qoladi - siz "ilg'or" hamma narsani o'zingiz qilishingiz kerak bo'ladi. Biroq, bunga arziydi. Agar u ishlayotgan bo'lsa, men keyingi maqolada ma'lumotlar bazasiga to'g'ridan-to'g'ri yozish bilan yondashuvni ko'rib chiqaman.

Manba: www.habr.com

a Izoh qo'shish