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