Соответственно, из 1С выгружаются два типа цен: «Розничная» и «Оптовая». При этом оптовая цена ниже розничной, и права покупки по ней имеют только пользователи из группы «Оптовые покупатели».
Каждую ночь в 00:00 1С выгружает на сайт Highload-блок, в котором заполнены два поля:
- XML-ID пользователя: совпадает в 1С и в базе данных сайта. Это штатное поле, чтобы оно заполнялось в Битриксе, ничего делать специально не надо.
- Поле с принадлежностью пользователя к группе оптовых клиентов: заполняется значением Y или N, значение может постоянно меняться в 1С (в соответствии с требованиями к оптовикам в магазине).
На сайте в час ночи нужно запускать скрипт, который найдет запись в Highload-блоке и сменит группу пользователя.
Данную инструкцию можно применять не только для переключения группы пользователя ради изменения типа цены. Использовать можно для более сложной логики: например, переключения пользователей по нескольким группам, при этом в поле можно передавать ID новой группы пользователя.
Получить поля HL блока и изменить группу пользователя
Для реализации функционала сначала сделаем и проверим работоспособность скрипта поиска записи в HL блоке, затем повесим его выполнение на агента.
При этом нужно учесть, что мы не трогаем администраторов и контент-менеджеров (ID групп 1 и 7).
Bitrix\Main\Loader::includeModule('highloadblock');
// HL блок с правом на спец цену - его id 8
$entityDataClass = Bitrix\Highloadblock\HighloadBlockTable::compileEntity(
Bitrix\Highloadblock\HighloadBlockTable::getById(8)->fetch()
)->getDataClass();
// Проходим по пользователям и получаем не админов
$arrStaff = Bitrix\Main\UserGroupTable::getList([
'filter' => [
'GROUP_ID' => [1, 7]
],
'select' => [
'USER_ID' // Нужен только ID пользователя
],
])->fetchAll();
// В $arrStaff ID админов и контент-менеджеров
$arrStaff = array_column($arrStaff, 'USER_ID');
// Получаем всех обычных пользователей
$UsersArray = Bitrix\Main\UserTable::getList([
'filter' => [
'!ID' => $arrStaff // Не админы и контентщики
],
'select' => [
'ID',
'XML_ID' // Нужны только эти поля пользователей
]
])->fetchAll();
// Получаем все записи из HL блока для пользователей
$xmlIds = array_column($UsersArray, 'XML_ID');
$hlData = $entityDataClass::getList([
'filter' => [
'UF_KONTRAGENT' => $xmlIds
],
'select' => [
'UF_KONTRAGENT',
'UF_IZMENIT_GRUPPU'
]
])->fetchAll();
// Преобразуем данные HL блока в ассоциативный массив для быстрого доступа
$hlDataMap = [];
foreach ($hlData as $data) {
$hlDataMap[$data['UF_KONTRAGENT']] = $data['UF_IZMENIT_GRUPPU'];
}
$user = new CUser; // объект для работы с пользователями
// Проходим по пользователям
foreach ($UsersArray as $userData) {
// Массив для временного хранения и обнуления
$arGroups = array();
// Проверяем наличие записи в HL блоке
if (isset($hlDataMap[$userData['XML_ID']])) {
// Если в HL у этого пользователя Y, то меняем группу на 9-ую
// иначе переводим в 5-ую
if ($hlDataMap[$userData['XML_ID']] === 'Y') {
$arGroups['GROUP_ID'] = [9]; // 9 - право на оптовую цену
} else {
$arGroups['GROUP_ID'] = [5]; // 5 - обычные пользователи
}
} else {
// Если записи о пользователе нет - может быть и такое, хотя он мог быть раньше был,
// иногда 1С глючит и не довыгружает данные, на всякий выкидываем из оптовиков
// переводим в 5-ую группу по умолчанию
$arGroups['GROUP_ID'] = [5]; // 5 - обычные пользователи
}
$user->Update(
$userData['ID'],
$arGroups
);
}
При каждом запуске скрипта группы пользователей меняются, приходится проходить по всем пользователям, так как пользователи могут становиться оптовиками на один-два дня. Как следствие, нужно проверять запись в поле UF_IZMENIT_GRUPPU для каждого пользователя.
Далее создаем нового агента changeUserGroup(); с запуском каждые 86000 секунд (раз в сутки), агент с запуском в точно указанное время и первый запуск устанавливаем на час ночи.
Функцию агента добавляем в init.php. Более подробно о создании агента, в заметке:
Создание агента в 1С-Битрикс
function changeUserGroup()
{
... наш код из примера выше ...
return 'changeUserGroup();';
}