Смена ставки НДС в масштабах всего каталога — это не «поменять одну цифру». Ставка НДС хранится у каждого товара как отдельная сущность каталога, поэтому переключить её сразу у тысяч позиций можно тремя путями: групповыми операциями в списке товаров, действиями через свойство или скриптом по API. Разберём каждый, покажем рабочий пример кода и обозначим, где легко наломать дров.
Где в Битрикс хранится ставка НДС товара
Прежде чем менять ставку массово, важно понимать модель данных. Ставка НДС — это не свойство инфоблока, а поле торгового каталога (модуль catalog). У каждого товара есть поле VAT_ID — идентификатор ставки из справочника, и флаг VAT_INCLUDED (Y/N) — включён ли налог в цену. Сами ставки лежат в справочнике «Магазин → Настройки → Ставки НДС» (таблица b_catalog_vat), а привязка товара к ставке — в b_catalog_product.
Отсюда важное следствие: если вы хотите изменить значение процента у существующей ставки (например, все товары с «НДС 18%» должны стать «20%») — иногда достаточно отредактировать саму ставку в справочнике, и она пересчитается для всех привязанных товаров. Но если нужно перевести часть товаров с одной ставки на другую (скажем, с 20% на 10% для льготной категории) — придётся менять VAT_ID у каждой позиции. Массовые методы ниже решают именно вторую задачу.
Групповые операции в списке товаров
Самый безопасный способ без кода — штатные групповые действия в списке товаров. Откройте «Контент → Инфоблоки → Товары» нужного каталога (либо «Магазин → Каталог товаров»). Действуйте по шагам:
- Настройте фильтр так, чтобы в списке остались только нужные товары — по разделу, бренду, текущей ставке НДС или другому свойству.
- Отметьте товары галочками (или флажком в шапке — «выделить всё на странице»).
- Внизу списка в блоке групповых действий выберите «Изменить» и примените.
Ключевой нюанс: чтобы поле ставки НДС появилось в форме группового редактирования, оно должно быть включено в настройках списка. Нажмите шестерёнку настройки таблицы и добавьте колонку «НДС» (поле CATALOG_VAT). После этого групповое «Изменить» позволит задать ставку сразу всем выделенным позициям.
Обновление через привязку к свойству или разделу
Часто ставка НДС логически связана с категорией товара: книги и детские товары — 10%, всё остальное — 20%. В таких случаях удобно опираться на раздел каталога или служебное свойство-маркер, а не перебирать товары вручную.
Практичная схема: заведите в инфоблоке свойство типа «список» VAT_GROUP со значениями «Стандарт»/«Льгота», проставьте его импортом или групповой операцией по разделам, а затем один раз прогоните скрипт, который читает это свойство и выставляет соответствующий VAT_ID. Плюс подхода — правило воспроизводимо: новые товары получают верную ставку по тому же признаку, и при следующей смене процентов не нужно заново выяснять, «кто есть кто».
- По разделу — товары из ветки «Книги» переводим на льготную ставку; удобно, если структура каталога совпадает с налоговой логикой.
- По свойству-маркеру — гибче, когда льготные позиции разбросаны по разным разделам.
- По бренду или производителю — реже, но встречается для импортных линеек.
Скрипт массовой смены через API
Для больших каталогов надёжнее всего скрипт на CCatalogProduct::Update(). Он меняет ставку у товара штатно, с вызовом событий и без прямых UPDATE в базу. Сначала узнайте VAT_ID нужной ставки в справочнике «Ставки НДС» (значение видно в URL при редактировании ставки или через CCatalogVat::GetList). Затем выберите товары фильтром и обновите каждый:
<?php
require($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/prolog_before.php');
if (!CModule::IncludeModule('catalog') || !CModule::IncludeModule('iblock')) die('no modules');
$IBLOCK_ID = 21; // ID инфоблока каталога
$NEW_VAT_ID = 3; // ID нужной ставки НДС из справочника
$OLD_VAT_ID = 2; // меняем только тех, у кого сейчас эта ставка
$rs = CIBlockElement::GetList(
[],
['IBLOCK_ID' => $IBLOCK_ID, 'ACTIVE' => 'Y'],
false, false,
['ID', 'NAME']
);
$cnt = 0;
while ($el = $rs->Fetch()) {
$prod = CCatalogProduct::GetByID($el['ID']);
if (!$prod || (int)$prod['VAT_ID'] !== $OLD_VAT_ID) continue;
$ok = CCatalogProduct::Update($el['ID'], [
'VAT_ID' => $NEW_VAT_ID,
'VAT_INCLUDED' => 'Y',
]);
if ($ok) { $cnt++; }
else { echo 'FAIL '.$el['ID'].' '.$el['NAME']."\n"; }
}
echo 'Updated: '.$cnt."\n";
Скрипт кладут в отдельный файл в корне и запускают из консоли (php /path/update_vat.php) или через административный инструмент. Обратите внимание на VAT_INCLUDED: если у вас цены хранятся с включённым налогом, оставляйте Y, иначе Битрикс начнёт считать НДС «сверху» и итоговая цена в корзине изменится.
\Bitrix\Catalog\Model\Product::update($id, ['VAT_ID' => $newVatId]). Логика та же, но метод возвращает объект Result с ошибками через getErrorMessages().Риски и проверка результата
Массовое изменение ставки напрямую влияет на цену и на печатные формы чеков, поэтому спешка недопустима. Основные грабли:
| Риск | Как избежать |
|---|---|
Прямой UPDATE в b_catalog_product | Только через API — иначе не сработают события, кэш и агрегаты цен |
Путаница VAT_INCLUDED | Сверить, включён ли налог в цену, до и после запуска |
| Изменение затронуло лишние товары | Фильтровать по OLD_VAT_ID, сначала прогон в «сухом» режиме без Update |
| Устаревший кэш каталога | Сбросить кэш компонентов и «умного фильтра» после смены |
Порядок безопасного внедрения: сделайте резервную копию базы, запустите скрипт сначала в режиме подсчёта (закомментируйте CCatalogProduct::Update и просто выводите ID) и убедитесь, что число совпадает с ожидаемым. Только потом — боевой прогон. После завершения проверьте несколько товаров в админке и в публичной части: карточку, корзину и оформление заказа — цена и строка «в том числе НДС» должны быть корректны.
BXClearCache(true)). Иначе на витрине какое-то время будут показываться старые суммы.Синхронизация с 1С
Если каталог обменивается данными с 1С через CommerceML, помните главное правило: 1С — ведущая система. Ставка НДС приходит в выгрузке import.xml в реквизитах товара и в узлах цен. Это значит, что при следующем обмене 1С перезапишет ставку, которую вы поменяли на сайте вручную или скриптом — и все ваши правки откатятся.
Поэтому массовую смену НДС при активной интеграции правильнее выполнять на стороне 1С: сменить ставку у номенклатуры в учётной системе и запустить выгрузку. На сайте при этом должно быть корректно настроено сопоставление ставок — Битрикс матчит приходящую ставку по проценту со справочником «Ставки НДС». Если в 1С появился новый процент, добавьте соответствующую ставку в справочник заранее, иначе обмен создаст дубль или проставит ставку по умолчанию.
- Проверьте, что имена/проценты ставок в 1С и в справочнике Битрикс совпадают.
- Убедитесь, что в настройках обмена не отключено обновление налоговых реквизитов.
- После выгрузки прогоните ту же проверку карточки и корзины, что и для ручного сценария.
Итог
Массовая смена ставки НДС в 1С-Битрикс сводится к выбору инструмента под масштаб: для сотни товаров хватит групповых операций в списке (не забыв вывести колонку «НДС» и увеличить постраничку), для льготных категорий удобнее опираться на раздел или свойство-маркер, а для крупного каталога — скрипт на CCatalogProduct::Update с фильтрацией по старой ставке. В любом сценарии критичны три вещи: бэкап, «сухой» прогон и проверка цены с учётом VAT_INCLUDED. А при работающей интеграции с 1С менять ставку нужно в учётной системе, иначе обмен откатит правки.
Мы в B2Bsite регулярно проводим такие операции на боевых магазинах: пишем безопасные скрипты, настраиваем сопоставление ставок в обмене с 1С и следим, чтобы после смены НДС корректно считались цены, чеки и фискальные документы. Если каталог большой или интеграция сложная — поможем сделать это без простоя и ошибок.
Частые вопросы
Можно ли поменять ставку сразу у всех товаров без кода?
Да, через групповые операции в списке товаров: настройте фильтр, выведите колонку «НДС» в настройках таблицы, отметьте товары и примените действие «Изменить». Но действие работает только в пределах текущей страницы списка.
Чем отличается изменение самой ставки от смены VAT_ID у товаров?
Если поменять процент у существующей ставки в справочнике, он пересчитается для всех привязанных товаров. Смена VAT_ID нужна, когда часть товаров надо перевести с одной ставки на другую, оставив остальных без изменений.
Каким методом API безопаснее менять ставку в скрипте?
Используйте CCatalogProduct::Update() или D7-обёртку \Bitrix\Catalog\Model\Product::update(). Они меняют ставку штатно, с событиями и без прямых UPDATE в таблицу b_catalog_product.
Что будет, если менять b_catalog_product напрямую SQL-запросом?
Не рекомендуется: не сработают обработчики событий, не сбросится кэш и агрегаты цен могут остаться неактуальными. Всегда используйте API каталога.
На что влияет флаг VAT_INCLUDED при массовой смене?
Он определяет, включён ли налог в цену товара. Если ошибиться, Битрикс начнёт считать НДС «сверху» и итоговая сумма в корзине изменится. Сверяйте значение до и после запуска.
Почему после смены ставки на витрине показываются старые цены?
Скорее всего, не сброшен кэш каталога и умного фильтра. Очистите автокэширование в настройках модуля или вызовите BXClearCache(true) после массовой операции.
Как менять НДС, если магазин синхронизируется с 1С?
Меняйте ставку на стороне 1С и запускайте выгрузку — при обмене 1С перезаписывает налоговые реквизиты и откатит правки, сделанные на сайте. Заранее заведите нужную ставку в справочнике Битрикс.
Как убедиться, что скрипт затронул только нужные товары?
Сначала сделайте бэкап и запустите скрипт в режиме подсчёта: без вызова Update, просто выводя ID подходящих позиций. Если число совпадает с ожидаемым, выполняйте боевой прогон.
Поможем с настройкой и поддержкой 1С-Битрикс: Управление сайтом
Поможем с настройкой, доработкой и поддержкой 1С-Битрикс: Управление сайтом.