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; } $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.
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:
$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:
$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);
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:
$inventory = [ 'is_in_stock' => true, 'qty' => 1234 ]; $prodEntity->setData('quantity_and_stock_status', $inventory); $repoProd->save($prodEntity);
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
.
$imagePathRelative = $this->imagePlaceToTmpMedia($imagePath); $product = $repoProd->get($sku); $gallery['images'][] = [ 'file' => $imagePathRelative, 'media_type' => 'image' 'label' => '' ]; $product->setData('media_gallery', $gallery); $product->setData('image', $imagePathRelative); $product->setData('small_image', $imagePathRelative); $product->setData('thumbnail', $imagePathRelative); $product->setData('swatch_image', $imagePathRelative); $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:
$cat = $factCat->create(); $cat->setName($name); $cat->setIsActive(true); $repoCat->save($cat);
Produk ini diberikan ke kategori berdasarkan ID kategori dan SKU produk:
$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.