Сгенерировать скидочные купоны, при заказе и отправить на почту

Просмотров: 3397

Задача: после того как пользователь сделал заказ, нужно сгенерировать одноразовые купоны для скидки (правила корзины) и отправить, эти купоны, на почту указанную при оформлении заказа. Купоны генерируются и отправляются, только после полного завершения заказа, который оплачен и переведен в статус "Выполнен".

генерировать скидочные купоны, при заказе и отправить на почту.

Для начала создаем правило корзины, для которого будем генерировать купоны. Переходим в "Администрирование -> Маркетинг -> Товарный маркетинг -> Правила работы с корзиной" и создаем скидку на нужную сумму и процент.

генерировать скидочные купоны, при заказе и отправить на почту.

Уже при желании добавляете нужные ограничения по разделам, товарам и прочим условиям. В моем случае правило распостраняется на весь каталог.

Для этого правила, на вкладке "Купоны" обязательно сгенерируйте один купон- что бы правило не работало просто так.

Программная генерация скидочного купона

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

В /local/php_interface/init.php добавляем следующий обработчик.


use Bitrix\Main\Loader;

AddEventHandler("sale", "OnSaleStatusOrder", "OrderComplete");
function OrderComplete($orderID, &$arFields)
{
    if ($arFields == 'F') {
        Loader::includeModule("sale");

        // Товары заказа
        $dbRes = \Bitrix\Sale\Basket::getList([
            'select' => ['QUANTITY'],
            'filter' => [
                '=ORDER_ID' => $orderID,
            ]
        ]);
        while ($item = $dbRes->fetch()) {
        	$itemsCount += (int)$item['QUANTITY'];
        }
     	// end Товары заказа


	// Генерируем купоны
	$i = 1;
 	while ($i <= $itemsCount) {
                $generateCoupon = \Bitrix\Sale\Internals\DiscountCouponTable::generateCoupon(true);
                $fields = array(
                    "DISCOUNT_ID" => "7",
                    "ACTIVE" => "Y",
                    "TYPE" => \Bitrix\Sale\Internals\DiscountCouponTable::TYPE_ONE_ORDER,
                    "COUPON" => $generateCoupon,
                    "DATE_APPLY" => false
                );
                $result = \Bitrix\Sale\Internals\DiscountCouponTable::add($fields);
                $cuponsList[] = '<br>' . $generateCoupon;
                $i++;
        }
	// end Генерируем купоны

        // Получаем email для отправки купона
        $dbRes = \Bitrix\Sale\PropertyValueCollection::getList([
            'select' => ['CODE', 'VALUE'],
            'filter' => ['=ORDER_ID' => $orderID, '=CODE' => 'EMAIL']
        ]);
        while ($item = $dbRes->fetch()) {
            $userOrderEmail = $item['VALUE'];
        }
        // end Получаем email для отправки купона
        
        // Отправляем письмо
        $EVEN_TYPE = 'SEND_CUPONS';
        $SITE_ID = 's1';
        $arFeedForm = array(
            "EMAIL_TO" => $userOrderEmail,
            "CUPON_LIST" => $cuponsList
        );
        CEvent::Send($EVEN_TYPE, $SITE_ID, $arFeedForm );
    }
}	
  • Здесь мы воспользовались событием OnSaleStatusOrder которое срабатывает при изменении статуса заказа.
  • При условии что заказ перешел в статус выполнен ($arFields == 'F') запускаем дальнейшую работу.
  • С помощью \Bitrix\Sale\Basket::getList получили состав этого заказа. Указываем 'select' => ['QUANTITY'],- нам нужны только количества товаров, не зачем тянуть все данные.
  • В переменной $itemsCount общее количество товаров в заказе.
  • Запускаем цикл, который работает до тех пор, пока счетчик $i не совпадет с $itemsCount

В теле цикла используем Internals\DiscountCouponTable::generateCoupon для генерации самого купона. И Internals\DiscountCouponTable::add который прявязывает купон к правилу корзины, с ID=7 (правило созданное выше, у вас другой ID).

Сам купон создается одноразовым, с помощью Internals\DiscountCouponTable::TYPE_ONE_ORDER. Если понадобится создать другой типа купона:

  • TYPE_BASKET_ROW - на одну позицию
  • TYPE_ONE_ORDER - на один заказ
  • TYPE_MULTI_ORDER - многоразовый

Отправка письма, средствами 1С-Битрикс

Дальше, осталось отправить письмо. В теле цикла, генерирующего купоны, мы собирали массив $cuponsList[] с купонами- его и будем отправлять.

С помощью PropertyValueCollection::getList мы получили электронную почту покупателя, указанную при оформлении заказа. Занесли ее в переменную $userOrderEmail.

А дальше, с помощью CEvent::Send дергаем почтовое событие с типом SEND_CUPONS и передаем в него массив с купонами и электронной почтой покупателя.

Теперь, создаем новый тип почтового события (Настройки -> Настройки продукта -> Почтовые и СМС события -> Типы событий), с названием SEND_CUPONS

генерировать скидочные купоны, при заказе и отправить на почту.

И само письмо, с любым текстом, самое главное не забываем добавить переменную с массивом купонов. Настройки -> Настройки продукта -> Почтовые и СМС события -> Почтовые шаблоны

генерировать скидочные купоны, при заказе и отправить на почту.

На этом все. Более сложные агоритмы генерации купонов, буду рассматривать в следующих заметках.

Михаил Базаров 30.07.2022
Что бы купоны не копились в базе, если они больше не нужны.
Можно запускать периодический скрипт с методом
\Bitrix\Sale\Internals\DiscountCouponTable::onDelete
который будет подчищать использованные купоны.
Alexey 01.09.2022
Спасибо за материал! Очень полезно.
Но, для ленивых, подскажите, как поправить под генерацию одного купона?
Михаил Базаров 01.09.2022
Цитата
Alexey написал:
Сгенерировать скидочные купоны, при заказе и отправить на почту

Как-то так. Не проверял, но вроде бы все правильно.
То есть даже не получаем список товаров заказа. Достатоно знать что он стал в статусе F
Код
if ($arFields == 'F') {
   // Генерируем купон
                $generateCoupon = \Bitrix\Sale\Internals\DiscountCouponTable::generateCoupon(true);
                $fields = array(
                    "DISCOUNT_ID" => "7",
                    "ACTIVE" => "Y",
                    "TYPE" => \Bitrix\Sale\Internals\DiscountCouponTable::TYPE_ONE_ORDER,
                    "COUPON" => $generateCoupon,
                    "DATE_APPLY" => false
                );
                $result = \Bitrix\Sale\Internals\DiscountCouponTable::add($fields);
                $cupon = $generateCoupon;
   // end Генерируем купон

        // Получаем email для отправки купона
        $dbRes = \Bitrix\Sale\PropertyValueCollection::getList([
            'select' => ['CODE', 'VALUE'],
            'filter' => ['=ORDER_ID' => $orderID, '=CODE' => 'EMAIL']
        ]);
        while ($item = $dbRes->fetch()) {
            $userOrderEmail = $item['VALUE'];
        }
        // end Получаем email для отправки купона
        
        // Отправляем письмо
        $EVEN_TYPE = 'SEND_CUPONS';
        $SITE_ID = 's1';
        $arFeedForm = array(
            "EMAIL_TO" => $userOrderEmail,
            "CUPON_LIST" => $cupon
        );
        CEvent::Send($EVEN_TYPE, $SITE_ID, $arFeedForm );
    }
Alexey 01.09.2022
Благодарю, Михаил :) Буду пробовать
Гость 08.06.2023
Подскажите, как создать большое кол-во купонов с заранее заданным форматом кода купона ?