Руководство по работе с классом DiscountCouponTable в 1С-Битрикс D7

В современных интернет-магазинах одним из ключевых инструментов маркетинга являются скидки и купоны. В 1С-Битрикс для хранения и управления купонами правил корзины предусмотрена специальная таблица и класс–обёртка: \Bitrix\Sale\Internals\DiscountCouponTable. Данный класс позволяет добавлять, редактировать, удалять купоны, а также хранить и анализировать их статус использования. Ниже мы подробно рассмотрим особенности работы с этим классом, его методы и возможности.

Работа с классом DiscountCouponTable в Битрикс D7

1. Общие сведения о классе

1.1 Назначение и наследование

Класс \Bitrix\Sale\Internals\DiscountCouponTable предназначен для работы с таблицей купонов правил корзины. Он обеспечивает удобный програмный интерфейс (API) в стиле ORM (Object-Relational Mapping) в рамках D7-подхода 1С-Битрикс.

Класс:

  • Является наследником \Bitrix\Main\ORM\Data\DataManager (до версии 18.0.2 модуля Main – класса \Bitrix\Main\Entity\DataManager).
  • Доступен, начиная с версии 14.11.0 модуля sale.

Сам класс находится в пространстве имён:

\Bitrix\Sale\Internals\DiscountCouponTable

Для работы с ним необходимо подключить модуль:

\Bitrix\Main\Loader::includeModule('sale');

2. Поля таблицы купонов

В таблице хранится информация о купонах (поле COUPON), а также о дате их создания, дате применения и другой служебной информации. Наиболее важные поля:

Поле Описание Тип Обяз.
ID Идентификатор купона Int Да
DISCOUNT_ID Идентификатор правила корзины Int Да
ACTIVE Флаг активности (Y/N) Char(1) Да
ACTIVE_FROM Дата начала активности Datetime (Bitrix) Нет
ACTIVE_TO Дата окончания активности Datetime (Bitrix) Нет
COUPON Код купона Varchar(32) Да
TYPE Тип купона (см. ниже) Int Да
MAX_USE Максимально возможное количество применений купона Int Да
USE_COUNT Количество раз использований купона Int Да
USER_ID Код пользователя – владельца купона Int Да
DATE_APPLY Дата и время последнего применения купона Datetime (Bitrix) Нет
TIMESTAMP_X Дата и время последнего изменения Datetime (Bitrix) Нет
MODIFY_BY Код пользователя, последним изменившего купон Int Нет
DATE_CREATE Дата и время создания купона Datetime (Bitrix) Нет
CREATED_BY Код пользователя, создавшего купон Int Нет
DESCRIPTION Комментарий к купону Text Нет

Обратите внимание, что поля ACTIVE_FROM, ACTIVE_TO, DATE_APPLY, TIMESTAMP_X и DATE_CREATE имеют тип Bitrix\Main\Type\DateTime, а не стандартный \DateTime из PHP. Если вы в своих скриптах используете объекты \DateTime, то при передаче значений в поля таблицы их нужно явно конвертировать в \Bitrix\Main\Type\DateTime с помощью метода createFromPhp.

Пример:

use Bitrix\Main\Type\DateTime as BXDateTime;

// Предположим, у нас уже есть php-объект
$phpDate = new \DateTime();

// Преобразуем в Bitrix DateTime
$bitrixDate = BXDateTime::createFromPhp($phpDate);

// После чего можно использовать $bitrixDate для записи в поле ACTIVE_FROM или ACTIVE_TO

3. Типы купонов

Класс содержит три константы, определяющие тип купона (TYPE):

  1. TYPE_BASKET_ROW — на одну позицию (товар) в корзине.
  2. TYPE_ONE_ORDER — на один заказ.
  3. TYPE_MULTI_ORDER — многоразовый купон (для нескольких заказов).

Для проверки валидности типа купона предусмотрен метод isValidCouponType.

4. Основные методы класса

Ниже рассмотрим наиболее востребованные методы, которые помогут при работе с таблицей купонов. Все методы являются статическими (вызываются напрямую из класса, без создания объекта класса).

4.1 getTableName()

Возвращает название таблицы в базе данных:

public static function getTableName()

Вам редко понадобится вызывать его напрямую, но это может пригодиться при отладке или для получения имени таблицы в SQL-запросах (если вы формируете их вручную).

4.2 getMap()

Метод возвращает описание полей ORM (массив полей) для таблицы купонов:

public static function getMap()

Это необходимо, если вам нужно узнать, какие поля формирует D7-ORM для данной таблицы, или, например, при расширении модели.

4.3 add($fields)

Метод add (унаследованный от \Bitrix\Main\ORM\Data\DataManager) добавляет новую запись (купон) в таблицу.

Пример добавления одного купона:

use Bitrix\Main\Loader;
use Bitrix\Sale\Internals\DiscountCouponTable as CouponTable;

Loader::includeModule('sale');

// Генерируем случайный код купона
$couponCode = CouponTable::generateCoupon(true);

$fields = [
    'DISCOUNT_ID' => 1, // Идентификатор правила корзины
    'ACTIVE'      => 'Y',
    'TYPE'        => CouponTable::TYPE_ONE_ORDER,
    'COUPON'      => $couponCode,
    'DATE_APPLY'  => false, // По умолчанию купон ещё не был применён
];

$result = CouponTable::add($fields);

if ($result->isSuccess()) {
    $newId = $result->getId();
    echo "Добавлен купон c ID: " . $newId;
} else {
    $errors = $result->getErrorMessages();
    echo "Ошибка: " . implode(', ', $errors);
}

Обратите внимание:

  • generateCoupon(true) — с параметром true класс проверит уникальность сгенерированного купона, пока не найдёт уникальный вариант.
  • В DISCOUNT_ID нужно передавать реальный идентификатор активного правила корзины.

Если хотите привязать купон к конкретному пользователю, укажите поле USER_ID в $fields.

4.4 generateCoupon($check = false)

Метод генерирует код купона:

public static function generateCoupon($check = false)
  • Если $check = false, метод вернёт случайную строку, не проверяя её уникальность.
  • Если $check = true, то метод будет «перегенерировать» купон до тех пор, пока не найдёт уникальный.

Используется удобно при массовом создании купонов.

4.5 addPacket($data, $count, $limit = 100)

Позволяет массово генерировать и добавлять купоны (создать несколько купонов за один вызов).

public static function addPacket(array $data, int $count, int $limit = 100)

Основные параметры:

  • $data — массив базовых значений купона (например, DISCOUNT_ID, TYPE, ACTIVE_FROM, USER_ID и т.д.).
  • $count — необходимое количество сгенерированных купонов.
  • $limit — максимальное число попыток «сгенерировать» все нужные купоны.

Пример массового добавления:

use Bitrix\Main\Loader;
use Bitrix\Sale\Internals\DiscountCouponTable as CouponTable;

Loader::includeModule('sale');

$fields = [
    'DISCOUNT_ID'  => 6,
    'ACTIVE_FROM'  => null,
    'ACTIVE_TO'    => null,
    'TYPE'         => CouponTable::TYPE_ONE_ORDER, // одноразовый купон
    'MAX_USE'      => 1,
    // 'USER_ID'    => 1, // можно передать, если требуется пользователь-владелец
];

$count = 5; // Хотим создать 5 купонов

$result = CouponTable::addPacket($fields, $count);

if ($result->isSuccess()) {
    // Все успешно
    echo 'Пакет из ' . $count . ' купонов успешно создан.';
    // Можно получить результат, если нужно
    // print_r($result->getData());
} else {
    $errors = $result->getErrorMessages();
    echo 'Ошибка: ' . implode(', ', $errors);
}

4.6 deleteByDiscount($discountId)

Удаляет все купоны, связанные с конкретным правилом корзины (по DISCOUNT_ID).

public static function deleteByDiscount(int $discountId)

Пример использования:

CouponTable::deleteByDiscount(6);

Все купоны, у которых DISCOUNT_ID = 6, будут удалены разом.

4.7 checkCoupon, checkDiscountId, checkType и другие методы-валидаторы

Они отвечают за валидацию полей при добавлении и обновлении купонов, а также при вызове массовых методов.

  • checkCoupon — проверяет купон на уникальность и корректность.
  • checkDiscountId — проверяет корректность поля DISCOUNT_ID.
  • checkType — проверяет корректность типа купона (TYPE).
  • isValidCouponType($couponType) — отдельный метод, возвращает true/false в зависимости от того, допустим ли тип.

Обычно все эти проверки вызываются внутри onBeforeAdd и onBeforeUpdate. Как правило, вам не нужно вызывать их напрямую, достаточно использовать add(), update() или addPacket() – класс сам проверит данные.

4.8 Управление флагом «Имеет купоны» у правил корзины

1С-Битрикс поддерживает индикатор «Имеет купоны» (HAS_COUPONS) в таблице правил (скидок) корзины. Этот флаг отвечает за быстродействие и для понимания, что у скидки действительно есть привязанные купоны. При массовом добавлении (или удалении) купонов вычисление флага может быть отложено и выполнено один раз, чтобы избежать лишних операций.

Методы для управления:

  • disableCheckCouponsUse() — запретить пересчёт флага при изменениях.
  • enableCheckCouponsUse() — разрешить пересчёт флага при изменениях.
  • setDiscountCheckList($discountList) — указать список DISCOUNT_ID, для которых надо обновить флаг.
  • updateUseCoupons() — обновить флаг у переданного списка правил.
  • clearDiscountCheckList() — очистить список правил для пересчёта.

Часто это нужно, если вы делаете массовые операции, например, удаляете несколько купонов подряд или обрабатываете импорт/экспорт. Тогда вы:

  1. Вызываете disableCheckCouponsUse();
  2. Выполняете необходимые массовые действия (deleteByDiscount(), addPacket() и т.д.);
  3. Устанавливаете список правил setDiscountCheckList(), если нужно;
  4. Вызываете updateUseCoupons();
  5. Включаете пересчёт обратно – enableCheckCouponsUse().

Таким образом, вы минимизируете нагрузку на базу данных, так как не запускаете пересчёт после каждого купона.

4.9 prepareCouponData(&$fields)

Подготавливает данные по купону. Используется в основном внутри админки, когда мы обрабатываем формы.

4.10 saveApplied($coupons, $userId, $currentTime)

Сохраняет информацию о применённых купонах. Обычно используется в механизмах оформления заказа, когда нужно зафиксировать, что пользователь применил определённые коды купонов.

public static function saveApplied(array $coupons, int $userId, \Bitrix\Main\Type\DateTime $currentTime)
  • $coupons — массив купонов
  • $userId — идентификатор пользователя (обычно текущего)
  • $currentTime — дата-время применения купона (обязательно в формате Bitrix\Main\Type\DateTime)

5. Практический пример добавления купона с датой активности

Рассмотрим распространённый сценарий: нужно добавить одноразовый купон, действительный в течение недели, для конкретного пользователя (ID 123).

use Bitrix\Main\Loader;
use Bitrix\Main\Type\DateTime as BXDateTime;
use Bitrix\Sale\Internals\DiscountCouponTable as CouponTable;

// Подключаем модуль
Loader::includeModule('sale');

// Генерируем случайный код купона
$couponCode = CouponTable::generateCoupon(true);

// Текущая дата (PHP DateTime)
$phpDateStart = new \DateTime();
$phpDateEnd   = clone $phpDateStart;
$phpDateEnd->modify('+7 days'); // прибавляем неделю

// Конвертируем в Bitrix DateTime
$bitrixDateStart = BXDateTime::createFromPhp($phpDateStart);
$bitrixDateEnd   = BXDateTime::createFromPhp($phpDateEnd);

// Добавляем купон
$fields = [
    'DISCOUNT_ID'  => 11,
    'USER_ID'      => 123,                        // Привязка к пользователю
    'ACTIVE'       => 'Y',
    'ACTIVE_FROM'  => $bitrixDateStart,
    'ACTIVE_TO'    => $bitrixDateEnd,
    'COUPON'       => $couponCode,
    'TYPE'         => CouponTable::TYPE_ONE_ORDER, // одноразовый
    'MAX_USE'      => 1,                           // можно применить только 1 раз
];

$result = CouponTable::add($fields);
if ($result->isSuccess()) {
    echo "Добавлен новый купон с ID: " . $result->getId();
} else {
    echo "Ошибка: " . implode(', ', $result->getErrorMessages());
}

Теперь у пользователя с ID 123 будет активный купон в течение семи дней.

6. Частые ошибки и важные нюансы

  1. Не путайте Bitrix\Main\Type\DateTime и PHP \DateTime. При попытке передать обычный PHP-объект DateTime в поля ACTIVE_FROM, ACTIVE_TO и др. вы получите ошибку вида «Неверно указана дата начала активности». Обязательно делайте BXDateTime::createFromPhp(...).
  2. Проверяйте существование правила корзины (DISCOUNT_ID). Если вы укажете DISCOUNT_ID, которого нет, или оно не активно, купон может фактически не работать. Технически метод checkDiscountId может вернуть ошибку при валидации.
  3. Не забывайте про индекс уникальности купонов. Если вы пытаетесь добавлять купон с одинаковым кодом, получите ошибку. Используйте либо generateCoupon(true), либо следите за уникальностью кода самостоятельно.
  4. Многократные операции – оптимизируйте пересчёт. Если нужно массово удалить, обновить или добавить купоны (тысячи записей), используйте методы disableCheckCouponsUse() / enableCheckCouponsUse() и updateUseCoupons() после крупного блока изменений. Это ускорит выполнение скриптов.
  5. Тип купона и логика его применения. Помните, что TYPE_ONE_ORDER означает одноразовый купон на весь заказ, а не на одну позицию товара. Для одной конкретной позиции используйте TYPE_BASKET_ROW, а для многоразового — TYPE_MULTI_ORDER.

7. Заключение

Класс \Bitrix\Sale\Internals\DiscountCouponTable — незаменимый инструмент, когда необходимо автоматизировать работу с купонами в 1С-Битрикс. Он упрощает создание, редактирование и удаление купонов, а также обеспечивает их корректную валидацию и учёт в механике скидок и правил корзины.

Ключевые моменты для запоминания:

  • Все даты и время хранятся в типе Bitrix\Main\Type\DateTime.
  • При массовых операциях с купонами используйте соответствующие методы (addPacket, deleteByDiscount, disableCheckCouponsUse/enableCheckCouponsUse), чтобы сократить нагрузку на систему.
  • Тип купона (TYPE) определяет, как часто и при каких условиях он может быть применён.

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

Теги:  руководство, D7

Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Аутсорсинг

готов помочь, если нет времени

договорная

Могу взять на себя работы по full-stack на основе готовой верстки

* если нет верстки, то возможность верстать с Figma в режиме редактора

Техническая поддержка

выполняется с сайтами на основе любых CMS

от 5 000 рублей
Оптимизация производительности действующих интернет-проектов, наполнение и сопровождение, полная техническая поддержка и продвижение в поисковых сетях.

* стоимость зависит от объема и сложности выполняемых работ, используемой CMS.