Добавление товаров в корзину в современной редакции Битрикса. Конспект вебинара
Часть 1 / Часть 2 / Часть 3
Вебинар:
¶Добавление в корзину
Процедура, которую проводит система при добавлении товара в корзину через публичную часть:
- проверка существования товара, его доступности, формирование данных для элемента корзины
- создание элемента корзины
- запрос у провайдера цен стоимости товара (можно добавлять без указания цены, провайдер сам вычислит актуальную), запрос доступного количества, учёт доступности товара;
- запись в базу
Было: $basketId = Add2BasketByProductID(27, 3);
Стало (! читать про особенность кода ниже):
use Bitrix\Catalog\Product\Basket;
/**
* Поля, которые могут быть установлены
* нами при добавлении товара в корзину:
*
* "BARCODE_MULTI" "BASE_PRICE"
* "CALLBACK_FUNC" "CAN_BUY"
* "CANCEL_CALLBACK_FUNC" "CATALOG_XML_ID"
* "CURRENCY" "CUSTOM_PRICE"
* "DELAY" "DETAIL_PAGE_URL"
* "DIMENSIONS" "DISCOUNT_COUPON"
* "DISCOUNT_NAME" "DISCOUNT_PRICE"
* "DISCOUNT_VALUE" "LID"
* "MARKING_CODE_GROUP" "MEASURE_CODE"
* "MEASURE_NAME" "NAME" "NOTES"
* "ORDER_CALLBACK_FUNC" "PAY_CALLBACK_FUNC"
* "PRICE_TYPE_ID" "PRICE"
* "PRODUCT_ID" "PRODUCT_PRICE_ID"
* "PRODUCT_PROVIDER_CLASS" "PRODUCT_XML_ID"
* "QUANTITY" "RECOMMENDATION"
* "SET_PARENT_ID" "SORT"
* "SUBSCRIBE" "TYPE"
* "VAT_INCLUDED" "VAT_RATE"
* "WEIGHT" "XML_ID"
*/
$product = [
'PRODUCT_ID' => $productId,
'QUANTITY' => $quantity,
'CUSTOM_PRICE' => 777,
'PROPS' => [
[
"NAME" => 'Материал',
"CODE" => 'matherial',
"VALUE" => 'Натуральная кожа',
"SORT" => 100,
],
[
"NAME" => 'Цвет заклёпок',
"CODE" => 'clips_color',
"VALUE" => 'Серебро',
"SORT" => 200,
],
]
];
// Только если мы хотим
// заменить на отличающиеся
// от того, что есть в каталоге
$product += [
'WEIGHT' => 700,
'DIMENSIONS' => [
'WIDTH' => 50,
'LENGTH' => 100,
'HEIGHT' => 1000,
],
];
// По сути мержатся поверх $product.
// Единственный ключ, обрабатываемый отдельно — SITE_ID
// При установке этого ключа
// контекст переключается на указанный код сайта
// ... вместо константы SITE_ID
$basketFields = [
// Этот ключ переопределит ключ из $product
'QUANTITY' => $quantity * 2,
// Контекст будет переключен на другой сайт
'SITE_ID' => 's2'
];
$options = [
// Если такой товар уже есть в корзине,
// не объединять добавляемый с ним
// ...а создавать рядом новую запись в корзине
'USE_MERGE' => 'N',
// Если в корзину добавляется
// товарное предложение:
// Catalog\ProductTable::TYPE_OFFER
// свойства товара
// будут заполнены автоматически
'FILL_PRODUCT_PROPERTIES' => 'Y',
];
Basket::addProduct(
$product, $basketFields, $options
);
Свойства в объекте корзины:
(!) Особенность в том, что каждый вызов кода выше будет поднимать объект корзины, добавлять в неё новый товар и сохранять в базу данных. Подходит для добавления например через аякс.
¶Комплексное добавление
Отделяем поднятие и фиксацию корзины от добавления в неё элементов.
use \Bitrix\Sale;
use \Bitrix\Catalog\Product\Basket;
$registry = Sale\Registry::getInstance(
Sale\Registry::REGISTRY_TYPE_ORDER
);
$context = ['SITE_ID' => SITE_ID];
$options = [
// Если такой товар уже есть в корзине,
// не объединять добавляемый с ним
// ...а создавать рядом новую запись в корзине
'USE_MERGE' => 'N',
// Если в корзину добавляется
// товарное предложение:
// Catalog\ProductTable::TYPE_OFFER
// ...свойства товара
// будут заполнены автоматически
'FILL_PRODUCT_PROPERTIES' => 'Y',
// При чтении информации о товаре через
// \CIBlockElement::GetList
// проверяет (или нет) доступы
'CHECK_PERMISSIONS' => 'N',
];
// 01.1 Поднимаем объект корзины
$basketClass = $registry->getBasketClassName();
$basket = $basketClass::loadItemsForFUser(
Sale\Fuser::getId(), SITE_ID
);
// 02. Набрасываем товаров
$productInfo01 = [/* ... */];
$productInfo02 = [/* ... */];
$productInfo03 = [/* ... */];
$res = Basket::addProductToBasket(
$basket, $productInfo01, $context, $options
);
$res = Basket::addProductToBasket(
$basket, $productInfo02, $context, $options
);
$res = Basket::addProductToBasket(
$basket, $productInfo03, $context, $options
);
// Дальше, например:
// $order->setBasket($basket);
// $order->save();
Обсуждение статьи 7
Делаю примерно так:
/////////
use \Bitrix\Sale;
use \Bitrix\Catalog\Product\Basket;
// получаем заказ по id
$orderOb = \Bitrix\Sale\Order::load($order['ORDER_ID']);
// получаем корзину заказа
$basket = $orderOb->getBasket();
// Далее происходит некий цикл, где мы добавляем товары, вот так
$context = ['SITE_ID' => 's1'];
$options = ['USE_MERGE' => 'Y', 'FILL_PRODUCT_PROPERTIES' => 'Y'];
$product = [
'PRODUCT_ID' => $arOrders[$keyOrder]['BASKET'][$keyBasket]['PRODUCT_ID'],
'QUANTITY' => $arOrders[$keyOrder]['BASKET'][$keyBasket]['COUNT'],
'CURRENCY' => 'RUB'
];
Basket::addProductToBasket($basket, $product, $context, $options);
Потом выходим из цикла и сохраняем заказ
$orderOb->save();
////////////////
По идее 2 товара должны пересчитаться кол-во и стоимость, а третий товар добавиться с нужным кол-вом, а они добавляются вот так: https://disk.yandex.ru/i/8SJt_ug0kgJZLg
Что это такое?
Кроме того, я думал, что данный способ корректно добавит новый товар в корзину заказа, но и он добавляется не правильно.