Наличие на складах в умном фильтре 1С-Битрикс, с автоматическим обновлением

Просмотров: 8920

Задача: добавить возможность фильтрации товаров по складам в умном фильтре. Данные должны обновляться автоматически, при импорте товаров из 1С.

Отбор по складам в умном фильтре 1С-Битрикс

Для начала создадим свойство в инфоблоке каталога, тип множественный список. В качестве элементов списка названия складов, по которым хотим сделать фильтрацию. В моем случае, свойство имеет код "ATT_NAL_STORE"

Отбор по складам в умном фильтре 1С-Битрикс
Названия складов, для фильтра, можно задать произвольно. Не обязательно один в один, как названия заданы в модуле магазина.

Связываем склады со свойством инфоблока

Теперь, нужно создать пользовательское поле у складов, тип число. Я задал код, этого, UF_ поля: "UF_ATT_NAL_STORE"

У каждого склада вписываем, в это поле, ID значения соответствующего ему элемента свойства инфоблока.

Отбор по складам в умном фильтре 1С-Битрикс

Таким образом мы связали каждый склад со свойством инфоблока.

Консольный скрипт для обновления свойства инфоблока

Cоздадим консольный скрипт который будет заполнять свойство инфоблока по crontab расписанию.

Если текучка товаров не большая, данный скрипт можно повесить на crontab задание, что бы выполнялся в фоне с заданной периодичностью, например, раз в 12 часов.

$_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__) . '/../..');
$DOCUMENT_ROOT = $_SERVER['DOCUMENT_ROOT'];

define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('BX_NO_ACCELERATOR_RESET', true);

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

set_time_limit(0);
ignore_user_abort(true);

use \Bitrix\Main\Loader;

Loader::includeModule("iblock");
Loader::includeModule("catalog");

$IBLOCK_ID = 13;

// Получаем все товары
$dbGoods = CIBlockElement::GetList(
    array('ID' => 'ASC'),
    array('IBLOCK_ID' => $IBLOCK_ID),
    false,
    false,
    array('ID')
);

$goodsIds = [];
while ($arGood = $dbGoods->Fetch()) {
    $goodsIds[] = $arGood['ID'];
}

// Получаем все склады для товаров за один запрос
$arStores = [];
if (!empty($goodsIds)) {
    $dbStores = CCatalogStore::GetList(
        array(),
        array(
            'PRODUCT_ID' => $goodsIds,
            'ACTIVE' => 'Y',
        ),
        false,
        false,
        array('PRODUCT_ID', 'PRODUCT_AMOUNT', 'UF_ATT_NAL_STORE')
    );

    while ($arStore = $dbStores->Fetch()) {
        if ($arStore['PRODUCT_AMOUNT'] > 0) {
            $arStores[$arStore['PRODUCT_ID']][] = array('VALUE' => $arStore['UF_ATT_NAL_STORE']);
        }
    }
}

// Обновляем свойства товаров
foreach ($goodsIds as $goodId) {
    // Очищаем свойство от предыдущих значений
    CIBlockElement::SetPropertyValuesEx(
        $goodId,
        $IBLOCK_ID,
        array('ATT_NAL_STORE' => '')
    );

    // Устанавливаем значение свойства, если есть что устанавливать
    if (isset($arStores[$goodId]) && !empty($arStores[$goodId])) {
        CIBlockElement::SetPropertyValuesEx(
            $goodId,
            $IBLOCK_ID,
            array('ATT_NAL_STORE' => $arStores[$goodId])
        );

        // Обновляем индекс
        \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex(
            $IBLOCK_ID,
            $goodId
        );
    }
}

require_once($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
  • С помощью CIBlockElement::GetList проходимся по всем элементам инфоблока (в моем случае $IBLOCK_ID = 13). Нам нужен только ID товара.
  • Внутри цикла очищаем значения свойства "ATT_NAL_STORE", установленные ранее, с помощью CIBlockElement::SetPropertyValuesEx
  • Далее, собираем массив $arStores с помощью CCatalogStore::GetList, в котором собрано наличие данного товара на складе и пользовательское поле склада "UF_ATT_NAL_STORE", связываюшее его со значением свойства "ATT_NAL_STORE"
  • Если на конкретном складе есть данный товар/элемент, наполняем массив $PROPERTY_VALUES в котором передаем ID элемента списка, свойства "ATT_NAL_STORE"
  • Из этого массива устанавливаем значение свойства методом CIBlockElement::SetPropertyValuesEx
  • Обновляем связанную с элементом инфомацию с помощью \Bitrix\Iblock\PropertyIndex\Manager::updateElementIndex

Обновление свойства при обмене с 1С

Если текучка товаров большая и необходима постоянная, актуальная информация о складах в умном фильтре. Можно добавить обработчик со скриптом в /local/php_interface/init.php, который будет срабатывать при каждом обновлении элемента каталога.

AddEventHandler("iblock", "OnAfterIBlockElementUpdate", array("UpdateStoreProp", "OnAfterIBlockElementUpdateHandler"));
class UpdateStoreProp
{
    function OnAfterIBlockElementUpdateHandler(&$arFields)
    {
        if ($arFields["RESULT"]) {
           ... ...
           Здесь скрипт приведенный выше
           В CIBlockElement::GetList добавляем
           фильтрацию 'ID' => $arFields['ID']
           ... ...
        }
    }
}
AddEventHandler("iblock", "OnAfterIBlockElementAdd", array("UpdateStoreProp2", "OnAfterIBlockElementAddHandler"));
class UpdateStoreProp2
{
    function OnAfterIBlockElementAddHandler(&$arFields)
    {
        if ($arFields["RESULT"]) {
           ... ...
           Здесь скрипт приведенный выше
           В CIBlockElement::GetList добавляем
           фильтрацию 'ID' => $arFields['ID']
           ... ...
        }
    }
}

Пример работы, с использованием данной заметки Магазин товаров для активного отдыха. Вопросы прошу писать в комментариях.

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 500 000 руб. от 5-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 100 000 руб. от 7-ми дней

Вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Магазин, быстро запускается на базе одного из 200-та готовых решений.

Мобильное приложение

от 500 000 руб. от 1-го месяца

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 350 000 руб. от 1-го месяца

Корпоративный сайт с информационными разделами, каталогом товаров или услуг. Включает формы обратной связи карточек каталога, любое количество статичных и динамичных разделов.

Инфресурс

от 400 000 руб. от 5-ти недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

Лечение сайтов от вирусов

от 40 000 руб. от 2-х дней

Выполню полную проверку сайта и окружения. В случае обнаружения вирусов проведу полный комплекс лечения проекта и закрытия лазеек.