Польза
Часть 1. Битрикс. Магазин. Заказы и корзины

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

Часть 1 / Часть 2 / Часть 3

Вебинар:

Трансформации начались с момента выпуска совершенно нового движка магазина. Чтобы обновиться, необходимо было провести конвертацию заказов.

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

Одна из характеристик нового подхода: обрабатывать во время записи только те данные, которые реально обновились.

Два основных класса

\Bitrix\Sale\Order и \Bitrix\Sale\Basket

Специфика: работать с объектом как с единым целым и сохранять данные только у головной сущности. Механика нового подхода сама решит, что внутри изменилось, что требует сохранения в базу данных и пересчёт.

Примеры кода и ошибок:

Исходная ситуация: получаем текущий заказ и добавляем товар

\Bitrix\Main\Loader::includeModule('sale');

$orderId = 752;
$order = \Bitrix\Sale\Order::load($orderId);

$productId = 412;
$basket = $order->getBasket();
$basketItem = $basket->createItem('catalog', $productId);

// Вариант 1:
// Устанавливаем количество товаров 5
$basketItem->setField('QUANTITY', 5);
// Ставим цену и маркируем её как кастомную
$basketItem->setPrice(175, true);

// Вариант 2:
$basketItem->setFields([
    'QUANTITY' => 5,
    'PRICE' => 175,
    'CUSTOM_PRICE' => 'Y'
]);

// Сохраняем головную сущность
$order->save();

Ошибка:

// Головной объект (заказ)
// фактически не обновлён
// и значит не произведены
// необходимые пересчёты
$basket->save();

Излишне (двойное сохранение):

$basket->save();
$order->save();

Правильно:

$order->save();

Современный подход

После выпуска топ-редакции (1С-Битрикс24: Интернет-магазин+CRM), чтобы код работы с главными сущностями интернет-магазина был универсальным, следует работать с реестром классов:

use Bitrix\Sale\BasketBase;
use Bitrix\Sale\Fuser;
use Bitrix\Sale\OrderBase;
use Bitrix\Sale\Registry;

// Получаем объект, заведующий реестрами
$registry = Registry::getInstance(Registry::REGISTRY_TYPE_ORDER);

/**
 * @var $orderClass OrderBase
 * @var $basketClass BasketBase
 */

// Получаем класс работы с заказами
$orderClass = $registry->getOrderClassName();
// Получаем класс работы с корзинами
$basketClass = $registry->getBasketClassName();

// Читаем заказ
$order = $orderClass::load($orderId);
// Читаем корзину из объекта заказа
$basket = $order->getBasket();

// Читаем корзину через класс по объекту заказа
$basket = $basketClass::loadItemsForOrder($order);

// Читаем корзину для текущего покупателя
$currentFUser = Fuser::getId();
$basket = $basketClass::loadItemsForFUser($currentFUser, SITE_ID);

/**
 * @var \Bitrix\Sale\BasketItem $bi
 */

// Добываем данные по полям товаров в корзине
foreach ($basket->getBasketItems() as $bi) {
    $basketProductFields = $bi->getFieldValues();
}

Использование библиотеки регистров открывает возможности по кастомизации локальных движков методом регистрации своих классов-обработчиков

Список стандартных классов в реестре заказов:

Registry::ENTITY_ORDER =>
'\Bitrix\Sale\Order',

Registry::ENTITY_PAYMENT =>
'\Bitrix\Sale\Payment',

Registry::ENTITY_PAYMENT_COLLECTION =>
'\Bitrix\Sale\PaymentCollection',

Registry::ENTITY_SHIPMENT =>
'\Bitrix\Sale\Shipment',

Registry::ENTITY_SHIPMENT_COLLECTION =>
'\Bitrix\Sale\ShipmentCollection',

Registry::ENTITY_SHIPMENT_ITEM =>
'\Bitrix\Sale\ShipmentItem',

Registry::ENTITY_SHIPMENT_ITEM_COLLECTION =>
'\Bitrix\Sale\ShipmentItemCollection',

Registry::ENTITY_SHIPMENT_ITEM_STORE =>
'\Bitrix\Sale\ShipmentItemStore',

Registry::ENTITY_SHIPMENT_ITEM_STORE_COLLECTION =>
'\Bitrix\Sale\ShipmentItemStoreCollection',

Registry::ENTITY_PROPERTY_VALUE_COLLECTION =>
'\Bitrix\Sale\PropertyValueCollection',

Registry::ENTITY_PROPERTY_VALUE =>
'\Bitrix\Sale\PropertyValue',

Registry::ENTITY_PROPERTY =>
'Bitrix\Sale\Property',

Registry::ENTITY_TAX =>
'\Bitrix\Sale\Tax',

Registry::ENTITY_BASKET_PROPERTY_ITEM =>
'\Bitrix\Sale\BasketPropertyItem',

Registry::ENTITY_BUNDLE_COLLECTION =>
'\Bitrix\Sale\BundleCollection',

Registry::ENTITY_BASKET =>
'\Bitrix\Sale\Basket',

Registry::ENTITY_BASKET_ITEM =>
'\Bitrix\Sale\BasketItem',

Registry::ENTITY_BASKET_PROPERTIES_COLLECTION =>
'\Bitrix\Sale\BasketPropertiesCollection',

Registry::ENTITY_DISCOUNT =>
'\Bitrix\Sale\Discount',

Registry::ENTITY_DISCOUNT_COUPON =>
'\Bitrix\Sale\DiscountCouponsManager',

Registry::ENTITY_ORDER_DISCOUNT =>
'\Bitrix\Sale\OrderDiscount',

Registry::ENTITY_OPTIONS =>
'Bitrix\Main\Config\Option',

Registry::ENTITY_PERSON_TYPE =>
'Bitrix\Sale\PersonType',

Registry::ENTITY_ORDER_STATUS =>
'Bitrix\Sale\OrderStatus',

Registry::ENTITY_DELIVERY_STATUS =>
'Bitrix\Sale\DeliveryStatus',

Registry::ENTITY_ENTITY_MARKER =>
'\Bitrix\Sale\EntityMarker',

Registry::ENTITY_ORDER_HISTORY =>
'Bitrix\Sale\OrderHistory',

Registry::ENTITY_NOTIFY =>
'Bitrix\Sale\Notify',

Registry::ENTITY_TRADE_BINDING_COLLECTION =>
'Bitrix\Sale\TradeBindingCollection',

Registry::ENTITY_TRADE_BINDING_ENTITY =>
'Bitrix\Sale\TradeBindingEntity',

Получение класса из реестра:

Битрикс. Магазин, заказы, корзина. Получение класса из реестра

Переопределение класса-обработчика:

Событие для проброса своих классов-обработчиков:

use Bitrix\Main\EventManager;

(EventManager::getInstance())
    ->addEventHandler(
        'main',
        'OnInitRegistryList',
        [
            '\AlexeyGfi\BasketHelper',
            'registerCustomInstances'
        ]
    );

В методе \Bitrix\Sale\Registry::initRegistry результат обработчика будет с-array_merge поверх стандартного списка:

Битрикс. Магазин, заказы, корзина. Переопределение класса в реестре обработчиков

Обсуждение статьи

Написать