Скрипт для чистки дубликатов пользователей с перепривязкой заказов в 1С-Битрикс

У одного из наших клиентов возникла проблема с дубликатами пользователей (покупателей) на сайте. Возникла она из-за того, что изначально в интернет-магазине не стояла настройка «Проверять email на уникальность при регистрации». Из-за этого покупатели, когда без авторизации в интернет-магазине, совершали заказ, то вводили свои данные и Битрикс создавал нового пользователя (логин равен адресу электронной почты) и привязывал заказ к этому новому пользователю. И все было замечательно до тех пор, пока в интернет-магазине не ввели скидочную систему, благодаря которой покупатели стали уже внимательнее относиться к своим аккаунтам (регистрироваться с одинаковыми email тоже запретили, чтобы новых дубликатов пользователей не появлялось).

Проверять email на уникальность.png

Но возникли проблемы со старыми пользователями:

  1. Покупатели само собою не могли вспомнить свой пароль и восстановить доступ у них не получалось, т.к. с таким email было несколько пользователей.
  2. Удалить лишних пользователей нельзя, т.к. к ним привязаны заказы.
  3. Необходимо собрать все заказы с дублей пользователей, чтобы покупатель видел все свои заказы и могла рассчитаться правильно скидка.

Чтобы решить все, перечисленные  проблемы дублей пользователей, решено было оставить только самого первого пользователя с одинаковым логином (все заказы одинаковых логинов перепривязать к нему), остальных пользователей удалить.

Конечно, все это можно делать ручками для каждого покупателя, но это не наш метод. Наш метод - написать скрипт для обработки всех пользователей и их заказов. Этот скрипт надо выполнить внутри админки сайта на странице адрес_сайта/bitrix/admin/php_command_line.php


//title: Чистка дублей пользователей с перепривязкой заказов

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

$order = array('sort' => 'asc');
$tmp = 'sort'; 
$rsUsers = CUser::GetList($order, $tmp);

$arlogin = [];
while($rsUsers->NavNext(true, "f_")) :
	$arlogin[mb_strtolower($f_LOGIN)][] = $f_ID;
endwhile;

foreach($arlogin as $login=>$arLoginId):
	if(count($arLoginId)>1):
		$arOrder = \Bitrix\Sale\Order::loadByFilter([
    		'filter' => [
        		"USER_ID" => $arLoginId, 
			],
    		'order' => ['ID' => 'ASC'],
		]);
		foreach($arOrder as $order):
			if( (int)$order->getUserId() != (int)$arLoginId[0] ){

				echo "{$order->getUserId()} - заказ {$order->getId()} - привязать к {$arLoginId[0]} {$login}\n";
				// Привязываем все заказы к самому первому пользователю с таким логином
				$order->setFieldNoDemand('USER_ID', $arLoginId[0]);
				$order->save();
			}
		endforeach;

		// Удаляем дубли пользователя, оставляем только самого первого
		foreach($arLoginId as $k=>$loginId){
			if($k>0) {
				if (CUser::Delete($loginId)) echo "Пользователь {$loginId} {$login} удален.\n";
			} else{
				echo "Оставляем пользователя {$loginId} {$login}\n";
			}
		}
	endif;
endforeach;

Перед выполнением этого скрипта обязательно сделайте бэкап базы данных.

Если у вас прям много таких дублей (тысячи и более), а сайт расположен на виртуальном хостинге, то может не хватить времени выполнения php скрипта. Но у таких сайтов обычно есть к кому обратиться за решением проблемы.