Бонус на внутренний счет пользователя по информации из 1С

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

Задача: 1С-Предприятие каждый день выгружает HL справочник на сайт с количеством бонусов контрагента в виде "XML-ID контрагента = Количество бонусов"
Нужно копировать бонусы на внутренний счет пользователя, для возможности дальнейшей оплаты заказов.

Бонус на внутренний счет пользователя по информации из 1С

В моем случае перерасчет бонусов происходит каждую ночь, с помощью скрипта запускаемого на cron. В течении дня пользователи тратят бонусы, а в 00:00 внутренний счет обновляется согласно HL справочнику.

Таким образом не важно что происходит с бонусами на стороне 1С, в любом случае учтется последнее обновление HL справочника по информации из 1С.

Получаем информацию из HL блока в 1С-Битрикс

Для начала получим информацию из справочника. По XML-ID пользователя найдем его внутренний (Битриксовый) ID и просто выведем на экран:

use Bitrix\Main\Loader;
use Bitrix\Highloadblock as HL;
use Bitrix\Main\UserTable;

Loader::includeModule('highloadblock');
Loader::includeModule('sale');

$hlblockDatas = HL\HighloadBlockTable::getById(5)->fetch();
$entityHlBonus = HL\HighloadBlockTable::compileEntity($hlblockDatas);
$entityDataClassBonus = $entityHlBonus->getDataClass();

// Получаем данные из HL блока с бонусами
$bonusData = $entityDataClassBonus::getList(array(
    'select' => array(
        'UF_KONTRAGENT',
        'UF_SUMMABONUSOV'
    ),
));
while ($arBonusData = $bonusData->Fetch()) {
        // Находим ID пользователя по XML-ID
        $userId = UserTable::getList([
            'filter' => [
                'XML_ID' => $arBonusData['UF_KONTRAGENT']
            ],
            'select' => [
                'ID'
            ]
        ])->fetch();

        echo 'У пользователя с ID ' . $userId['ID') . ' ' . $arBonusData['UF_SUMMABONUSOV'] . ' бонуса';

}
  • Подключили модуль HL блоков и из справочника с ID 5 получили поля UF_KONTRAGENT и UF_SUMMABONUSOV.
  • Далее, в цикле, с помощью Bitrix\Main\UserTable получлил ID пользователя с переданным в фильтр XML-ID (поле UF_KONTRAGENT). И вывели на экран информацию по бонусам этого пользователя.

Начисление суммы на внутренний счет пользователя через API

Дальше все просто: нам нужно получить внутренний счет пользователя и обновить его баланс суммой полученной из HL справочника.

Замечание по получению информации о счете: для ситуации, когда в HL блоке появляется новый контрагент, у которого еще нет внутреннего счета на сайте. Счет нужно сначала создать, с нулем на балансе, а дальше можно обновлять.

$_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__) . '/../..');

define('NO_KEEP_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
define('BX_NO_ACCELERATOR_RESET', true);

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

@set_time_limit(0);
@ignore_user_abort(true);

use Bitrix\Main\Loader;
use Bitrix\Highloadblock as HL;
use Bitrix\Main\UserTable;

Loader::includeModule('highloadblock');
Loader::includeModule('sale');

$hlblockDatas = HL\HighloadBlockTable::getById(5)->fetch();
$entityHlBonus = HL\HighloadBlockTable::compileEntity($hlblockDatas);
$entityDataClassBonus = $entityHlBonus->getDataClass();

// Получаем данные из HL блока с бонусами
$bonusData = $entityDataClassBonus::getList(array(
    'select' => array(
        'UF_KONTRAGENT',
        'UF_SUMMABONUSOV'
    ),
));
while ($arBonusData = $bonusData->Fetch()) {
    if (!empty($arBonusData['UF_KONTRAGENT'])) {
        // Получаем ID пользователя зная его XML_ID из HL
        $userId = UserTable::getList([
            'filter' => [
                'XML_ID' => $arBonusData['UF_KONTRAGENT']
            ],
            'select' => [
                'ID'
            ]
        ])->fetch();
        if (!empty($userId['ID'])) {
            // Получаем информацию о текущем счете пользователя
            $userCurrentAccount = CSaleUserAccount::GetByUserID(
                $userId['ID'],
                "RUB"
            );

            // Если у пользователя еще нет счета создаем с нулем на балансе
            if (empty($userCurrentAccount)) {
                CSaleUserAccount::add(array(
                    'USER_ID' => $userId['ID'],
                    'CURRENCY' => 'RUB',
                    'CURRENT_BUDGET' => '0'
                ));
                $userCurrentAccount = CSaleUserAccount::GetByUserID(
                    $userId['ID'],
                    "RUB"
                );
            }

            // Обновляем сумму на счете из HL
            CSaleUserAccount::update($userCurrentAccount['ID'], array(
                'CURRENT_BUDGET' => $arBonusData['UF_SUMMABONUSOV']
            ));
            unset($userId, $userCurrentAccount);
        }
    }
}

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

Привел готовый код для запуска его на crontab задании, если у вас пользователей не много, можно сделать агента. В моем случае более 100 тыс. пользователей и crontab задание более приемлимо - отрабатывает минут за 10

Суть проста: не важно какая сумма на счету пользователя до запуска скрипта, она обновиться суммой указанной в $arBonusData['UF_SUMMABONUSOV'] с помощью метода CSaleUserAccount::update

Михаил Базаров 24.09.2024
Подразумевается что этот скрипт запускается из директории /local/php_interface/ или /bitrix/php_interface/
Если размещаете где-то глубже, не забудте поменять строку
Код
$_SERVER['DOCUMENT_ROOT'] = realpath(dirname(__FILE__) . '/../..');

под ваш уровень вложенности, иначе php интерпритатор не найдет путь до ядра битрикс

Блог-note: заметки разработчика

Заполнение множественного пользовательского свойства типа "строка" через API

Задача: когда пользователь заходит в мобильное приложение, нужно сохранить FCM токен устройства в пользовательское поле ...

Постраничная навигация в списке разделов Битрикс- catalog.section.list

Если в магазине очень много разделов и хочется вывести их с постраничной навигацией: можно воспользоваться методами CDBR...

Удалить товары из корзины, если есть определенные товары.

Задача: если в корзину добавлены товары с определенным свойством, нужно удалить из корзины, все другие товары- предупред...

Не дать купить товара больше, чем находится на определенных складах

Задача: в магазине 20 складов, на всех есть остатки но нужно ограничить покупку товара только остатками на двух складах,...

Оптимизация jpeg и png картинок на cron, с помощью jpegoptim и optipng

Задача: на сайт каждый день проходит выгрузка из 1С с обновлением картинок. Нужно оптимизмровать эти картинки с помощью...

Вывод элементов с помощью API битрикс

Иногда, выводить элементы инфоблока с помощью компонентов, может оказаться избыточным. Например, если нужно вывести элем...

Дать пользователю возможность быстро отредактировать материал

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

Бонус за выполненный заказ на внутренний счет пользователя

Задача: после того как заказ, в интернет-магазине, перешел в статус "Выполнен" начислить пользователю 5% от стоимости за...

Автоматически помечаем новинки лейблом в каталоге битрикс

Если вы хотите помечать новинки каталога, вашего магазина на Битрикс, лейблом "Новинка". И так, что бы это происходило а...