Magento з'яўляецца e-commerce рашэннем, г.зн. больш нацэлена на продаж прадуктаў, чым на спадарожны склад складской, лагістычны або фінансавы ўлік. Для спадарожнага лепш падыходзяць іншыя прыкладанні (напрыклад, ERP-сістэмы). Таму дастаткова часта ў практыцы выкарыстання Magento ўзнікае задача інтэграцыі крамы з гэтымі іншымі сістэмамі (напрыклад, з 1С).
Па вялікім рахунку інтэграцыю можна звесці да рэплікацыі дадзеных па:
- каталогу (прадукты, катэгорыі);
- інвентарным дадзеных (рэшткі прадуктаў на складах і кошты);
- кліентам;
- заказам;
Magento для маніпуляцыі з дадзенымі ў базе прапануе асобны клас аб'ектаў.
Кліенты і замовы рэплікуюцца, як правіла, у іншы бок – з 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);
Падыход з выкарыстаннем "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);
і пры захаванні мадэлі праз РЭПО-аб'ект :
$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);
Медыя
Як правіла, медыя-суправаджэнне прадукта для кліента ў краме (e-commerce) адрозніваецца ад медыя-суправаджэння гэтага ж прадукта для супрацоўніка ва ўнутранай сістэме ўліку (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
).
Катэгорыі
Часцяком структура катэгорый крамы і backend-прыкладанні або размяшчэнне ў іх прадуктаў можа значна адрознівацца. Стратэгіі пераносу дадзеных аб катэгорыях і прадуктах у іх залежаць ад мноства фактараў. У дадзеным прыкладзе я прытрымваюся наступнай:
- катэгорыі backend'а і крамы супастаўляюцца па назове;
- калі імпартуецца катэгорыя, якой няма ў краме, то яна ствараецца пад каранёвай катэгорыяй (
Default Category
) і яе далейшае пазіцыянаванне ў каталогу крамы мяркуецца ўручную; - прывязка прадукта да катэгорыі адбываецца толькі пры ім стварэнні ў краме (першым імпарце);
Асноўная інфармацыя аб катэгорыі знаходзіцца ў табліцы catalog_category_entity
(каталог катэгорый). Стварэнне катэгорыі ў Magento:
/** @var MagentoCatalogApiDataCategoryInterfaceFactory $factCat */
/** @var MagentoCatalogApiCategoryRepositoryInterface $repoCat */
$cat = $factCat->create();
$cat->setName($name);
$cat->setIsActive(true);
$repoCat->save($cat);
Прывязка прадукта да катэгорыі ажыццяўляецца па ID катэгорыі і SKU прадукта:
/** @var MagentoCatalogModelCategoryProductLinkFactory $factCatProdLink */
/** @var MagentoCatalogApiCategoryLinkRepositoryInterface $repoCatLink */
$link = $factCatProdLink->create();
$link->setCategoryId($catMageId);
$link->setSku($prodSku);
$repoCatLink->save($link);
Разам
Напісаць код для дадання ў Magento 2 прадукта праграмным шляхам вельмі нескладана. Усё выкладзенае вышэй я зьвёў у дэма-модульfl32:import:prod
, якая імпартуе прадукты, апісаныя ў JSON-файле «
[
{
"sku": "...",
"name": "...",
"desc": "...",
"desc_short": "...",
"price": ...,
"qty": ...,
"categories": ["..."],
"image_path": "..."
}
]
Малюнкі для імпарту знаходзяцца ў каталогу ./etc/data/img
.
Час імпарту 10 прадуктаў падобным спосабам складае каля 10 секунд на маім ноўтбуку. Калі развіваць гэтую думку далей, то нескладана прыйсці да высновы, што ў гадзіну можна імпартаваць каля 3600 прадуктаў, а на імпарт 100К прадуктаў можа сысці каля 30 гадзін. Замена наўтбука на сервер дазваляе некалькі згладзіць сітуацыю. Можа, нават у разы. Але не на парадкі. Магчыма гэтая хуткасць павольнасць у нейкай меры з'яўляецца адной з прычын з'яўлення праекта
Кардынальным рашэннем для павелічэння хуткасці імпарту можа стаць прамая запіс у базу, але ў гэтым выпадку губляюцца ўсе «плюшкі», якія тычацца пашыральнасці Magento – давядзецца ўсё «пашыранае» рабіць самому. Тым не менш, яно таго вартае. Калі атрымаецца, то разгледжу падыход з прамым запісам у БД у наступным артыкуле.
Крыніца: habr.com