Magento 2: Mengimpor Produk dari Sumber Eksternal

Magento adalah solusi e-commerce, mis. lebih ditujukan untuk menjual produk dibandingkan pergudangan, logistik atau akuntansi keuangan yang menyertai penjualan. Aplikasi lain (misalnya, sistem ERP) lebih cocok untuk aplikasi pendamping. Oleh karena itu, cukup sering dalam praktik penggunaan Magento, muncul tugas untuk mengintegrasikan penyimpanan dengan sistem lain ini (misalnya, 1C).

Secara umum, integrasi dapat direduksi menjadi replikasi data dengan:

  • katalog (produk, kategori);
  • data inventaris (saldo produk di gudang dan harga);
  • klien;
  • pesanan;

Magento menawarkan kelas objek terpisah untuk memanipulasi data dalam database - repositori. Karena kekhasan Magento, menambahkan data ke database melalui repositori mudah untuk dikodekan, namun, katakanlah, lambat. Dalam publikasi ini, saya mempertimbangkan tahapan utama menambahkan produk secara terprogram ke Magento 2 dengan cara "klasik" - menggunakan kelas repo.

Pelanggan dan pesanan biasanya direplikasi ke arah lain - dari Magento ke sistem ERP eksternal. Oleh karena itu, lebih mudah dengan mereka, di sisi Magento Anda hanya perlu memilih data yang sesuai, lalu β€œpeluru terbang keluar dari sisi kami".

Prinsip pencatatan data ke dalam database

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

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

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

dan penulisan ke database dilakukan melalui Gudang:

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

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

Pendekatan "Pabrik" dan "Repositori" dapat digunakan untuk semua model utama di domain Magento 2.

Informasi Produk Dasar

Saya sedang melihat struktur data yang cocok dengan versi Magento 2.3. Informasi paling dasar tentang produk ada di tabel catalog_product_entity (registrasi produk):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

Saya terbatas pada satu jenis produk (type_id='simple'), satu set atribut default (attribute_set_id=4) dan abaikan atribut has_options ΠΈ required_options. Sejak atributnya entity_id, created_at ΠΈ updated_at dihasilkan secara otomatis, lalu sebenarnya untuk menambahkan produk baru kita hanya perlu mengaturnya sku. Saya melakukan ini:

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

dan saya mendapatkan pengecualian:

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

Saya menambahkan nama produk ke permintaan dan mendapat pesan bahwa atributnya hilang Price. Setelah menambahkan harga, produk ditambahkan ke database:

$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 produk varchar (catalog_product_entity_varchar), harga - di tabel catalog_product_entity_decimal. Sebelum menambahkan produk, disarankan untuk secara eksplisit menunjukkan bahwa kami menggunakan etalase administratif untuk mengimpor data:

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

Atribut Tambahan

Memproses atribut produk tambahan menggunakan Magento adalah suatu kesenangan. Model data EAV untuk entitas utama (lihat tabel eav_entity_type) adalah salah satu fitur utama platform ini. Kami cukup menambahkan 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 yang tersedia. Di Magento 2.3, struktur dalam database yang menggambarkan format untuk menyimpan data inventaris adalah berbeda secara signifikan dari apa yang terjadi sebelumnya. Namun, menambahkan jumlah produk dalam stok melalui model produk tidak lebih sulit dibandingkan menambahkan atribut lainnya:

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

Media

Biasanya, dukungan media untuk suatu produk untuk klien di toko (e-commerce) berbeda dengan dukungan media untuk produk yang sama untuk karyawan dalam sistem akuntansi internal (ERP). Dalam kasus pertama, disarankan untuk menunjukkan produk secara langsung, dalam kasus kedua, cukup memberikan gambaran umum tentang produk. Namun, mentransfer setidaknya gambar utama suatu produk adalah hal yang cukup umum. case saat mengimpor data.

Saat menambahkan gambar melalui panel admin, gambar tersebut disimpan terlebih dahulu di direktori sementara (./pub/media/tmp/catalog/product) dan hanya ketika menyimpan produk dipindahkan ke direktori media (./pub/media/catalog/product). Selain itu, ketika ditambahkan melalui panel admin, gambar tersebut diberi tag 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);

Untuk beberapa alasan, media ditautkan hanya setelah pertama kali menyimpan produk dan mengambilnya kembali dari repositori. Dan Anda perlu menentukan atributnya label saat menambahkan entri ke galeri media produk (jika tidak, kami mendapat pengecualian 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 berbeda secara signifikan. Strategi untuk memigrasikan data tentang kategori dan produk di dalamnya bergantung pada banyak faktor. Dalam contoh ini saya berpegang pada yang berikut:

  • kategori backend dan toko dibandingkan berdasarkan nama;
  • jika suatu kategori diimpor yang tidak ada di toko, maka kategori tersebut dibuat di bawah kategori root (Default Category) dan penempatan selanjutnya dalam katalog toko diasumsikan secara manual;
  • suatu produk ditugaskan ke suatu kategori hanya ketika dibuat di toko (impor pertama);

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

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

Menautkan produk ke suatu kategori dilakukan dengan menggunakan ID kategori dan SKU produk:

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

Total

Menulis kode untuk menambahkan produk secara terprogram ke Magento 2 cukup mudah. Saya telah menggabungkan semua yang disebutkan di atas ke dalam modul demo β€œflancer32/mage2_ext_demo_import". Hanya ada satu perintah konsol dalam modul 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 untuk diimpor ada di katalog ./etc/data/img.

Waktu untuk mengimpor 10 produk menggunakan cara ini sekitar 10 detik di laptop saya. Jika kita mengembangkan ide ini lebih jauh, mudah untuk menyimpulkan bahwa sekitar 3600 produk dapat diimpor per jam, dan diperlukan waktu sekitar 100 jam untuk mengimpor 30 ribu produk. Mengganti laptop dengan server memungkinkan Anda untuk memperlancar situasi. Bahkan mungkin beberapa kali. Tapi tidak berdasarkan besarnya. Mungkin kecepatan dan kelambatan ini sampai batas tertentu menjadi salah satu alasan munculnya proyek ini magento/async-import.

Solusi radikal untuk meningkatkan kecepatan impor bisa berupa entri langsung ke database, tetapi dalam kasus ini semua β€œkeuntungan” mengenai ekstensibilitas Magento hilang - Anda harus melakukan semuanya β€œlanjutan” sendiri. Namun, itu sepadan. Jika berhasil, saya akan mempertimbangkan pendekatan dengan menulis langsung ke database di artikel berikutnya.

Sumber: www.habr.com

Tambah komentar