Magento 2: mengimpor produk dari sumber eksternal

Magento adalah solusi e-commerce, mis. lebih fokus pada penjualan produk daripada pada penjualan gudang, logistik atau akuntansi keuangan yang menyertainya. Aplikasi lain (seperti sistem ERP) lebih cocok untuk teman. Oleh karena itu, cukup sering dalam praktik menggunakan Magento, tugas mengintegrasikan toko dengan sistem lain ini (misalnya, dengan 1C) muncul.


Secara umum, integrasi dapat direduksi menjadi replikasi data dengan:


  • katalog (produk, kategori);
  • data inventaris (stok produk di gudang dan harga);
  • untuk pelanggan;
  • pesanan;

Magento untuk memanipulasi data dalam database menawarkan kelas objek yang berbeda - repositori . Karena kekhasan Magento, menambahkan data ke database melalui repositori mudah dikodekan, tetapi itu terjadi, katakanlah, tidak dengan cepat. Dalam publikasi ini, saya mempertimbangkan tahap-tahap utama dari menambahkan program secara terprogram ke Magento 2 dengan cara "klasik" - menggunakan kelas repo.


Pelanggan dan pesanan biasanya direplikasi ke pihak lain - dari Magento ke sistem ERP eksternal. Oleh karena itu, lebih mudah dengan mereka, di sisi Magento, Anda hanya perlu memilih data yang sesuai, dan kemudian " peluru ditembakkan dari pihak kami ".


Prinsip penulisan data ke database


Saat ini, pembuatan objek yang disimpan dalam database secara terprogram di Magento dilakukan melalui Pabrik :


function __construct (\Magento\Cms\Model\BlockFactory $blockFactory) { $this->blockFactory = $blockFactory; } /** @var \Magento\Cms\Model\Block $block */ $block = $this->blockFactory->create(); 

dan menulis ke database melalui Repositori :


 function __construct (\Magento\Cms\Api\BlockRepositoryInterface $blockRepo) { $this->blockRepo = $blockRepo; } $this->blockRepo->save($block); 

Pendekatan Factory and Repository dapat digunakan untuk semua model utama di area subjek Magento 2.


Informasi Produk Dasar


Saya sedang mempertimbangkan struktur data yang sesuai dengan Magento 2.3. Informasi produk paling dasar ada di tabel catalog_product_entity (registri produk):


 entity_id attribute_set_id type_id sku has_options required_options created_at updated_at 

Saya membatasi type_id='simple' satu jenis produk ( type_id='simple' ), satu set attribute_set_id=4 default ( attribute_set_id=4 ) dan mengabaikan atribut has_options dan required_options . Karena atribut entity_id , created_at dan updated_at dihasilkan secara otomatis, maka, pada dasarnya, kita hanya perlu menentukan sku untuk menambahkan produk baru. Saya melakukan ini:


 /** @var \Magento\Catalog\Api\Data\ProductInterfaceFactory $factProd */ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $repoProd */ /** @var \Magento\Catalog\Api\Data\ProductInterface $prod */ $prod = $factProd->create(); $prod->setAttributeSetId(4); $prod->setTypeId('simple'); $prod->setSku($sku); $repoProd->save($prod); 

dan dapatkan pengecualian:


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

Saya menambahkan nama produk ke permintaan dan saya mendapat pesan bahwa atribut Price tidak ada. Setelah menambahkan harga, produk masuk ke dalam basis data:


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

Nama produk disimpan dalam tabel atribut varchar produk ( catalog_product_entity_varchar ), harga disimpan dalam tabel catalog_product_entity_decimal . Sebelum menambahkan produk, disarankan untuk secara eksplisit menunjukkan bahwa kami menggunakan etalase administratif untuk mengimpor data:


 /** @var \Magento\Store\Model\StoreManagerInterface $manStore */ $manStore->setCurrentStore(0); 

Atribut Tambahan


Memproses atribut produk tambahan dengan Magento adalah suatu kesenangan. Model data EAV untuk entitas inti (lihat tabel eav_entity_type ) adalah salah satu fitur utama platform ini. Cukup tambahkan atribut yang sesuai ke model produk:


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

dan saat menyimpan model melalui objek repo:


 $repoProd->save($prod); 

atribut tambahan juga akan disimpan dalam tabel database yang sesuai.


Data inventaris


Secara sederhana - jumlah produk dalam persediaan. Dalam Magento 2.3, struktur basis data yang menggambarkan format untuk menyimpan data inventaris berbeda secara signifikan dari sebelumnya. Namun, menambahkan jumlah produk dalam persediaan melalui model produk tidak jauh lebih sulit daripada menambahkan atribut lainnya:


 /** @var \Magento\Catalog\Model\Product $prodEntity */ /** @var \Magento\Catalog\Api\ProductRepositoryInterface $repoProd */ $inventory = [ 'is_in_stock' => true, 'qty' => 1234 ]; $prodEntity->setData('quantity_and_stock_status', $inventory); $repoProd->save($prodEntity); 

Media


Sebagai aturan, dukungan media untuk produk untuk pelanggan di toko (e-commerce) berbeda dari dukungan media untuk produk yang sama untuk karyawan dalam sistem akuntansi internal (ERP). Dalam kasus pertama, diinginkan untuk menunjukkan "wajah produk", di kedua - itu sudah cukup untuk memberikan gambaran umum tentang produk. Namun demikian, transfer setidaknya gambar utama produk adalah case cukup umum ketika mengimpor data.


Saat menambahkan gambar melalui panel admin, gambar pertama kali disimpan dalam direktori sementara ( ./pub/media/tmp/catalog/product ) dan hanya ketika produk disimpan dipindahkan ke direktori media ( ./pub/media/catalog/product ). Juga, ketika menambahkan melalui small_image admin, gambar diatur ke image , small_image , thumbnail , swatch_image .


 /** @var \Magento\Catalog\Api\ProductRepositoryInterface $repoProd */ /** @var \Magento\Catalog\Model\Product\Gallery\CreateHandler $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); 

Untuk beberapa alasan, media diikat hanya setelah penyimpanan awal dan menerimanya dari repositori lagi. Dan Anda perlu menentukan atribut label saat menambahkan entri ke galeri media produk (jika tidak, kita mendapatkan pengecualian Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516 ditentukan Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516 ).


Kategori


Seringkali struktur kategori toko dan aplikasi backend atau penempatan produk di dalamnya dapat sangat bervariasi. Strategi untuk mentransfer data tentang kategori dan produk di dalamnya tergantung pada banyak faktor. Dalam contoh ini, saya tetap pada yang berikut:


  • kategori backend dan store dibandingkan dengan nama;
  • jika suatu kategori diimpor yang tidak ada di toko, maka ia dibuat di bawah kategori root ( Default Category ) dan pemosisian lebih lanjutnya dalam katalog toko diasumsikan secara manual;
  • suatu produk ditugaskan untuk suatu kategori hanya ketika itu dibuat di toko (impor pertama);

Informasi kategori dasar ada di tabel catalog_category_entity (katalog kategori). Membuat Kategori di Magento:


 /** @var \Magento\Catalog\Api\Data\CategoryInterfaceFactory $factCat */ /** @var \Magento\Catalog\Api\CategoryRepositoryInterface $repoCat */ $cat = $factCat->create(); $cat->setName($name); $cat->setIsActive(true); $repoCat->save($cat); 

Produk ini diberikan ke kategori berdasarkan ID kategori dan SKU produk:


 /** @var \Magento\Catalog\Model\CategoryProductLinkFactory $factCatProdLink */ /** @var \Magento\Catalog\Api\CategoryLinkRepositoryInterface $repoCatLink */ $link = $factCatProdLink->create(); $link->setCategoryId($catMageId); $link->setSku($prodSku); $repoCatLink->save($link); 

Total


Menulis kode untuk menambahkan produk ke Magento 2 secara pemrograman sangat mudah. Semua hal di atas, saya telah mengurangi ke modul demo " flancer32 / mage2_ext_demo_import ". Hanya ada satu fl32:import:prod konsol di fl32:import:prod , yang mengimpor produk yang dijelaskan dalam file JSON " ./etc/data/products.json ":


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

Gambar yang akan diimpor terletak di direktori ./etc/data/img .


Waktu impor 10 produk dengan cara ini adalah sekitar 10 detik pada laptop saya. Jika kita mengembangkan ide ini lebih lanjut, mudah untuk menyimpulkan bahwa sekitar 3.600 produk dapat diimpor per jam, dan sekitar 30 jam dapat diambil untuk mengimpor 100 ribu produk. Mengganti laptop dengan server memungkinkan Anda untuk sedikit meringankan situasi. Mungkin bahkan kadang-kadang. Tapi tidak atas perintah besarnya. Mungkin ini kecepatan lambatnya sampai batas tertentu merupakan salah satu alasan munculnya proyek impor magento / async .


Keputusan utama untuk meningkatkan kecepatan impor mungkin adalah untuk menulis langsung ke database, tetapi dalam hal ini semua "roti" tentang perpanjangan Magento hilang - Anda harus melakukan semuanya "maju" sendiri. Namun, itu sepadan. Jika berhasil, maka saya akan mempertimbangkan pendekatan dengan pencatatan langsung dalam database di artikel berikutnya.

Source: https://habr.com/ru/post/id436020/


All Articles