@denism300

Как в Битриксе отключить товарное предложение?

Понадобилось отключать активность у некоторых ТП.
Написал такой обработчик:
use Bitrix\Main\Loader;
use Bitrix\Catalog\StoreProductTable;
use Bitrix\Catalog\PriceTable;
use Bitrix\Catalog\ProductTable;
use CCatalogSku;

Loader::includeModule('catalog');

class OfferCheckPriceAndQty
{
    const STORE_IDS   = [1, 2];
    const PRICE_TYPES = ['BASE', 'WHOLESALE'];

    public static function onBeforeIBlockElementHandler(&$arFields)
    {
        $offerId = $arFields['ID'];
        if (is_array(CCatalogSku::GetProductInfo($offerId))) {
            $quantityIsZero = self::checkQuantities($offerId);
            $pricesAreZero  = self::checkPrices($offerId);

            if ($quantityIsZero || $pricesAreZero) {
                $res = ProductTable::Update($offerId, array("ACTIVE" => "N"));
                AddMessage2Log($res, 'OfferCheckPriceAndQty');
            } else {
                $res = ProductTable::Update($offerId, array("ACTIVE" => "Y"));
            }
        }
    }

    protected static function checkQuantities($offerId)
    {
        // код
    }
    protected static function checkPrices($offerId)
    {
        // код
    }

В настройках (Файл для редактирования элемента, позволяющий модифицировать поля перед сохранением) ИП предложений указал файл с содержимым
function BXIBlockAfterSave($arFields)
{
    OfferCheckPriceAndQty::onBeforeIBlockElementHandler($arFields);
}

И активность ТП не убирается.
В логе все ок.
Module: OfferCheckPriceAndQty
\Bitrix\Main\ORM\Data\UpdateResult::__set_state(array(
   'isSuccess' => true,
   'errors' => 
  \Bitrix\Main\ErrorCollection::__set_state(array(
     'values' => 
    array (
    ),
  )),
   'data' => 
  array (
  ),
   'wereErrorsChecked' => false,
   'object' => NULL,
   'affectedRowsCount' => NULL,
   'primary' => NULL,
))

Пробовал повесить на события
EventManager::getInstance()->AddEventHandler("iblock", "OnAfterIBlockElementAdd", array("OfferCheckPriceAndQty", "onBeforeIBlockElementHandler"));
EventManager::getInstance()->AddEventHandler("iblock", "OnAfterIBlockElementUpdate", array("OfferCheckPriceAndQty", "onBeforeIBlockElementHandler"));
EventManager::getInstance()->AddEventHandler("catalog", "OnProductAdd", array("OfferCheckPriceAndQty", "onBeforeIBlockElementHandler"));
EventManager::getInstance()->AddEventHandler("catalog", "OnProductUpdate", array("OfferCheckPriceAndQty", "onBeforeIBlockElementHandler"));

безрезультатно.
При этом, если сделать так:
$res = ProductTable::Update($offerId, array("ACTIVE" => "N", "AVAILABLE" => "N"));

то свойство "Доступность" меняется, а активность - нет.
  • Вопрос задан
  • 27 просмотров
Решения вопроса 1
@tgarl
Активность относится к элементу инфоблока, а не к каталогу, а вы только пытаетесь через каталог ProductTable её убрать.

Вот какие нужно задействовать таблицы:
названия, активности - элемент, CIBlockElement
Количство - каталог, CCatalogProduct
цена - прайс, CPrice

под D7, сами поменяете таблицы на правильные, я только указал в чем принципиальная ошибка
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
к ответу tgarl добавлю только, что если делать обработчик для onBefore события, то в нём не надо самому делать апдейт в базе, а надо делать
$arFields['ACTIVE'] = 'N';
Именно для этого $arFields и принимают по ссылке. И надо не забывать, что на том же событии могут быть другие обработчики, со своими изменениями
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы