@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"));

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

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

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

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

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