Abr@X@bra.ru
Магазин на Битрикс. О бедном товаре.
Магазин на Битрикс. О бедном товаре.

Магазин на Битрикс. О бедном товаре.

09.02.2017
986

Эта статья открывает серию "почему" и "зачем" для разработчиков магазинов. Темы будут определяться исходя из вопросов на форуме и в блогах, обращений в техподдержку, предложений сайта идей. За рамками публикаций сознательно будут оставлены вопросы, касающиеся причин тех или иных архитектурных решений.

Итак, поговорим о товарах.

Товар как сущность

Товар — это то, что можно положить в корзину и на что оформить заказ. Сразу оговорюсь — речь пойдет исключительно о штатном функционале, т.е. модулях catalog и iblock (Торговый каталог и Информационные блоки). В рамках этих ограничений любой товар — элемент инфоблока. Обратное утверждение не столь категорично — далеко не каждый элемент инфоблока является товаром. Инфоблок должен быть торговым каталогом — это абсолютно необходимое, но недостаточное условие. Второе условие — для элемента инфоблока должны быть заданы характеристики товара (количественный учет и доступность, вес и размеры, etc). За работу с характеристиками товара (далее – товаром) отвечает класс CCatalogProduct модуля catalog. Этот класс относится к старому ядру. Таблет orm \Bitrix\Catalog\ProductTable на текущий момент (catalog 17.0.1) может быть использован только для выборок.

ВАЖНО! Элемент, у которого есть цены, но нет характеристик товара — не товар. Вы не сможете работать с ним в разрезе интернет-магазина. Элемент с характеристиками, но без доступных цен (частный случай — полное отсутствие цен) – это всего-навсего товар, который нельзя продать. Возможен вариант, когда владельцу магазина (именно ему, а не разработчику) характеристики товара не нужны. В таком случае достаточно создать запись с дефолтными значениями параметров и забыть о ней.

Типичный пример неправильного создания товара:

    

if (\Bitrix\Main\Loader::includeModule('catalog')) { // создание элемента инфоблока $element = new CIBlockElement; // минимальный перечень ключей, не учитывающий настройки обязательности полей элемента (например, привязку к разделам) $fields = array( 'IBLOCK_ID' => ID_торгового_каталога, 'NAME' => 'Товар' ); $id = (int)$element->Add($fields); if ($id > 0) { // сохранение базовой цены $result = CPrice::SetBasePrice($id, 100, 'RUB'); } }

А вот как правильно:

    

if (\Bitrix\Main\Loader::includeModule('catalog')) { $useStoreControl = (string)\Bitrix\Main\Config\Option::get('catalog', 'default_use_store_control') === 'Y'; $element = new CIBlockElement; $fields = array( 'IBLOCK_ID' => ID_торгового_каталога, 'NAME' => 'Товар' ); $id = (int)$element->Add($fields); if ($id > 0) { $fields = array( 'ID' => $id, 'QUANTITY_TRACE' => \Bitrix\Catalog\ProductTable::STATUS_DEFAULT, 'CAN_BUY_ZERO' => \Bitrix\Catalog\ProductTable::STATUS_DEFAULT, 'WEIGHT' => 0, 'MEASURE' => ID_единицы_измерения ); if (!$useStoreControl) { // выключен складской учет $fields['QUANTITY'] = общее_количество_товара; } // создание товара $result = CCatalogProduct::Add($fields); if ($result) { // добавление коэффициента единицы измерения товара $result = \Bitrix\Catalog\MeasureRatioTable::add(array( 'PRODUCT_ID' => $id, 'RATIO' => коэффициент_единицы_измерения ) ); // добавление цены $priceId = CPrice::Add(array( 'PRODUCT_ID' => $id, 'CATALOG_GROUP_ID' => ID_типа_цены, 'PRICE' => 100, 'CURRENCY' => 'RUB' ) ); } } }

Исходя из вышеизложенного, проверка существования товара выглядит так (с учетом прав текущего пользователя):

    

if (\Bitrix\Main\Loader::includeModule('catalog')) { $iterator = CIBlockElement::GetList(array( array(), array( 'ID' => ID_товара, 'ACTIVE' => 'Y', 'ACTIVE_DATE' => 'Y', 'CHECK_PERMISSIONS' => 'Y', 'MIN_PERMISSION' => 'R' , false, false, array('ID', 'IBLOCK_ID') ); $element = $iterator->Fetch(); if (empty($element)) { echo 'Товар не найден'; } else { $product = \Bitrix\Catalog\ProductTable::getList(array( 'select' => array('ID', 'AVAILABLE'), 'filter' => array('=ID' => ID_товара) ) )->fetch(); if (empty($product)) { echo 'Товар не найден'; } } }

Типы товаров

С выпуском catalog 14.0.0 появилось понятие типа товара. На тот момент их было всего два – товар и комплект. Начиная с catalog 16.0.3 в продукте поддерживаются 6 типов товаров: Основные

  • \Bitrix\Catalog\ProductTable::TYPE_PRODUCT – простой товар
  • \Bitrix\Catalog\ProductTable::TYPE_SET – комплект
  • \Bitrix\Catalog\ProductTable::TYPE_SKU – товар с торговыми предложениями
  • \Bitrix\Catalog\ProductTable::TYPE_OFFER – торговое предложение

Дополнительные

  • \Bitrix\Catalog\ProductTable::TYPE_FREE_OFFER – торговое предложение, у которого нет товара (не указан или удален)
  • \Bitrix\Catalog\ProductTable::TYPE_EMPTY_SKU – специфический тип, означает невалидный товар с торговыми предложениями.

Установка типа товара происходит автоматически, хотя и может быть определена вручную.

Типы товаров, которые могут быть добавлены в корзину:

  • \Bitrix\Catalog\ProductTable::TYPE_PRODUCT – простой товар
  • \Bitrix\Catalog\ProductTable::TYPE_SET – комплект
  • \Bitrix\Catalog\ProductTable::TYPE_OFFER – торговое предложение

Варианты торгового каталога

От настроек торгового каталога зависит, какие типы товаров могут быть в нем. Получить эту информацию можно, вызывая метод CCatalogSku::GetInfoByIBlock(). Метод возвращает либо false, либо массив. В первом случае это обычный инфоблок, не имеющий отношения к магазину. Во втором (вернулся массив) необходимо проверять значение ключа CATALOG_TYPE:

    

if (\Bitrix\Main\Loader::includeModule('catalog')) { $catalog = CCatalogSku::GetInfoByIBlock(ID_инфоблока); if (empty($catalog)) { echo 'Инфоблок не найден или не имеет отношения к торговому каталогу'; } else { switch ($catalog['CATALOG_TYPE'] ) { case CCatalogSku::TYPE_CATALOG: echo 'Простой торговый каталог'; break; case CCatalogSku::TYPE_FULL: echo 'Расширенный торговый каталог'; break; case CCatalogSku::TYPE_PRODUCT: echo 'Инфоблок товаров с торговыми предложениями'; break; case CCatalogSku::TYPE_OFFERS: echo 'Торговый каталог предложений'; } } }

CCatalogSku::TYPE_CATALOG - простой торговый каталог. Может содержать следующие типы товаров:

  • \Bitrix\Catalog\ProductTable::TYPE_PRODUCT – простой товар
  • \Bitrix\Catalog\ProductTable::TYPE_SET – комплект



CCatalogSku::TYPE_FULL - расширенный торговый каталог. Может содержать все типы товаров простого торгового каталога плюс товары с торговыми предложениями:

  • \Bitrix\Catalog\ProductTable::TYPE_PRODUCT – простой товар
  • \Bitrix\Catalog\ProductTable::TYPE_SET – комплект
  • \Bitrix\Catalog\ProductTable::TYPE_SKU – товар с торговыми предложениями



CCatalogSku::TYPE_PRODUCT - инфоблок товаров с торговыми предложениями. Не является торговым каталогом. Содержит лишь один основной тип товара и один дополнительный:

  • \Bitrix\Catalog\ProductTable::TYPE_SKU – товар с торговыми предложениями
  • \Bitrix\Catalog\ProductTable::TYPE_EMPTY_SKU – товар, у которого отсутствуют торговые предложения (удалены либо не создавались)



CCatalogSku::TYPE_OFFERS - торговый каталог предложений. Его типы товаров:

  • \Bitrix\Catalog\ProductTable::TYPE_OFFER – торговое предложение
  • \Bitrix\Catalog\ProductTable::TYPE_FREE_OFFER – торговое предложение, у которого нет товара (не указан)




ВАЖНО! До версии catalog 16.0.3, если инфоблок переставал быть торговым каталогом, у всех элементов этого инфоблока немедленно удалялись характеристики товара и цены. Сейчас эта информация стирается только при удалении самого элемента.

Доступность товара и возможность его покупки

До выхода обновления catalog 16.0.3 доступность товара рассчитывалась «на лету» при выборке из базы. Вследствие этого нельзя было получить доступность товара с торговыми предложениями. Сейчас доступность рассчитывается в момент изменения характеристик товара и сохраняется в базе. Простой товар, комплект или торговое предложение считаются недоступным, если:

  • для него включен количественный учет
  • запрещена покупка при отсутствии
  • количество меньше либо равно нулю

Во всех остальных случаях товар доступен.

Товар с торговыми предложениями считается недоступным, если все(!) его предложения недоступны (алгоритм расчета см. выше). Для комплекта параметры, участвующие в расчете доступности, выставляются автоматически и не могут быть изменены.

Доступность не означает, что товар может быть куплен. Полный перечень условий для покупки:

  • Товар доступен
  • Элемент инфоблока активен
  • Даты активности элемента отсутствуют либо текущая дата попадает в диапазон активности
  • условия, завязанные на конкретного покупателя
  • минимальные права доступа – чтение
  • у товара есть цены тех типов, по которым клиент может покупать

Доступность товара пересчитывается при вызове следующих методов:

  • CIBlockElement::Add
  • CIBlockElement::Update
  • CIBlockElement:: Delete
  • CIBlockElement::SetPropertyValues (при передаче свойства привязки торгового предложения к головному товару)
  • CCatalogProduct::Add
  • CCatalogProduct::Update
  • CCatalogProduct:: Delete

Настройки модуля Торговый каталог

Вкратце коснемся настроек модуля, непосредственно влияющих на товары

Показывать вкладку Торговый каталог для товаров, имеющих торговые предложения. Включение этой настройки отключает автоматический пересчет доступности товаров с торговыми предложениями.

Значения параметров товаров по умолчанию. Изменение настроек в этом разделе касается лишь тех товаров, у которых в соответствующих параметрах выставлено «по умолчанию».




В случае проблем с товарами (неверная доступность, неверные типы товаров, etc) можно воспользоваться одной из служебных процедур модуля из раздела Переиндексация данных - Переиндексацией товаров. Начиная с версии catalog 17.0.1 эта процедура дополнительно валидирует коэффициенты единиц измерения.


Автор статьи: Жуков Евгений






Bitrix, PHP
Читайте также:
10 вредных советов для начинающих разработчиков

10 вредных советов для начинающих разработчиков

Другие программисты могут не согласиться с данными советами, но это именно то, что делает их такими редкими и ценными.
Читать
Chrome, функции о которых вы не знали.

Chrome, функции о которых вы не знали.

Мы часто воспринимаем адресную строку браузера исключительно как место, куда мы вводим URL страницы, на которую мы хотим...
Читать
Ajax подгрузка контента Битрикс

Ajax подгрузка контента Битрикс

Ajax подгрузка контента, бесконечный скроллинг, «вебдванольная постраничка» — этот подход называют по разному, но суть о...
Читать