Оформление быстрого заказа в 1с-битрикс

Оформление быстрого заказа в 1с-битрикс

Сейчас практически любой интернет-магазин имеет функцию быстрого заказа. Кто-то просто отправляет информацию о заказе в письме, а кто-то формирует такой заказ, как новый заказ. Мы же решили сделать второй вариант и добавляем новый быстрый заказ к основным. Таким образом мы получаем полноценный заказ и можем с ним работать, как и со всеми остальными. Так же мы решили сделать оформление быстрого заказа не только в карточке товара, но и в корзине (не путать с полноценным оформлением заказа). Таким образом, клиент может купить не только 1 товар, а сразу несколько введя условно только номер телефона. Многих устраивает именно такой вариант, а кто-то использует полноценное оформление заказа, чтобы сразу указать все необходимы данные и получить мгновенный расчет стоимости доставки.

Перейдем непосредственно к формированию нового заказа. Мы не будем рассказывать, как создать всплывающую форму для ввода емейла, а перейдем сразу к программной части.

Итак, мы получаем из формы 4 параметра: имя, телефон, емейл и ид товара. Либо, если нет ИД, то передаем параметр, указывающий о том, что мы оформляем корзину пользователя. Первым делом определим ид сайта и достанем корзину пользователя.

global $USER;
$siteId = \Bitrix\Main\Context::getCurrent()->getSite();//достаем текущий сайт
$basket = Sale\Basket::loadItemsForFUser(Sale\Fuser::getId(), $siteId);//достаем корзину пользователя
Мы определяем местоположение клиента по его IP и имея его, формируем заказ именно в этот город. Правда, если мы не смогли его определить, то принудительно ставим Москву. Ничего, менеджеры потом сами узнают у него, куда ему заказ отгрузить)
$region = $arLocs["REGION_ID"];

Далее начинаем работать с пользователем. Есть четыре варианта дальнейшего поведения. Первый вариант: человек уже авторизован, тогда нам в принципе нечего больше с ним сделать. Второй вариант: пользователь указал емейл(хотя он у нас необязателен), тогда ищем пользователя с этим емейлом и уже работаем с ним(в теории не совсем верно, мало ли клиент ошибся и ввел не тот емейл, а он уже есть в базе), если емейла нет, то регистрируем пользователя с этим емейлом. И четвертый вариант: нам ничего не остается делать, как использовать фейкового пользователя. Конечно, в битриксе есть анонимные пользователи, но формируются они, по сути, так же, как и обычные, мы же используем готового пользователя. Зачем плодить анонимов?)

$USERID = false;
if ($USER->IsAuthorized()){
	$USERID = IntVal($USER->GetID());
}elseif($_POST["EMAIL"]!=""){
$by = 'id';
	$orders = 'desc';
	$rsUsers = CUser::getList($by, $orders, array("EMAIL" => $_POST["EMAIL "]));                        
	if ($rsUser = $rsUsers->Fetch()) 
	{
		$USERID = $rsUser["ID"];
	}
	if(!$USERID){
		$passw=rndstr();
		$user = new CUser;
		$usr_fio = explode(' ', $_POST["NAME"]);
		$arFields = Array(
		"NAME"              => $usr_fio[1],
		"LAST_NAME"         => $usr_fio[0],
		"SECOND_NAME"		  => $usr_fio[2],
		"EMAIL"             => $_POST["EMAIL"],
		"LOGIN"             => $_POST["EMAIL"],
		"ACTIVE"            => "Y",
		"PASSWORD"          => $passw,
		"CONFIRM_PASSWORD"  => $passw,
	);

	$USERID = $user->Add($arFields);
	}
}else{
	$USERID = IntVal(3);//ИД фейкового пользователя: 3
}

С пользователем определились, двигаемся дальше. Создаем объект заказа для данного пользователя. И формируем корзину для этого заказа. Как говорилось ранее, у нас 2 варианта, смотря что мы делаем. Первое – это 1 товар, а второе – это целая корзина. Итак, рассмотрим первый вариант. Пользователь решил купить 1 товар. Чтобы он не потерял текущую корзину, мы ее сохраняем отдельно, а все что есть в ней – удаляем. Затем добавляем уже нужный товар.

$basketItemList = $basket->getOrderableItems();
$basketItems = $basketItemList->getBasketItems();//Заносим сюда запись корзины
if(count($basketItems)>0){
foreach ($basketItems as $basketItem) {//перебираем записи
		$basketItem->delete();//удаляем запись
	}
}
		
if ($item = $basket->getExistsItem('catalog', $_POST["ID"])) {//Проверяем, есть ли такой товарв в корзине
	$item->setField('QUANTITY', $item->getQuantity() + 1);//если есть – увеличиваем его количество
} else {//а если нет?
	$item = $basket->createItem('catalog', $_POST["ID"]);//добавляем товар в корзину
	$item->setFields(array(
		'QUANTITY' => 1,
		'CURRENCY' => \Bitrix\Currency\CurrencyManager::getBaseCurrency(),
		'LID' => \Bitrix\Main\Context::getCurrent()->getSite(),
		'PRODUCT_PROVIDER_CLASS' => 'CCatalogProductProvider',
	));
}
$basket->save();//сохраняем корзину

Так же тут можно сформировать массив со всеми товарами из корзины, чтобы затем передать данные о заказанных товарах в аналитику янлекса, гугла и т.д. При втором варианты мы ничего не делаем.

Далее нем надо разобраться с вариантами доставок, и в зависимости от конечной точки доставки сформировать необходимый пулл данных. Самый простой вариант руками определить нужную доставку и оплату, чтобы потом подставить все это в данные заказа. Например, так:

$deliv_id = 2;//ид варианта доставки(у нас это самовывоз)
$deliv_price = 0;//стоимость доставки
$payments_id = 1;//вариант оплаты(у нас это наличные)
Далее добавим имеющиеся данные в свойства заказа. Т.к. мы все делаем руками, то и свойства мы проставляем тоже руками.
$orderProperties[1] = $_POST["NAME"];
$orderProperties[3] = $_POST["PHONE"];
$orderProperties[28] = "Y";//это у нас свойство, которое заполняется при быстром заказе, чтобы менеджеры не тупили
if($_POST["EMAIL"]!=""){//если указали емейл
	$orderProperties[2] = $_POST["EMAIL"];
}
$propertyCollection = $order->getPropertyCollection();//создаем коллекцию свойств заказа
foreach ($propertyCollection as $property)
{
	$arProperty = $property->getProperty();
	if($orderProperties[$arProperty['ID']]!=""){
		$propertyCollection->setValuesFromPost(array('PROPERTIES' => Array($arProperty["ID"]=>$orderProperties[$arProperty['ID']])), array());//устанавливаем нужные свойства
}
}

Далее привяжем нашу корзину к заказу и установим тип плательщика – физ. лицо.

$result = $order->setBasket($basketItemList);
if (!$result->isSuccess())
	print_r($result->getErrors());
	
$order->setPersonTypeId('1');	

Далее мы должны добавить в заказ отгрузки.

$shipmentCollection = $order->getShipmentCollection();
$shipment = $shipmentCollection->createItem();
	
$arDeliveryServiceAll = Sale\Delivery\Services\Manager::getRestrictedObjectsList($shipment);
$deliveryObj = $arDeliveryServiceAll[$deliv_id];//достаем объект отгрузки
$dlv_id = $deliveryObj->getId();//получаем ид нужной доставки
if(!$dlv_id){//если что-то пошло не так, и мы не получили ид доставки
	$dlv_id = "2";//ставим номер два, самовывоз
}

Теперь надо добавить в отгрузку товары из корзины. И пересчитать стоимость доставки.

$shipmentItemCollection = $shipment->getShipmentItemCollection(Sale\Delivery\Services\Manager::getObjectById($dlv_id));
foreach ($order->getBasket() as $item)
{
	$shipmentItem = $shipmentItemCollection->createItem($item);
	$shipmentItem->setQuantity($item->getQuantity());
}

$shipmentCollection = $shipment->getCollection();
if (!empty($arDeliveryServiceAll)) {
	if ($deliveryObj->isProfile()) {
		$name = $deliveryObj->getNameWithParent();
	} else {
		$name = $deliveryObj->getName();
	}
	$shipment->setFields(array(
		'DELIVERY_ID' => $deliveryObj->getId(),
		'DELIVERY_NAME' => $name,
		'CURRENCY' => $order->getCurrency()
	));

	$shipmentCollection->calculateDelivery();
}

Затем сформируем оплаты и сохраним заказ.

$paySystemObject = Sale\PaySystem\Manager::getObjectById($payments_id);
$paymentCollection = $order->getPaymentCollection();

$payment = $paymentCollection->createItem($paySystemObject);
$payment->setFields(array(
	'SUM' => $order->getPrice(),
	'CURRENCY'=> $payment->arParams['SELL_CURRENCY'],
));
	
$order->save();

Дело сделано. Заказ в базе, все уведомления уже разосланы. Можно закругляться и идти пить кофе. Напоследок можем получить номер и ид заказа, чтобы написать его пользователю. Как?

$ORDER_ID = $order->GetId();//ид заказа
$ORDER_NUMBER = $order->getField('ACCOUNT_NUMBER');//номер заказа
$ORDER_PRICE = $order->getPrice();//стоимость заказа
$ORDER_PRICE_DELIVERY= $order->getDeliveryPrice();//стоимость доставки заказа

Комментировать