Задать вопрос
@Osco

Как скрыть товары для группы пользователей?

Здравствуйте!

  • Есть ряд товаров, все они есть на складе, много.
  • Есть порядка 30 типов цен, которые привязаны 30 группам пользователей соответственно.
  • Для конкретного покупателя целый ряд товаров отображается как "нет в наличии", потому что на них не установлена цена в типе цен


Необходимо СКРЫТЬ от конкретного пользователя товары с отсутствующей ценой в типе цены для
группы к которой привязан этот пользователь. Стандартные настройки типа:
692f33e6e254b199420836.png
не работают.
Магия DeepSeek тоже бессильна:
spoiler

// /local/php_interface/init.php
use Bitrix\Main\EventManager;
use Bitrix\Main\Loader;
use Bitrix\Main\Application;

$eventManager = EventManager::getInstance();

// Отключаем все стандартные фильтры по наличию и ценам
$eventManager->addEventHandler('iblock', 'OnBeforeIBlockElementGetList', function(&$arFilter) {
    // Удаляем все фильтры, связанные с каталогом (они будут мешать)
    $keysToRemove = [
        'CATALOG_AVAILABLE', 'AVAILABLE', '=CATALOG_AVAILABLE',
        'CATALOG_PRICE_', '>CATALOG_PRICE_', '!=CATALOG_PRICE_'
    ];
    
    foreach ($keysToRemove as $key) {
        foreach (array_keys($arFilter) as $filterKey) {
            if (strpos($filterKey, $key) === 0) {
                unset($arFilter[$filterKey]);
            }
        }
    }
});

// Отключаем проверку доступности через модуль каталога
$eventManager->addEventHandler('catalog', 'OnGetAvailableItems', function() {
    return false;
});
// Продолжение в init.php
$eventManager->addEventHandler('iblock', 'OnAfterIBlockElementGetList', function(&$arResult) {
    if (empty($arResult) || !Loader::includeModule('catalog') || !Loader::includeModule('sale')) {
        return;
    }
    
    // Получаем текущего пользователя и его группы
    global $USER;
    $userId = $USER->GetID();
    $userGroups = $USER->GetUserGroupArray();
    
    // Определяем, какие типы цен доступны этим группам
    $allowedPriceTypes = [];
    
    // Способ 1: Через стандартные привязки типов цен к группам
    $priceTypeRes = \Bitrix\Catalog\GroupTable::getList([
        'select' => ['ID', 'NAME'],
        'filter' => ['=GROUP_ACCESS.GROUP_ID' => $userGroups]
    ]);
    
    while ($priceType = $priceTypeRes->fetch()) {
        $allowedPriceTypes[] = (int)$priceType['ID'];
    }
    
    // Если нет привязок, берем все типы цен
    if (empty($allowedPriceTypes)) {
        $priceTypeRes = \Bitrix\Catalog\GroupTable::getList(['select' => ['ID']]);
        while ($priceType = $priceTypeRes->fetch()) {
            $allowedPriceTypes[] = (int)$priceType['ID'];
        }
    }
    
    // Если все равно пусто - выходим
    if (empty($allowedPriceTypes)) {
        return;
    }
    
    // Собираем ID товаров из результата
    $elementIds = [];
    foreach ($arResult as $item) {
        if (isset($item['ID'])) {
            $elementIds[] = (int)$item['ID'];
        }
    }
    
    if (empty($elementIds)) {
        return;
    }
    
    // Получаем товары, у которых ЕСТЬ цены в доступных типах
    $connection = Application::getConnection();
    $sql = "
        SELECT DISTINCT cp.PRODUCT_ID 
        FROM b_catalog_price cp
        WHERE cp.PRODUCT_ID IN (" . implode(',', $elementIds) . ")
        AND cp.CATALOG_GROUP_ID IN (" . implode(',', $allowedPriceTypes) . ")
        AND cp.PRICE > 0
        AND (cp.QUANTITY_FROM IS NULL OR cp.QUANTITY_FROM = 0)
        AND (cp.QUANTITY_TO IS NULL OR cp.QUANTITY_TO = 0)
    ";
    
    $result = $connection->query($sql);
    $productsWithPrices = [];
    
    while ($row = $result->fetch()) {
        $productsWithPrices[(int)$row['PRODUCT_ID']] = true;
    }
    
    // Фильтруем результат - оставляем только товары с ценами
    $filteredResult = [];
    foreach ($arResult as $item) {
        if (isset($item['ID']) && isset($productsWithPrices[(int)$item['ID']])) {
            $filteredResult[] = $item;
        }
    }
    
    $arResult = $filteredResult;
    
    // Обновляем навигацию, если есть
    if (isset($GLOBALS['NAV_RESULT']) && is_object($GLOBALS['NAV_RESULT'])) {
        $GLOBALS['NAV_RESULT']->NavRecordCount = count($filteredResult);
        $GLOBALS['NAV_RESULT']->SelectedRows = count($filteredResult);
    }
});
  • Вопрос задан
  • 14 просмотров
Подписаться 1 Средний Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Python-разработчик
    10 месяцев
    Далее
  • Skillbox
    Профессия Графический дизайнер PRO
    15 месяцев
    Далее
  • Нетология
    Фронтенд-разработчик
    11 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы