Работа с корзиной

Модуль расширенного управления меню для битрикс

Декабрь 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();
}

Получение объекта корзины и массива товаров в корзине:


$basket = \Bitrix\Sale\Basket::loadItemsForFUser(

    \
Bitrix\Sale\Fuser::getId(), 
    \
Bitrix\Main\Context::getCurrent()->getSite()
);
$basketItems $basket->getBasketItems(); // все товары
$basketItemsOrderable $basket->getOrderableItems(); // только товары, доступные для заказа

Немного другой способ, позволяет получить корзину только с товарами, которые доступны для заказа:


$basketStorage = \Bitrix\Sale\Basket\Storage::getInstance(

    \
Bitrix\Sale\Fuser::getId(), 
    \
Bitrix\Main\Context::getCurrent()->getSite()
);
$basket $basketStorage->getOrderableBasket();

Получение количества товаров и количества позиций в корзине:


$productCount count($basket->getQuantityList());

$itemCount array_sum($basket->getQuantityList());
foreach (
$basket as $basketItem)
    
$arResult['basket'][$basketItem->getProductId()] = $basketItem->getQuantity(); // массив соответствий PRODUCT_ID и количества

Удаление позиции корзины по идентификатору позиции корзины:


// для успешного удаления, корзина должна быть получена через getBasket, а не через getOrderableBasket

$item=$basket->getItemById($basketId); 
$item->delete();
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
$basket->refresh($refreshStrategy);    
$basket->save();

Удаление товара с с идентификатором в переменной $productId из корзины (если в корзине присутствует один и тот же товар с разными свойствами, то все позиции корзины будут удалены):


// для успешного удаления, корзина должна быть получена через getBasket, а не через getOrderableBasket

foreach ($basket as $item)
{
    if(
$item->getProductId()!=$productId)
        continue;
    
$item->delete();
    
$refreshStrategy = \Bitrix\Sale\Basket\RefreshFactory::create(\Bitrix\Sale\Basket\RefreshFactory::TYPE_FULL);
    
$basket->refresh($refreshStrategy);    
    
$basket->save();
}

Поиск позиции в корзине:


$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();

Получение информации обо всех позициях в корзине:


$basket->getPrice(); // Цена всей корзины с учетом скидок

$basket->getBasePrice(); // Цена всей корзины без учета скидок  
$basket->getVatSum(); // Сумма  ндс
$basket->getVatRate(); // Ставка ндс

Получение информации о скидках в корзине (в компоненте "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);

См. также:

← Переход к списку