Добавление заказов с других сайтов методами API Битриса.

UPD: в скрипте используются старые методы работы с заказами, для тех у кого Битрикс новых редакций рекомендую в работе с заказами использовать D7!

У одно из клиентов столкнулся с задачей передачи заказов с второстепенных сайтов на один основной (менеджеры постоянно теряли/забывали заказы) для хранения и обработки всего в одном месте.

Найти готового решения под эту задачу мне не удалось, поэтому вооружившись API Битрикса, начал выполнять задачу.

Ниже покажу скрипт, принимающий уже сформированный php-массив с второстепенных сайтов. (если нужна будет часть кода с передающий сайтов, пишите в комментарии, добавлю отдельной статьей)

Входные параметры приблизительно такие:

Array
(
    [FIO] => Тестов Тест Тестович
    [EMAIL] => mail@mail.ru
    [PHONE] => 89055555555
    [ZIP] => 117447
    [CITY] => Москва
    [LOCATION] => 671
    [ADDRESS] => улица Победы д1, кв.1
    [BASKET] => Array
        (
            [28901] => 1.00
            [28915] => 1.00
            [18192] => 1.00
        )
)

В BASKET-е в качестве ключа артикул товара, в значении - количество из корзины.

У вас в качестве артикула может выступать внешний код, или любой другой параметр одинаковый у всех товаров на сайтах.

После проверки наличия нужных нам переменных и подключенных модулей, проверяем есть ли пользователь с таким же email. Есть - отлично, нет - создадим нового.

	// Шаг 1. Lexa.pro: найти/создать пользователя
	
	global $USER;

	$emailUser = CUser::GetList($by="", $order="", array('=EMAIL' => $post_data["EMAIL"]));
	while($arUser = $emailUser->Fetch())
		$USER_ID = $arUser["ID"];
			
	if(empty($USER_ID)){ // Если не нашлось email-а в БД, созданим нового юзвера
		
		$NEW_LOGIN = $post_data["EMAIL"];
		$NEW_EMAIL = $post_data["EMAIL"];
		$NEW_NAME = "";
		$NEW_LAST_NAME = "";

		if(strlen($post_data["FIO"]) > 0)
		{
			$arNames = explode(" ", $post_data["FIO"]);
			$NEW_NAME = $arNames[1];
			$NEW_LAST_NAME = $arNames[0];
		}

		$pos = strpos($NEW_LOGIN, "@");
		if ($pos !== false)
			$NEW_LOGIN = substr($NEW_LOGIN, 0, $pos);

		if (strlen($NEW_LOGIN) > 47)
			$NEW_LOGIN = substr($NEW_LOGIN, 0, 47);

		if (strlen($NEW_LOGIN) < 3)
			$NEW_LOGIN .= "___";

		$dbUserLogin = CUser::GetByLogin($NEW_LOGIN);
		if ($arUserLogin = $dbUserLogin->Fetch())
		{
			$newLoginTmp = $NEW_LOGIN;
			$uind = 0;
			do
			{
				$uind++;
				if ($uind == 10)
				{
					$NEW_LOGIN = $arUserResult["USER_EMAIL"];
					$newLoginTmp = $NEW_LOGIN;
				}
				elseif ($uind > 10)
				{
					$NEW_LOGIN = "buyer".time().GetRandomCode(2);
					$newLoginTmp = $NEW_LOGIN;
					break;
				}
				else
				{
					$newLoginTmp = $NEW_LOGIN.$uind;
				}
				$dbUserLogin = CUser::GetByLogin($newLoginTmp);
			}
			while ($arUserLogin = $dbUserLogin->Fetch());
			$NEW_LOGIN = $newLoginTmp;
		}

		$GROUP_ID = array(2);
		$def_group = COption::GetOptionString("main", "new_user_registration_def_group", "");
		if($def_group!="")
		{
			$GROUP_ID = explode(",", $def_group);
			$arPolicy = $USER->GetGroupPolicy($GROUP_ID);
		}
		else
		{
			$arPolicy = $USER->GetGroupPolicy(array());
		}

		$password_min_length = intval($arPolicy["PASSWORD_LENGTH"]);
		if($password_min_length <= 0)
			$password_min_length = 6;
		$password_chars = array(
			"abcdefghijklnmopqrstuvwxyz",
			"ABCDEFGHIJKLNMOPQRSTUVWXYZ",
			"0123456789",
		);
		if($arPolicy["PASSWORD_PUNCTUATION"] === "Y")
			$password_chars[] = ",.<>/?;:'\"[]{}\|`~!@#\$%^&*()-_+=";
		$NEW_PASSWORD = $NEW_PASSWORD_CONFIRM = randString($password_min_length+2, $password_chars);

		$user = new CUser;
		$arAuthResult = $user->Add(Array(
			"LOGIN" => $NEW_LOGIN,
			"NAME" => $NEW_NAME,
			"LAST_NAME" => $NEW_LAST_NAME,
			"PASSWORD" => $NEW_PASSWORD,
			"CONFIRM_PASSWORD" => $NEW_PASSWORD_CONFIRM,
			"EMAIL" => $NEW_EMAIL,
			"GROUP_ID" => $GROUP_ID,
			"ACTIVE" => "Y",
			"LID" => SITE_ID,
			)
		);

		if (IntVal($arAuthResult) <= 0)
		{
			$arResult["ERROR"][] = GetMessage("STOF_ERROR_REG").((strlen($user->LAST_ERROR) > 0) ? ": ".$user->LAST_ERROR : "" );
		}
		else
		{
			$USER->Authorize($arAuthResult);
		}
	} else {
		$USER->Authorize($USER_ID); // авторизуем, если новый
	}

Далее нам необходимо положить переданные товары пользователя в корзину основного сайта, приступим:

	// Шаг 2. Lexa.pro: найти переданные товары и положить в корзинку
	
	CSaleBasket::DeleteAll(CSaleBasket::GetBasketUserID()); // для начала удалим товары из корзины основного сайта, если вдруг они есть
	
	$summ = 0;
	foreach($post_data["BASKET"] as $artProd => $quant) {
		$artSelect = Array("ID", "IBLOCK_ID", "NAME", "CATALOG_GROUP_".$typePrice);
		$artFilter = Array("IBLOCK_ID" => $arIBLOCKS, "ACTIVE" => "Y", $arLinkProd => $artProd);
		$res = CIBlockElement::GetList(Array(), $artFilter, false, false, $artSelect);
		while($ob = $res->Fetch()) {

			$summ += $ob['CATALOG_PRICE_'.$typePrice]*intval($quant);

			//if(CSaleBasket::Add($arBasket)) {} else {echo 'товар не добавлен';};// добавляем объект в корзину
			Add2BasketByProductID($ob["ID"],$quant);
		}
	}

И затем последний шаг непосредственно само добавление заказа пользователя с использование встроенным методов 1С-Битрикса

	// Шаг 3. Lexa.pro: оформляем заказ
	// в моем случае не важно какие тип платильщика, способы доставки и оплаты были указаны
	
	// 3.1 Получаем корзину
	$basket = array(); // корзина
	
	$dbBasketItems = CSaleBasket::GetList(
		 array(),
		 array("FUSER_ID" => CSaleBasket::GetBasketUserID(),"LID" => SITE_ID, "ORDER_ID" => "NULL"),
		 false,
		 false,
		 array("ID", "CALLBACK_FUNC", "MODULE", "PRODUCT_ID", "QUANTITY", "PRODUCT_PROVIDER_CLASS")
	);
	while ($arItems = $dbBasketItems->GetNext())
	{
		$basket[] = $arItems;
	}
	
	// 3.2Добавляем заказ
	$arOrderDat = CSaleOrder::DoCalculateOrder(
		SITE_ID,
		$USER->GetID(),
		$basket,
		$PERSON_TYPE_ID, // тип плательщика
		array(),
		$DELIVERY_ID, // доставка
		$PAY_SYSTEM_ID, // оплата
		array(),
		$arErrors,
		$arWarnings
	);	
	
	
	$arFields = array(
		"LID" => SITE_ID,
		"PERSON_TYPE_ID" => $PERSON_TYPE_ID,
		"PAYED" => "N",
		"CANCELED" => "N",
		"STATUS_ID" => "N",
		"PRICE" => $summ,
		"CURRENCY" => "RUB",
		"USER_ID" => (int)$USER->GetID(),
		"PAY_SYSTEM_ID" => $PAY_SYSTEM_ID,
		//"PRICE_DELIVERY" => $arResult["DELIVERY_PRICE"],
		"DELIVERY_ID" => $DELIVERY_ID,
		//"DISCOUNT_VALUE" => $arResult["DISCOUNT_PRICE"],
		//"TAX_VALUE" => $arResult["bUsingVat"] == "Y" ? $arResult["VAT_SUM"] : $arResult["TAX_PRICE"],
		"USER_DESCRIPTION" => $post_data["SITE"],
		"ORDER_PROP" => array(
			85 => $post_data["PHONE"],
			87 => $post_data["FIO"],
			91 => $post_data["ADDRESS"],
			109 => $post_data["CITY"],
		),
	);
	
	//не получилось прикрепить корзину к заказу
	$orderID = (int)CSaleOrder::DoSaveOrder($arOrderDat, $arFields, 0, $arErrors);
	CSaleBasket::OrderBasket($orderID, $_SESSION["SALE_USER_ID"], SITE_ID); // привязывает товары из корзины к заказу.

Такой вот несложный скрипт получилось. Надеюсь кому-нибудь поможет:)


Возврат к списку