Magento 2: واردات محصولات از منابع خارجی

Magento یک راه حل تجارت الکترونیک است، یعنی. بیشتر در جهت فروش محصولات است تا انبارداری، لجستیک یا حسابداری مالی همراه با فروش. سایر برنامه ها (به عنوان مثال، سیستم های ERP) برای برنامه های همراه مناسب تر هستند. بنابراین، اغلب در تمرین استفاده از Magento، وظیفه ادغام یک فروشگاه با این سیستم های دیگر (به عنوان مثال، 1C) مطرح می شود.

به طور کلی، یکپارچگی را می توان به تکرار داده ها با موارد زیر کاهش داد:

  • کاتالوگ (محصولات، دسته بندی ها)؛
  • داده های موجودی (موجودی محصول در انبارها و قیمت ها)؛
  • مشتریان؛
  • سفارشات؛

Magento یک کلاس جداگانه از اشیاء را برای دستکاری داده ها در پایگاه داده ارائه می دهد - مخازن. با توجه به ویژگی های Magento، افزودن داده ها به پایگاه داده از طریق مخازن به راحتی قابل کدگذاری است، اما، فرض کنید، کند است. در این نشریه، من مراحل اصلی افزودن برنامه‌ای یک محصول به Magento 2 را به روش "کلاسیک" - با استفاده از کلاس‌های repo در نظر می‌گیرم.

مشتریان و سفارشات معمولاً در جهت دیگر تکرار می شوند - از مجنتو تا سیستم های 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);

رویکرد "Factory" و "Repository" را می توان برای همه مدل های اصلی در دامنه 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);

و هنگام ذخیره مدل از طریق شی 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).

Категории

اغلب، ساختار طبقه بندی فروشگاه و برنامه کاربردی یا قرار دادن محصولات در آنها می تواند به طور قابل توجهی متفاوت باشد. استراتژی‌های انتقال داده‌ها در مورد دسته‌ها و محصولات درون آن‌ها به عوامل زیادی بستگی دارد. در این مثال من به موارد زیر پایبند هستم:

  • دسته های باطن و فروشگاه با نام مقایسه می شوند.
  • اگر دسته‌ای وارد شده است که در فروشگاه نیست، آن‌گاه تحت دسته root ایجاد می‌شود (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 بسیار آسان است. من همه چیزهایی که در بالا گفته شد را در یک ماژول دمو ترکیب کردم.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-import.

یک راه حل اساسی برای افزایش سرعت واردات می تواند ورود مستقیم به پایگاه داده باشد، اما در این مورد تمام "خوبی" در مورد توسعه پذیری Magento از بین می رود - شما باید همه چیز را "پیشرفته" خودتان انجام دهید. با این حال، ارزش آن را دارد. اگر جواب داد، در مقاله بعدی روش نوشتن مستقیم در پایگاه داده را در نظر خواهم گرفت.

منبع: www.habr.com

اضافه کردن نظر