Декабрь 4, 2018
Теги: Магазин
Работа с корзиной при помощи классов "\Bitrix\Sale\Basket", "\Bitrix\Catalog\Product\Basket" и других.
Добавление в корзину товара с идентификатором в переменной $productId и количеством в переменной $quantity (замена функции "Add2BasketByProductID" в старом ядре):
$res = array();
$product = array(
'PRODUCT_ID' => $productId,
'QUANTITY' => $quantity,
/* если нужно использовать свойства корзины
'PROPS' => array(
array(
"NAME" => "Номер конфигурации",
"CODE" => "HASH",
"VALUE" => $hash,
"SORT" => "100",
),
array(
"NAME" => "Уникальный идентификатор",
"CODE" => "TIMESTAMP",
"VALUE" => $uniqueId,
"SORT" => "100",
),
),
*/
);
/* если нужно добавить товар с уникальной ценой, которая
будет браться не из каталога и не будет впоследствии меняться
$rewriteFields = array(
'PRICE'=> 120.00,
'CUSTOM_PRICE'=>'Y',
'PRODUCT_PROVIDER_CLASS'=>'', // это поле необходимо при 'CUSTOM_PRICE'=>'Y', иначе будет отображаться скидка от цены товара c PRODUCT_ID
'CURRENCY'=>'RUB', // это нужно когда не указан 'PRODUCT_PROVIDER_CLASS'
);
*/
$basketResult = \Bitrix\Catalog\Product\Basket::addProduct($product/*, $rewriteFields, $options */);
if ($basketResult->isSuccess())
{
$res['success'] = true;
$data = $basketResult->getData();
/*
Array (
[ID] => 3 // basket id
)
*/
$basket = \Bitrix\Sale\Basket::loadItemsForFUser(
\Bitrix\Sale\Fuser::getId(),
\Bitrix\Main\Context::getCurrent()->getSite()
);
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$basket->refresh($refreshStrategy);
$basket->save();
}
else
{
$res['success'] = false;
$res['error'] = $basketResult->getErrorMessages();
}
Получение объекта корзины и массива товаров в корзине:
Немного другой способ, позволяет получить корзину только с товарами, которые доступны для заказа:
Получение количества товаров и количества позиций в корзине:
Удаление позиции корзины по идентификатору позиции корзины:
Удаление товара с с идентификатором в переменной $productId из корзины (если в корзине присутствует один и тот же товар с разными свойствами, то все позиции корзины будут удалены):
Поиск позиции в корзине:
$item = $basket->getItemById($id); // по id, $item->getId()
$item = $basket->getItemByBasketCode($basketCode); // по коду корзины, $item->getBasketCode()
$item = $basket->getExistsItem($moduleId, $productId, $properties); // по коду товара и свойствам корзины
$item = $basket->getExistsItemByItem($basketItem); // по объекту BasketItem
Получение информации о позиции в корзине:
$item->getId() // ID позиции корзины
$item->getBasketCode() // код корзины
$item->getProductId() // код товара
$item->getFUserId() // id владельца корзины
$item->getQuantity() // количество товара
$item->getWeight() // вес товара
$item->canBuy() // товар доступен для покупки
$item->isDelay() // товар отложен
$item->getCurrency() // код валюты
$item->getFinalPrice() // стоимость всех единиц позиции товара
$item->getPrice() // цена с учетом скидок
$item->getBasePrice() // цена без учета скидок
$item->getDefaultPrice() // цена по умолчанию
$item->getDiscountPrice() // величина скидки
$item->isCustomPrice() // цена указана вручную (без использования провайдера)
$item->getVatRate() // ставка гдс
$item->getPriceWithVat() // цена с ндс
$item->getBasePriceWithVat() // базовая цена с ндс
$item->getInitialPrice() // исходная цена без ндс
$item->getVat() // ндс
$item->isVatInPrice() // цена включает ндс
$item->getCallbackFunction() // поле "CALLBACK_FUNC"
$item->getProviderEntity() // объект провайдера
$item->getProvider() // класс провайдера
$item->getField('PRICE') // получение значения любого поля
$item->getAvailableFields() // массив кодов всех полей
$item->getSettableFields() // массив кодов изменяемых полей
$item->getCalculatedFields() // массив кодов генерируемых полей
$item->isCalculatedField('FIELD_NAME') // поле является генерируемым
$item->isBarcodeMulti()
Получение свойств позиции корзины:
foreach ($item->getPropertyCollection() as $property) // \Bitrix\Sale\BasketPropertyItem
{
var_dump($property->getField('NAME')); // string(14) "Product XML_ID"
var_dump($property->getField('CODE')); // string(14) "PRODUCT.XML_ID"
var_dump($property->getField('VALUE')); // string(36) "1b31a4b4-6917-43c8-8591-c3812e013fcc"
var_dump($property->getField('SORT')); // string(3) "100"
var_dump($property->getField('XML_ID')); // string(16) "bx_5ef392ec7e158"
}
Функции для работы со свойствами корзины по символьному коду:
function getBasketPropertyValue(\Bitrix\Sale\BasketItem $item,$code)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
return $property->getField('VALUE');
}
return false;
}
function getBasketPropertyValues(\Bitrix\Sale\BasketItem $item)
{
$values = array();
foreach ($item->getPropertyCollection() as $property)
$values[$property->getField('CODE')] = $property->getField('VALUE');
return $values;
}
function saveBasketProperty(\Bitrix\Sale\BasketItem $item,$code,$value=false,$name=false,$sort=false,$xmlId=false)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
if($value!==false)
$property->setField('VALUE', $value);
if($name!==false)
$property->setField('NAME', $name);
if($sort!==false)
$property->setField('SORT', $sort);
if($xmlId!==false)
$property->setField('XML_ID', $xmlId);
return;
}
$property = $item->getPropertyCollection()->createItem();
$property->setField('CODE', strval($code));
$property->setField('VALUE', strval($value));
$property->setField('NAME', strval($name));
$property->setField('SORT', $sort!==false?$sort:'100');
if($xmlId!==false)
$property->setField('XML_ID', $xmlId);
}
function deleteBasketProperty(\Bitrix\Sale\BasketItem $item,$code)
{
foreach ($item->getPropertyCollection() as $property)
{
if($property->getField('CODE')!=$code)
continue;
$property->delete();
return;
}
}
// использование
// получить значение по символьному коду
var_dump(getBasketPropertyValue($item,'test'));
// получить массив значений, где ключом является символьный код
var_dump(getBasketPropertyValues($item));
// сохранить значение (добавить или обновить)
saveBasketProperty($item,'test','123');
$basket->save(); // для корзины заказа должно быть $order->save();
// удалить значение
deleteBasketProperty($item,'test');
$basket->save(); // для корзины заказа должно быть $order->save();
Получение информации обо всех позициях в корзине:
Получение информации о скидках в корзине (в компоненте "bitrix:sale.basket.basket" эта информация уже доступна в переменной $arResult['APPLIED_DISCOUNT_LIST'])
if (!$basket->getOrder())
{
$userId = $USER->GetID() ?: CSaleUser::GetAnonymousUserID();
$order = \Bitrix\Sale\Order::create(\Bitrix\Main\Context::getCurrent()->getSite(), $userId);
$result = $order->appendBasket($basket);
if ($result->isSuccess())
{
}
$discounts = $order->getDiscount();
$showPrices = $discounts->getShowPrices();
if (!empty($showPrices['BASKET']))
{
foreach ($showPrices['BASKET'] as $basketCode => $data)
{
$basketItem = $basket->getItemByBasketCode($basketCode);
if ($basketItem instanceof \Bitrix\Sale\BasketItemBase)
{
$basketItem->setFieldNoDemand('BASE_PRICE', $data['SHOW_BASE_PRICE']);
$basketItem->setFieldNoDemand('PRICE', $data['SHOW_PRICE']);
$basketItem->setFieldNoDemand('DISCOUNT_PRICE', $data['SHOW_DISCOUNT']);
}
}
}
}
$order = $basket->getOrder();
$calcResults = $order->getDiscount()->getApplyResult(true);
$fullDiscountList = $calcResults['FULL_DISCOUNT_LIST'];
$appliedDiscountList = array();
foreach ($calcResults['DISCOUNT_LIST'] as $discountData)
{
if (isset($calcResults['FULL_DISCOUNT_LIST'][$discountData['REAL_DISCOUNT_ID']]))
{
$appliedDiscountList[$discountData['REAL_DISCOUNT_ID']] = $calcResults['FULL_DISCOUNT_LIST'][$discountData['REAL_DISCOUNT_ID']];
}
}
Короткий способ получения корзины с уже рассчитанными скидками и только позициями доступными для заказа:
$basketStorage = \Bitrix\Sale\Basket\Storage::getInstance(\Bitrix\Sale\Fuser::getId(), \Bitrix\Main\Context::getCurrent()->getSite());
$basket = $basketStorage->getOrderableBasket();
$registryOrder = \Bitrix\Sale\Registry::getInstance(\Bitrix\Sale\Registry::REGISTRY_TYPE_ORDER);
$orderClassName = $registryOrder->getOrderClassName();
$order = $orderClassName::create(\Bitrix\Main\Context::getCurrent()->getSite(), $USER->GetID());
$order->appendBasket($basket);