Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

В мақолаи қаблӣ Ман раванди воридоти маҳсулотро ба Magento 2 ба таври муқаррарӣ - тавассути моделҳо ва анборҳо тавсиф кардам. Усули маъмулӣ суръати коркарди маълумотро хеле паст дорад. Ноутбуки ман дар як сония тақрибан як маҳсулот истеҳсол мекард. Дар ин идома, ман як роҳи алтернативии воридоти маҳсулотро баррасӣ мекунам - тавассути воридшавии мустақим ба пойгоҳи додаҳо, гузаштан аз механизмҳои стандартии Magento 2 (моделҳо, фабрикаҳо, анборҳо). Пайдарҳамии қадамҳои воридоти маҳсулотро метавон ба ҳама забони барномасозӣ, ки бо MySQL кор карда метавонад, мутобиқ кардан мумкин аст.

Радди: Magento дорои функсияҳои омода барои воридоти маълумот ва, эҳтимоли зиёд, он барои шумо кофӣ хоҳад буд. Аммо, агар ба шумо назорати пурратари раванди воридот лозим бошад, на танҳо бо омода кардани файли CSV барои он чизе, ки шумо доред, хуш омадед ба гурба.

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Рамзе, ки дар натиҷаи навиштани ҳарду мақола ба вуҷуд меояд, дар модули Magento дидан мумкин аст "flancer32/mage2_ext_demo_import". Инҳоянд баъзе маҳдудиятҳое, ки ман барои содда кардани рамзи модули намоишӣ риоя кардам:

  • Маҳсулот танҳо эҷод карда мешаванд, навсозӣ намешаванд.
  • Як анбор
  • Танҳо номҳои категорияҳо бидуни сохтори онҳо ворид карда мешаванд
  • Сохторҳои маълумот ба версияи 2.3 мувофиқанд

JSON барои воридоти як маҳсулот:

{
  "sku": "MVA20D-UBV-3",
  "name": "Заглушка для пломбировки ВА47-29 IEK",
  "desc": "Обеспечение доступа к устройствам ...",
  "desc_short": "Заглушка для пломбировки ВА47-29 IEK предназначена для ...",
  "price": 5.00,
  "qty": 25,
  "categories": ["Категория 1", "Категория 2"],
  "image_path": "mva20d_ubv_3.png"
}

Баррасии марҳилаҳои асосии воридот

  • бақайдгирии худи маҳсулот
  • алоқаи байни маҳсулот ва вебсайт
  • хусусиятҳои асосии маҳсулот (EAV)
  • маълумот оид ба инвентаризатсия (миқдори маҳсулот дар анбор)
  • ВАО (расмҳо)
  • пайвастшавӣ бо категорияҳои каталог

Бақайдгирии маҳсулот

Маълумоти асосиро дар бораи маҳсулот метавон дар catalog_product_entity:

CREATE TABLE `catalog_product_entity` (
  `entity_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Id',
  `attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set ID',
  `type_id` varchar(32) NOT NULL DEFAULT 'simple' COMMENT 'Type ID',
  `sku` varchar(64) DEFAULT NULL COMMENT 'SKU',
  `has_options` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Has Options',
  `required_options` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Required Options',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update Time',
  PRIMARY KEY (`entity_id`),
  KEY `CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID` (`attribute_set_id`),
  KEY `CATALOG_PRODUCT_ENTITY_SKU` (`sku`)
)

Ҳадди ақали маълумоти зарурӣ барои эҷоди сабт дар феҳристи маҳсулот инҳоянд:

  • attribute_set_id
  • sku

иловагӣ:

  • type_id - агар мо онро муайян накунем, пас "оддӣ" истифода мешавад

Барои навиштан мустақиман ба пойгоҳи додаҳо, ман адаптери DB-и худи Magento-ро истифода мебарам:

function create($sku, $typeId, $attrSetId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity');
    $bind = [
        'sku' => $sku,
        'type_id' => $typeId,
        'attribute_set_id' => $attrSetId
    ];
    $conn->insert($table, $bind);
    $result = $conn->lastInsertId($table);
    return $result;
}

Пас аз бақайдгирии маҳсулот бо catalog_product_entity он дар панели идоракунӣ, дар шабакаи маҳсулот намоён мешавад (Каталог/Маҳсулот).

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Муносибати байни маҳсулот ва вебсайт

Ассотсиатсияи маҳсулот бо сайт муайян мекунад, ки маҳсулот дар кадом мағозаҳо ва намоишгоҳҳо дар пеш дастрас хоҳад буд.

function linkToWebsite($prodId, $websiteId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_website');
    $bind = [
        'product_id' => $prodId,
        'website_id' => $websiteId
    ];
    $conn->insert($table, $bind);
}

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Хусусиятҳои асосии маҳсулот

Маҳсулоти ба қайд гирифташуда ҳанӯз ном ё тавсиф надорад. Ҳамаи ин тавассути он анҷом дода мешавад Хусусиятҳои EAV. Дар ин ҷо як рӯйхати хусусиятҳои асосии маҳсулот аст, ки барои дуруст нишон додани маҳсулот дар пеш заруранд:

  • name
  • price
  • description
  • short_description
  • status
  • tax_class_id
  • url_key
  • visibility

Ба чунин маҳсулот атрибути алоҳида илова карда мешавад (тафсилоти гирифтани идентификатор ва навъи атрибут аз коди он хориҷ карда мешавад):

public function create($prodId, $attrCode, $attrValue)
{
    $attrId = /* get attribute ID by attribute code */
    $attrType = /* get attribute type [datetime|decimal|int|text|varchar]) by attribute code */
    if ($attrId) {
        /** @var MagentoFrameworkAppResourceConnection $this->resource */
        /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
        $conn = $this->resource->getConnection();
        $tblName = 'catalog_product_entity_' . $attrType;
        $table = $this->resource->getTableName($tblName);
        $bind = [
            'attribute_id' => $attrId,
            'entity_id' => $prodId,
            /* put all attributes to default store view with id=0 (admin) */
            'store_id' => 0,
            'value' => $attrValue
        ];
        $conn->insert($table, $bind);
    }
}

Бо истифода аз рамзи атрибут, мо id ва навъи додаи онро муайян мекунем (datetime, decimal, int, text, varchar), пас маълумотро барои равзанаи маъмурӣ ба ҷадвали мувофиқ нависед (store_id = 0).

Пас аз илова кардани атрибутҳои дар боло зикршуда ба маҳсулот, шумо ин расмро дар панели идоракунӣ мегиред:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Маълумоти инвентаризатсия

Аз версияи 2.3 дар Magento сар карда, ду маҷмӯи параллели ҷадвалҳо мавҷуданд, ки нигоҳдории иттилооти инвентаризатсияро таъмин мекунанд (миқдори маҳсулот):

  • cataloginventory_*: сохтори кӯҳна;
  • inventory_*: сохтори нав (MSI - Inventory Multi Source);

Шумо бояд маълумоти инвентаризатсияро ба ҳарду сохтор илова кунед, зеро сохтори нав ҳанӯз аз сохтори кӯҳна комилан мустақил нест (эҳтимол дорад, ки барои default анбор дар сохтори нав як миз ҷалб карда мешавад cataloginventory_stock_status ҳамчун inventory_stock_1).

каталог_

Ҳангоми ҷойгиркунии Magneto 2.3 мо дар аввал 2 вуруд дорем store_website, ки ба ду сайт мувофиқат мекунад - маъмурӣ ва муштарии асосӣ:

website_id|code |name        |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
         0|admin|Admin       |         0|               0|         0|
         1|base |Main Website|         0|               1|         1|

Ҷадвал cataloginventory_stock мо танҳо як вуруд дорем:

stock_id|website_id|stock_name|
--------|----------|----------|
       1|         0|Default   |

Яъне дар сохтори кӯҳнаи мо танҳо як «анбор» мавҷуд аст (stock) ва он ба вебсайти маъмурӣ пайваст карда шудааст. Илова кардани навгониҳо тавассути панели администратор sources/stocks дар MSI (сохтори нав) боиси воридшавии нав дар cataloginventory_stock.

Маълумоти инвентаризатсия дар бораи маҳсулот дар сохтори кӯҳна дар аввал дар ҷадвалҳо сабт карда мешавад:

  • cataloginventory_stock_item
  • cataloginventory_stock_status

cataloginventory_stock_item

function createOldItem($prodId, $qty)
{
    $isQtyDecimal = (((int)$qty) != $qty);
    $isInStock = ($qty > 0);
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('cataloginventory_stock_item');
    $bind = [
        'product_id' => $prodId,
        /* we use one only stock in 'cataloginventory' structure by default */
        'stock_id' => 1,
        'qty' => $qty,
        'is_qty_decimal' => $isQtyDecimal,
        'is_in_stock' => $isInStock,
        /* default stock is bound to admin website (see `cataloginventory_stock`) */
        'website_id' => 0
    ];
    $conn->insert($table, $bind);
}

cataloginventory_stock_status

function createOldStatus($prodId, $qty)
{
    $isInStock = ($qty > 0);
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('cataloginventory_stock_status');
    $bind = [
        'product_id' => $prodId,
        /* we use one only stock in 'cataloginventory' structure by default */
        'stock_id' => 1, 
        'qty' => $qty,
        'stock_status' => MagentoCatalogInventoryApiDataStockStatusInterface::STATUS_IN_STOCK,
        /* default stock is bound to admin website (see `cataloginventory_stock`) */
        'website_id' => 0 
    ];
    $conn->insert($table, $bind);
}

инвентаризатсия_

Дар аввал, сохтори нав барои нигоҳ доштани маълумоти инвентаризатсия 1 "манбаъ»(inventory_source):

source_code|name          |enabled|description   |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default    |Default Source|      1|Default Source|0.000000| 0.000000|US        |...|

ва як"анбор»(inventory_stock):

stock_id|name         |
--------|-------------|
       1|Default Stock|

«Сарчашма» нигаҳдории ҷисмонии маҳсулотро ифода мекунад (дар сабт координатҳои ҷисмонӣ ва суроғаи почтаи электронӣ мавҷуд аст). "Анбор"иттиҳоди мантиқии якчанд "манбаъҳо" аст (inventory_source_stock_link)

link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
      1|       1|default    |       1|

дар сатҳе, ки пайвастшавӣ ба канали фурӯш рух медиҳад (inventory_stock_sales_channel)

type   |code|stock_id|
-------|----|--------|
website|base|       1|

Аз рӯи сохтори маълумот, намудҳои гуногуни каналҳои фурӯш тахмин карда мешаванд, аммо ба таври нобаёнӣ танҳо пайвастшавӣ "саҳомӣ"-"сомона"(пайванд ба вебсайт рамзи вебсайтро пайравӣ мекунад - base).

як"анбор"метавонад ба якчанд пайваст"манбаъҳо"ва як"манбаъ"- ба якчанд"анборхо"(муносибати бисёр ба бисёр). Истисноҳо пешфарз мебошанд "манбаъ"Ва"анбор". Онҳо ба дигар объектҳо дубора пайваст карда намешаванд (маҳдудият дар сатҳи код - хато "Истиноди марбут ба манбаи пешфарз ё саҳмияи пешфарзро захира карда наметавонед"). Тафсилоти бештарро дар бораи сохтори MSI дар Magento 2 дар мақола пайдо кардан мумкин аст "Системаи идоракунии анбор бо истифода аз CQRS ва Event Sourcing. Тарҳрезӣ".

Ман конфигуратсияи пешфарзро истифода мебарам ва тамоми маълумоти инвентаризатсияро ба манбаъ илова мекунам default, ки дар канали фурӯш бо вебсайт бо код алоқаманд аст base (ба канори пеши мағоза мувофиқат мекунад - нигаред store_website):

function createNewItem($sku, $qty)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('inventory_source_item');
    $bind = [
        'source_code' => 'default',
        'sku' => $sku,
        'quantity' => $qty,
        'status' => MagentoInventoryApiApiDataSourceItemInterface::STATUS_IN_STOCK
    ];
    $conn->insert($table, $bind);
}

Пас аз илова кардани маълумоти инвентаризатсия ба маҳсулот дар панели идоракунӣ, шумо ин расмро мегиред:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

ВАО

Ҳангоми "дастӣ" илова кардани тасвир ба маҳсулот тавассути панели идоракунӣ, маълумоти дахлдор дар ҷадвалҳои зерин навишта мешаванд:

  • catalog_product_entity_media_gallery: феҳристи медиа (тасвирҳо ва файлҳои видео);
  • catalog_product_entity_media_gallery_value: пайваст кардани ВАО ба маҳсулот ва намоишгоҳҳо (маҳаллӣ);
  • catalog_product_entity_media_gallery_value_to_entity: пайваст кардани ВАО танҳо ба маҳсулот (эҳтимолан мундариҷаи пешфарз барои маҳсулот);
  • catalog_product_entity_varchar: Нақшҳое, ки дар он тасвир истифода мешавад, дар ин ҷо нигоҳ дошта мешаванд;

ва худи тасвирҳо дар директория захира карда мешаванд ./pub/media/catalog/product/x/y/ки дар x и y — ҳарфҳои якум ва дуюми номи файли тасвир. Масалан, файл image.png бояд ҳамчун захира карда шавад ./pub/media/catalog/product/i/m/image.png, то ки платформа онро ҳамчун тасвир ҳангоми тавсифи маҳсулот аз каталог истифода барад.

Сабти ном дар ./pub/media/catalog/product/ файли медиа (раванди ҷойгиркунии худи файл дар ин мақола муҳокима карда нашудааст):

function createMediaGallery($imgPathPrefixed)
{
    $attrId = /* get attribute ID by attribute code 'media_gallery' */
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery');
    $bind = [
        'attribute_id' => $attrId,
        'value' => $imgPathPrefixed,
        /* 'image' or 'video' */
        'media_type' => 'image',
        'disabled' => false
    ];
    $conn->insert($table, $bind);
    $result = $conn->lastInsertId($table);
    return $result;
}

Ҳангоми сабти ном, ба файли нави медиа идентификатор таъин карда мешавад.

Мо файли медиаи ба қайд гирифташударо бо маҳсулоти мувофиқ барои дӯкони пешфарз алоқаманд мекунем:

function createGalleryValue($mediaId, $prodId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery_value');
    $bind = [
        'value_id' => $mediaId,
        /* use admin store view by default */
        'store_id' => 0,
        'entity_id' => $prodId,
        'label' => null,
        /* we have one only image */
        'position' => 1,
        'disabled' => false
    ];
    $conn->insert($table, $bind);
}

Мо файли медиаи сабтшударо бо маҳсулоти мувофиқ бидуни пайвастшавӣ ба ягон дӯкон пайваст мекунем. Маълум нест, ки ин маълумот маҳз дар куҷо истифода мешавад ва чаро дастрасӣ ба маълумот аз ҷадвали қаблӣ ғайриимкон аст, аммо ин ҷадвал вуҷуд дорад ва ҳангоми илова кардани расм ба маҳсулот маълумот ба он навишта мешавад. Ҳамин тавр.

function createGalleryValueToEntity($mediaId, $prodId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery_value_to_entity');
    $bind = [
        'value_id' => $mediaId,
        'entity_id' => $prodId
    ];
    $conn->insert($table, $bind);
}

catalog_product_entity_varchar

Файли медиа метавонад бо нақшҳои гуногун истифода шавад (рамзи атрибутҳои мувофиқ дар қавс нишон дода шудааст):

  • Асос (image)
  • Тасвири хурд (small_image)
  • Эскиз (thumbnail)
  • Намунаи тасвир (swatch_image)

Пайваст кардани нақшҳо ба файли медиа маҳз ҳамон чизест, ки дар он рӯй медиҳад catalog_product_entity_varchar. Рамзи ҳатмӣ ба рамзи дар "Хусусиятҳои асосии маҳсулот".

Пас аз илова кардани тасвир ба маҳсулот дар панели идоракунӣ чунин менамояд:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Категорияҳо

Ҷадвалҳои асосии дорои маълумот аз рӯи категория:

  • catalog_category_entity: феҳристи категорияҳо;
  • catalog_category_product: робитаи байни маҳсулот ва категорияҳо;
  • catalog_category_entity_*: арзишҳои атрибутҳои EAV;

Дар аввал, дар як барномаи холии Magento, феҳристи категория 2 категорияро дар бар мегирад (ман номҳои сутунро кӯтоҳ кардам: crt - created_at, upd - updated_at):

entity_id|attribute_set_id|parent_id|crt|upd|path|position|level|children_count|
---------|----------------|---------|---|---|----|--------|-----|--------------|
        1|               3|        0|...|...|1   |       0|    0|             1|
        2|               3|        1|...|...|1/2 |       1|    1|             0|

Категория бо id=1 решаи тамоми каталоги Magento аст ва на дар панели идоракунӣ ва на дар саҳифаи аввал дастрас нест. Категория бо id=2 (Категорияи пешфарз) категорияи решавӣ барои мағозаи асосии сайт аст (Мағозаи асосии вебсайт) ҳангоми ҷойгиркунии барнома сохта шудааст (ниг. Admin / Мағозаҳо / Ҳама мағозаҳо). Ғайр аз он, категорияи решаи худи мағоза низ дар пеш мавҷуд нест, танҳо зеркатегорияҳои он.

Азбаски мавзӯи ин мақола ҳоло ҳам воридоти маълумот дар бораи маҳсулот аст, ман ҳангоми сохтани категорияҳо воридшавии мустақим ба пойгоҳи додаҳоро истифода намебарам, балки синфҳои пешниҳодкардаи худи Magento (моделҳо ва анборҳо) истифода хоҳам кард. Воридкунии мустақим ба пойгоҳи додаҳо танҳо барои пайваст кардани маҳсулоти воридотӣ бо категория истифода мешавад (категория бо номи он мувофиқат мекунад ва ID категория ҳангоми мувофиқат гирифта мешавад):

function create($prodId, $catId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_category_product');
    $bind = [
        'category_id' => $catId,
        'product_id' => $prodId,
    ];
    $conn->insert($table, $bind);
}

Пас аз илова кардани истиноди маҳсулот ба категорияҳои "Категорияи 1" ва "Категорияи 2", тафсилоти маҳсулот дар панели маъмур чунин менамояд:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Амалҳои иловагӣ

Пас аз ба итмом расидани воридоти маълумот, шумо бояд қадамҳои иловагии зеринро иҷро кунед:

  • индексатсияи маълумот: занг дар консол ./bin/magento indexer:reindex;
  • барқарорсозии URL-ҳо барои маҳсулот/категорияҳо: шумо метавонед васеъкуниро истифода баред "elgentos/regenerate-catalog-urls«

Маҳсулот дар панели идоракунӣ пас аз иҷрои амалҳои иловагӣ:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

ва дар пеш:

Magento 2: воридоти маҳсулот мустақиман ба пойгоҳи додаҳо

Натиҷа

Ҳамон маҷмӯи маҳсулот (10 дона), ки дар мақолаи қаблӣ ворид карда мешавад, ҳадди аққал як миқдори калонтар (1 сония нисбат ба 10) ворид карда мешавад. Барои дақиқтар ҳисоб кардани суръат, ба шумо миқдори зиёди маҳсулот лозим аст - якчанд сад ё беҳтараш ҳазорҳо. Аммо, ҳатто бо чунин андозаи хурди маълумоти воридотӣ, мо метавонем хулоса барорем, ки истифодаи абзорҳои аз ҷониби Magento пешниҳодшуда (моделҳо ва анборҳо) назаррас аст (ман таъкид мекунам - хеле!) суръат бахшидан ба рушди функсияҳои зарурӣ, вале дар айни замон ба таври назаррас (ман таъкид мекунам - хеле!) суръати ба базаи маълумот дохил шуданро кам кунед.

Дар натиҷа, об тар шуд ва ин ошкор нест. Бо вуҷуди ин, ҳоло ман код дорам, ки бо он бозӣ кунам ва шояд ба хулосаҳои ҷолибтар биёям.

Манбаъ: will.com