Польза
Часть 2. Битрикс. Магазин. Корзина

Добавление товаров в корзину в современной редакции Битрикса. Конспект вебинара

Часть 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

Написать
Вадик
А это, точно нужно?
03. Записываем изменения $basket->save();
Ответить
Аноним
Да
Ответить
Битриксоид из Колхоза Битриксоид из Колхоза
Действительно, не нужно.
Изменил хвост кода.
Спасибо
Ответить
Аноним
Что то не выходит((
Делаю примерно так:
/////////
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
Ответить
Битриксоид из Колхоза Битриксоид из Колхоза
У вас 'USE_MERGE' => 'Y', то есть да: по-идее у вас должно быть корректное склеивание количества, если id товара совпадает с каким-то элементов внутри существующей корзины.
Подозрение на то, что внутри метода $basket->getExistsItem отрабатывает неверно.
Нужно дебажить ))
Ответить
Александр
Как раз вот этого у меня нет ($basket->getExistsItem)
Что это такое?
Кроме того, я думал, что данный способ корректно добавит новый товар в корзину заказа, но и он добавляется не правильно.
Ответить
ЕК
А как можно просматривать обьект, как у вас на скрине?
Ответить
Написать