Magento 2: การนำเข้าผลิตภัณฑ์จากแหล่งภายนอก

Magento เป็นโซลูชันอีคอมเมิร์ซ เช่น มุ่งเป้าไปที่การขายผลิตภัณฑ์มากกว่าการขายในคลังสินค้า ลอจิสติกส์ หรือการบัญชีการเงิน แอปพลิเคชันอื่นๆ (เช่น ระบบ ERP) เหมาะกว่าสำหรับแอปพลิเคชันประกอบ ดังนั้นบ่อยครั้งในทางปฏิบัติในการใช้ Magento จึงมีงานรวมร้านค้าเข้ากับระบบอื่น ๆ เหล่านี้ (เช่น 1C)

โดยทั่วไปแล้ว การบูรณาการสามารถลดการจำลองข้อมูลลงได้โดย:

  • แคตตาล็อก (ผลิตภัณฑ์, หมวดหมู่);
  • ข้อมูลสินค้าคงคลัง (ยอดคงเหลือสินค้าในคลังสินค้าและราคา)
  • ลูกค้า;
  • คำสั่ง;

Magento เสนอคลาสของวัตถุแยกต่างหากสำหรับจัดการข้อมูลในฐานข้อมูล - ที่เก็บ. เนื่องจากลักษณะเฉพาะของ Magento การเพิ่มข้อมูลลงในฐานข้อมูลผ่านพื้นที่เก็บข้อมูลจึงเป็นเรื่องง่ายในการเขียนโค้ด แต่สมมุติว่าช้า ในเอกสารเผยแพร่นี้ ฉันพิจารณาขั้นตอนหลักของการเพิ่มผลิตภัณฑ์ลงใน Magento 2 โดยทางโปรแกรมด้วยวิธี "คลาสสิก" - โดยใช้คลาส repo

ลูกค้าและคำสั่งซื้อมักจะถูกจำลองไปในทิศทางอื่น - จาก Magento ไปจนถึงระบบ ERP ภายนอก ดังนั้นจึงง่ายกว่าสำหรับพวกเขา ในด้าน Magento คุณเพียงแค่ต้องเลือกข้อมูลที่เหมาะสม จากนั้น "กระสุนบินออกมาจากด้านข้างของเรา"

หลักการบันทึกข้อมูลลงฐานข้อมูล

ในขณะนี้ การสร้างวัตถุที่บันทึกไว้ในฐานข้อมูลโดยทางโปรแกรมใน Magento เสร็จสิ้นแล้ว โรงงาน:

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

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

และการเขียนลงฐานข้อมูลก็ทำผ่าน กรุ:

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

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

วิธีการ "โรงงาน" และ "พื้นที่เก็บข้อมูล" สามารถใช้กับโมเดลหลัก ๆ ทั้งหมดในโดเมน Magento 2

ข้อมูลผลิตภัณฑ์พื้นฐาน

ฉันกำลังดูโครงสร้างข้อมูลที่ตรงกับเวอร์ชัน Magento 2.3 ข้อมูลพื้นฐานที่สุดเกี่ยวกับผลิตภัณฑ์อยู่ในตาราง catalog_product_entity (ทะเบียนผลิตภัณฑ์):

entity_id
attribute_set_id
type_id
sku
has_options
required_options
created_at
updated_at

ฉันจำกัดผลิตภัณฑ์ประเภทเดียว (type_id='simple') ชุดของคุณลักษณะเริ่มต้น (attribute_set_id=4) และละเว้นแอตทริบิวต์ has_options и required_options. เนื่องจากคุณสมบัติ entity_id, created_at и updated_at ถูกสร้างขึ้นโดยอัตโนมัติ ดังนั้น ในการเพิ่มผลิตภัณฑ์ใหม่เราเพียงแค่ต้องตั้งค่า sku. ฉันทำนี่:

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

และฉันได้รับข้อยกเว้น:

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

ฉันเพิ่มชื่อผลิตภัณฑ์ลงในคำขอและได้รับข้อความแจ้งว่าแอตทริบิวต์หายไป Price. หลังจากเพิ่มราคาแล้ว สินค้าจะถูกเพิ่มลงในฐานข้อมูล:

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

ชื่อผลิตภัณฑ์ถูกจัดเก็บไว้ในตารางคุณลักษณะ varchar ของผลิตภัณฑ์ (catalog_product_entity_varchar) ราคา - ในตาราง catalog_product_entity_decimal. ก่อนที่จะเพิ่มผลิตภัณฑ์ ขอแนะนำให้ระบุอย่างชัดเจนว่าเราใช้หน้าร้านผู้ดูแลระบบเพื่อนำเข้าข้อมูล:

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

คุณสมบัติเพิ่มเติม

การประมวลผลคุณลักษณะของผลิตภัณฑ์เพิ่มเติมโดยใช้ Magento เป็นเรื่องที่น่ายินดี แบบจำลองข้อมูล EAV สำหรับเอนทิตีหลัก (ดูตารางที่ XNUMX) eav_entity_type) เป็นหนึ่งในคุณสมบัติหลักของแพลตฟอร์มนี้ เราเพียงแค่เพิ่มคุณลักษณะที่เหมาะสมให้กับรุ่นผลิตภัณฑ์:

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

และเมื่อบันทึกโมเดลผ่านวัตถุ repo:

$repoProd->save($prod);

คุณลักษณะเพิ่มเติมจะถูกจัดเก็บไว้ในตารางฐานข้อมูลที่เกี่ยวข้อง

ข้อมูลสินค้าคงคลัง

พูดง่ายๆ - จำนวนสินค้าในสต็อก ใน Magento 2.3 โครงสร้างในฐานข้อมูลที่อธิบายรูปแบบการจัดเก็บข้อมูลสินค้าคงคลังคือ แตกต่างอย่างมีนัยสำคัญ จากสิ่งที่เกิดขึ้นก่อนหน้านี้ อย่างไรก็ตาม การเพิ่มปริมาณสินค้าในสต็อกผ่านรุ่นสินค้านั้นไม่ได้ยากกว่าการเพิ่มคุณสมบัติอื่นๆ มากนัก:

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

สื่อ

ตามกฎแล้ว การสนับสนุนสื่อสำหรับผลิตภัณฑ์สำหรับลูกค้าในร้านค้า (อีคอมเมิร์ซ) แตกต่างจากการสนับสนุนสื่อสำหรับผลิตภัณฑ์เดียวกันสำหรับพนักงานในระบบบัญชีภายใน (ERP) ในกรณีแรกขอแนะนำให้แสดงผลิตภัณฑ์แบบเห็นหน้ากัน ในกรณีที่สอง ก็เพียงพอที่จะให้แนวคิดทั่วไปเกี่ยวกับผลิตภัณฑ์ อย่างไรก็ตาม การถ่ายโอนรูปภาพหลักของผลิตภัณฑ์เป็นอย่างน้อยก็เป็นเรื่องปกติ case เมื่อนำเข้าข้อมูล

เมื่อเพิ่มรูปภาพผ่านแผงผู้ดูแลระบบ รูปภาพจะถูกบันทึกในไดเร็กทอรีชั่วคราวก่อน (./pub/media/tmp/catalog/product) และเมื่อบันทึกผลิตภัณฑ์เท่านั้นที่จะย้ายไปยังไดเร็กทอรีมีเดีย (./pub/media/catalog/product). นอกจากนี้ เมื่อเพิ่มผ่านแผงผู้ดูแลระบบ รูปภาพก็จะถูกแท็กด้วย 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);

ด้วยเหตุผลบางประการ สื่อบันทึกจะถูกลิงก์หลังจากบันทึกผลิตภัณฑ์ในครั้งแรกและดึงข้อมูลจากที่เก็บอีกครั้งเท่านั้น และคุณต้องระบุแอตทริบิวต์ label เมื่อเพิ่มรายการลงในแกลเลอรีสื่อผลิตภัณฑ์ (ไม่เช่นนั้นเราจะได้รับข้อยกเว้น Undefined index: label in .../module-catalog/Model/Product/Gallery/CreateHandler.php on line 516).

หมวดหมู่

บ่อยครั้งที่โครงสร้างหมวดหมู่ของร้านค้าและแอปพลิเคชันแบ็กเอนด์หรือการจัดวางผลิตภัณฑ์อาจแตกต่างกันอย่างมาก กลยุทธ์ในการย้ายข้อมูลเกี่ยวกับหมวดหมู่และผลิตภัณฑ์ภายในนั้นขึ้นอยู่กับหลายปัจจัย ในตัวอย่างนี้ ฉันยึดถือสิ่งต่อไปนี้:

  • หมวดหมู่แบ็กเอนด์และร้านค้าจะถูกเปรียบเทียบตามชื่อ
  • หากมีการนำเข้าหมวดหมู่ที่ไม่ได้อยู่ในร้านค้า หมวดหมู่นั้นจะถูกสร้างขึ้นภายใต้หมวดหมู่รูท (Default Category) และการวางตำแหน่งเพิ่มเติมในแค็ตตาล็อกร้านค้าจะดำเนินการด้วยตนเอง
  • สินค้าถูกกำหนดให้กับหมวดหมู่เฉพาะเมื่อมีการสร้างในร้านค้า (นำเข้าครั้งแรก)

ข้อมูลพื้นฐานเกี่ยวกับหมวดหมู่อยู่ในตาราง catalog_category_entity (แคตตาล็อกของหมวดหมู่) การสร้างหมวดหมู่ใน Magento:

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

การเชื่อมโยงผลิตภัณฑ์เข้ากับหมวดหมู่จะดำเนินการโดยใช้รหัสหมวดหมู่และ SKU ของผลิตภัณฑ์:

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

เบ็ดเสร็จ

การเขียนโค้ดเพื่อเพิ่มผลิตภัณฑ์ลงใน Magento 2 โดยทางโปรแกรมนั้นค่อนข้างง่าย ฉันได้รวมทุกอย่างที่ระบุไว้ข้างต้นไว้ในโมดูลสาธิตแล้ว “flancer32/mage2_ext_demo_import". มีคำสั่งคอนโซลเพียงคำสั่งเดียวในโมดูล fl32:import:prodซึ่งนำเข้าผลิตภัณฑ์ที่อธิบายไว้ในไฟล์ JSON "./etc/data/products.json":

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

รูปภาพสำหรับการนำเข้าอยู่ในแค็ตตาล็อก ./etc/data/img.

เวลาในการนำเข้าผลิตภัณฑ์ 10 รายการโดยใช้วิธีนี้คือประมาณ 10 วินาทีบนแล็ปท็อปของฉัน หากเราพัฒนาแนวคิดนี้ต่อไป ก็เป็นเรื่องง่ายที่จะสรุปได้ว่าสามารถนำเข้าผลิตภัณฑ์ได้ประมาณ 3600 รายการต่อชั่วโมง และอาจใช้เวลาประมาณ 100 ชั่วโมงในการนำเข้าผลิตภัณฑ์ 30 รายการ การเปลี่ยนแล็ปท็อปด้วยเซิร์ฟเวอร์ทำให้สถานการณ์คลี่คลายลงได้บ้าง อาจจะหลายครั้งด้วยซ้ำ แต่ไม่ใช่ตามลำดับความสำคัญ บางทีความเร็วและความช้านี้อาจเป็นสาเหตุหนึ่งที่ทำให้โครงการเกิดขึ้นได้ magento/async-นำเข้า.

วิธีแก้ปัญหาที่รุนแรงในการเพิ่มความเร็วในการนำเข้าอาจเป็นการเข้าสู่ฐานข้อมูลโดยตรง แต่ในกรณีนี้ "สารพัด" ทั้งหมดที่เกี่ยวข้องกับความสามารถในการขยายของ Magento จะหายไป - คุณจะต้องทำทุกอย่าง "ขั้นสูง" ด้วยตัวเอง อย่างไรก็ตามมันก็คุ้มค่า หากได้ผลผมจะพิจารณาแนวทางการเขียนลงฐานข้อมูลโดยตรงในบทความถัดไป

ที่มา: will.com

เพิ่มความคิดเห็น