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


Статья про работу с заказами на api d7
обработчики на сохранение корзины https://dev.1c-bitrix.ru/api_d7/bitrix/sale/events/basket_saved.php
подключаем модуль
use Bitrix\Sale;
Ид сайта
$siteId = Bitrix\Main\Context::getCurrent()->getSite(); //для публичного раздела
$siteId = "s1"; //или указать жестко
//или из запроса
if (array_key_exists('site_id', $_REQUEST) && is_string($_REQUEST['site_id'])){
   $siteId = $_REQUEST['site_id'];
   if($siteId !== '' && preg_match('/^[a-z0-9_]{2}$/i', $siteId) === 1){
      define('SITE_ID', $siteId);
   }   
}

FUser - идентификатор покупателя
$fuser = Sale\Fuser::getId(); //Идентификатор покупателя текущего пользователя
$fuser = Sale\Fuser::getIdByUserId($userId) //Идентификатор покупателя  id пользователя
Создать пустую корзину
$basket = \Bitrix\Sale\Basket::create($siteId);
$basket->setFUserId($fuser); //привязать к покупателю
Получить корзину
//для корзины БЕЗ заказа
$basket = Sale\Basket::loadItemsForFUser($fuser, $siteId); //по идентификатор покупателя

//для корзины, привязанной к заказу
$basket = Sale\Order::load($orderId)->getBasket(); //по id заказа
$basket = Sale\Basket::loadItemsForOrder($order); //по заказу-объекту
ORM-класс
$basketRes = Sale\Internals\BasketTable::getList(array(
    'filter' => array(
        'FUSER_ID' => $fuser, 
        'ORDER_ID' => null,
        'LID' => $siteId,
        'CAN_BUY' => 'Y',
    )
));

while ($item = $basketRes->fetch()) {
    ...
}
актуализация корзины
$basket->refresh();
сохранение корзины
Важно!
Если корзина привязана к заказу, то сохраняем, через $order->save();
Если корзина НЕ привязана к заказу, то сохраняем, через $basket->save();

Не забывайте сохранять после всех изменений корзины

Информация о корзине общая
Товары корзины
$basketItems = $basket->getBasketItems(); // все товары
$basketItemsOrderable = $basket->getOrderableItems(); // только товары, доступные для заказа
$arBasketInfo = $basket->getListOfFormatText(); //массив товаров в читаемом виде
$arQuantityList = $basket->getQuantityList();//массив вида basketId - количество
количество товаров в корзине
var_dump(array_sum($basket->getQuantityList())); // количество товаров в корзине
var_dump(count($basket->getQuantityList())); // количество позиций в корзине
$basket->getBasePrice();  // Цена без учета скидок
$basket->getPrice(); // Цена с учетом скидок, корректно работает только для уже оформленного заказа
$basket->getWeight(); // Общий вес корзины
$basket->getVatSum(); // Сумма  ндс
$basket->getVatRate(); // Ставка ндс
$basket->getFUserId(); //Id покупателя
$basket->getOrder(); //заказ, к которому привязана 
Товары корзины формируем в  массив
$arItems = array();
foreach ($basket as $item) {
     $arItems[] = array(
       "ID" => $item->getProductId(),
       "COUNT" => $item->getQuantity(),
       "SUM" => $item->getFinalPrice(),
       "PRICE" => $item->getPrice()
    );
}
копирование корзины
//Если привязана к заказу, то скопирует вместе с заказом
$basket->createClone(); 

//скопирует, только если корзина не привязана к заказу
$basket->copy(); 

Товар в корзине
получить товар в корзине по id позиции в корзине (не путать с id товара)
$item = $basket->getItemById($id);
получить товар в корзине по id товара
$item = $basket->getExistsItem('catalog', $productId); //вернет товар, если он без свойств в корзине
$item = $basket->getExistsItem('catalog', $productId, $properties); //вернет товар, с такими же $properties
функция, которая возвращает товар в корзине по productId
если товаров несколько, только с разными свойствами, вернет первый
function GetExistsBasketItem($basket,$moduleId,$productId){
   $result = false;
   if(!empty($productId) && (intval($productId)>0) && (intval($productId)==$productId) && ($moduleId!='')){
      foreach ($basket as $item) {
         if($productId == $item->getProductId() && ($item->getField('MODULE') == $moduleId)){
            $result = $item;
            break;
         }
      }
   }
   return $result;
}
$item = GetExistsBasketItem($basket,'catalog',$productID); //вернет false, если нет такого
Действия над товаром

$item->setField('QUANTITY', $quantity); //Обновить поле товара
$item->setFields(array( 'QUANTITY' => $quantity, 'PRICE' => $price)); //Обновить несколько полей товара
$item->delete(); //удалить товар

Информация о товаре в корзине
список полей товара в корзине https://dev.1c-bitrix.ru/rest_help/sale/basketitem/sale_basketitem_getFields.php
//все поля элемента корзины
$item->getFields(); //вариант 1
$item->getFieldsCatalogProduct(); //вариант 2

$item->getField('PRICE') // получение значения любого поля
$item->getId() // ID позиции корзины
$item->getBasketCode() // код корзины
$item->getProductId() // id товара
$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->getAvailableFields() //  массив кодов всех полей
$item->getSettableFields() // массив кодов изменяемых полей

$item->getCalculatedFields() // массив кодов генерируемых полей
$item->isCalculatedField('FIELD_NAME') // поле является генерируемым

$item->isBarcodeMulti()
получить название единицы измерения товара
$arProductIds = array($productId1,$productId2); // ID товаров
$arMeasure = \Bitrix\Catalog\ProductTable::getCurrentRatioWithMeasure($arProductIds);  

echo $arMeasure[$productId1]['MEASURE']['SYMBOL_RUS'];
echo $arMeasure[$productId2]['MEASURE']['SYMBOL_RUS'];

Добавление товаров в корзину

Вариант 1.
$currency = Bitrix\Currency\CurrencyManager::getBaseCurrency(); // Базовая валюта  "RUB","USD",...
$item = $basket->createItem('catalog', $productId); 

//если цена рассчитывается стандартными методами битрикса
$item->setFields(array(
        'QUANTITY' => $quantity,
        'CURRENCY' => $currency,
        'LID' => $siteId,
        'PRODUCT_PROVIDER_CLASS' =>\Bitrix\Catalog\Product\Basket::getDefaultProviderName()
));

//если своя цена
$item->setFields(array(
        'QUANTITY' => $quantity,
        'CURRENCY' => $currency,
        'LID' => $siteId,
        'PRICE' => $customPrice,
        'CUSTOM_PRICE' => 'Y',          
));

$basket->save(); //можно все товары добавить, а потом сохранить корзину
Вариант 2.  аналог Add2BasketByProductID
Bitrix\Main\Loader::includeModule("catalog");
$product = array(
    'PRODUCT_ID' => $productId,
    'QUANTITY' => $quantity,
    'PROPS' => array(
        array(
            "NAME" => "Имя свойства",
            "CODE" => "CODE_PROP",
            "VALUE" => "Значение свойства",
            "SORT" => "100",
        ),       
    ),
);
$basketResult = \Bitrix\Catalog\Product\Basket::addProduct($product/*, $rewriteFields, $options */);
if (!$basketResult->isSuccess()){
    //$basketResult->getErrorMessages();
}

Свойства товаров в корзине
получить свойства товара
вариант1.
$basketPropertyCollection = $item->getPropertyCollection(); // \Bitrix\Sale\BasketPropertyItem
foreach ($basketPropertyCollection as $basketProperty){ 
    $name = $basketProperty->getField('NAME')); // любое поле свойства 'NAME','CODE','VALUE','SORT','XML_ID'   
} 
$basketPropertyCollection->getPropertyValues(); //возвращает массив свойств
вариант2. ORM
$basketPropRes = Sale\Internals\BasketPropertyTable::getList(array(
   'filter' => array(
      "BASKET_ID" => $basketItemId,
   ),
));
while ($property = $basketPropRes->fetch()) {
   var_dump($property);
}
Действия над свойствами товаров
$basketProperty->setField('VALUE', 'Значение'); //изменить
$basketProperty->delete(); //Удалить

//добавить или обновить свойство
$basketPropertyCollection->setProperty(array(
    array(
       'NAME' => 'Имя свойства',
       'CODE' => 'CODE_PROP',
       'VALUE' => 'Значение свойства',
       'SORT' => 100,
    ),
));