Magento 2: استيراد المنتجات من مصادر خارجية

Magento هو أحد حلول التجارة الإلكترونية، أي. يهدف إلى بيع المنتجات أكثر من التخزين أو الخدمات اللوجستية أو المحاسبة المالية المصاحبة للمبيعات. تعتبر التطبيقات الأخرى (على سبيل المثال، أنظمة تخطيط موارد المؤسسات) أكثر ملاءمة للتطبيقات المصاحبة. لذلك، في كثير من الأحيان في ممارسة استخدام Magento، تنشأ مهمة دمج المتجر مع هذه الأنظمة الأخرى (على سبيل المثال، 1C).

بشكل عام، يمكن تقليل التكامل إلى تكرار البيانات من خلال:

  • كتالوج (المنتجات والفئات)؛
  • بيانات المخزون (أرصدة المنتجات في المستودعات والأسعار)؛
  • العملاء؛
  • طلبات؛

تقدم Magento فئة منفصلة من الكائنات لمعالجة البيانات في قاعدة البيانات - مستودعات. نظرًا لخصائص Magento، من السهل برمجة إضافة البيانات إلى قاعدة البيانات من خلال المستودعات، ولكنها بطيئة على سبيل المثال. أتناول في هذا المنشور المراحل الرئيسية لإضافة منتج برمجيًا إلى Magento 2 بالطريقة "الكلاسيكية" - باستخدام فئات الريبو.

عادةً ما يتم تكرار العملاء والأوامر في الاتجاه الآخر - من 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 للكيانات الرئيسية (انظر الجدول eav_entity_type) هي إحدى الميزات الرئيسية لهذا النظام الأساسي. نقوم ببساطة بإضافة السمات المناسبة إلى نموذج المنتج:

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

وعند حفظ النموذج عبر كائن الريبو:

$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 (كتالوج الفئات). إنشاء فئة في الماجنتو:

/** @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. لقد قمت بدمج كل ما هو مذكور أعلاه في وحدة تجريبية "lancer32/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 - سيتعين عليك القيام بكل شيء "متقدم" بنفسك. ومع ذلك، الأمر يستحق ذلك. إذا نجح الأمر، فسوف أفكر في أسلوب الكتابة المباشرة إلى قاعدة البيانات في المقالة التالية.

المصدر: www.habr.com

إضافة تعليق