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); // привязывает товары из корзины к заказу.
Такой вот несложный скрипт получилось. Надеюсь кому-нибудь поможет:)