Позиции заказа в WooCommerce

Вчера внезапно осознал, что на этом сайте у меня нет подробного гайда про позиции заказов. Ну что же, вот и он – в нём поговорим про то, что это такое, а также про то, как добавлять, изменять и удалять позиции заказа в коде.

Кстати, прежде чем мы начнём, хочу порекомендовать вам два собственных видеокурса – по созданию темы WooCommerce и по созданию плагина для WooCommerce.

Что такое позиции заказа?

Чтобы быстро понять, что такое позиции заказа, рекомендую взглянуть на этот скриншот:

Позиции заказа в WooCommerce
Позиции заказа доступны на странице редактирования заказа, но обратите внимание, что вы не сможете изменять состав заказа для некоторых его статусов, например «В обработке», изменить его состав можно например в статусе «В ожидании оплаты».

Итак, как вы возможно догадались позиции заказа бывают трёх типов:

  1. Товары – тип line_item,
  2. Доставка – тип shipping,
  3. Сборы – тип fee.

Также позиции заказа имеют свои собственные таблицы в базе данных WooCommerce – это {префикс}woocommerce_order_items и {префикс}woocommerce_order_itemmeta – для метаданных.

Когда-то давно у меня возникал вопрос – зачем создавать отдельные таблицы в базе данных для элементов заказа, а не линковать товары по их айдишнику? И ответ очень прост на самом деле – предположим, что пользователь купил товар, а через месяц его цена изменилась. Но мы ведь не можем при этом перерассчитывать стоимость этого товара в старом заказе 🙃

Как получить и вывести позиции заказа?

Для получения позиций заказа мы можем использовать метод get_items() объекта класса WC_Order. У этого метода есть единственный параметр, $types – тип позиций заказа, которые нам нужно получить, значения могут быть line_itemfeeshipping. Можно передать несколько значений в виде массива. По умолчанию – line_item, то есть только товары.

// предположим, что у нас заказ с ID=5, получим его объект
$order_id = 5;
$order = wc_get_order( $order_id );
 
// теперь из объекта получаем все типы позиций заказа
$order_items = $order->get_items( array( 'line_item', 'fee', 'shipping' ) );
 
if ( ! is_wp_error( $order_items ) ) {
	// выводим их данные в цикле
	foreach( $order_items as $item_id => $order_item ) {
 
		echo $order_item->get_order_id(); // ID заказа
		echo $order_item->get_name(); // название позиции заказа
		echo $order_item->get_total(); // цена позиции
		echo $order_item->get_type(); // тип: line_item | fee | shipping
 
		// только для товаров:
		echo $order_item->get_quantity(); // количество товара
		echo $order_item->get_product_id(); // ID товара
		echo $order_item->get_variation_id(); // ID вариации
		echo $order_item->get_product(); // объект товара, ассоциированного с позицией
	}
 
}

Добавление позиции в заказ

Также при помощи всего лишь двух функций – wc_add_order_item() и wc_add_order_item_meta() мы можем добавить позиции в заказ. Если вам интересно создание самого заказа через код, напишите в комментариях, я опубликую отдельный урок об этом.

Попробуем добавить позицию заказа типа line_item, то есть товар.

// допустим мы будем добавлять позиции в заказ с ID=5
$order_id = 5;
 
$order_item_id = wc_add_order_item( 
	$order_id, 
	array(
		'order_item_name' => 'Шапочка', // может отличаться от названия товара
		'order_item_type' => 'line_item', // указываем тип позиции – товар
	)
);
 
wc_add_order_item_meta( $order_item_id, '_qty', 2, true ); // количество
wc_add_order_item_meta( $order_item_id, '_product_id', 13, true ); // ID товара
// также можно добавить "_variation_id"
wc_add_order_item_meta( $order_item_id, '_line_subtotal', 10, true ); // цена одной единицы
wc_add_order_item_meta( $order_item_id, '_line_total', 20, true ); // общая стоимость
 
$order = new WC_Order( $order_id );
$order->calculate_totals(); // пересчитываем стоимость заказа

Теперь давайте добавим сбор.

$order_item_id = wc_add_order_item( 
	$order_id, 
	array(
 		'order_item_name' => 'НДС 5%',
 		'order_item_type' => 'fee',
	)
);
wc_add_order_item_meta( $order_item_id, '_fee_amount', 20, true );
wc_add_order_item_meta( $order_item_id, '_line_total', 20, true );
 
$order = new WC_Order( $order_id );
$order->calculate_totals(); // пересчитываем стоимость заказа

Изменение уже существующих позиций в заказе

Можем рассмотреть это на двух примерах – в первом примере мы переприкрепим позицию к другому заказу, для этого воспользуемся функцией wc_update_order_item().

wc_update_order_item( 
	$order_item_id, 
	array( 
		'order_id' => $new_order_id // ID нового заказа, к которому прикрепляем позицию
	)
);

Во втором примере мы лишь изменим количество товара в позиции функцией wc_update_order_item_meta(). Предположим, что цена товара равна 10, тогда при изменении количества товара на 3, общую стоимость нам тоже нужно изменить на 30.

wc_update_order_item_meta( $order_item_id, '_qty', 3 );
wc_update_order_item_meta( $order_item_id, '_line_total', 30 );

И ещё один момент – не забывайте пересчитывать весь заказ методом calculate_totals().

Удаление позиций из заказа

Классный момент это то, что когда вы удаляете целиком позицию из заказа функцией wc_delete_order_item(), то вам не нужно отдельно беспокоиться о его метаданных, т к они будут удалены автоматически.

wc_delete_order_item( $order_item_id );

Но если вы хотите удалить только определённый мета-ключ, при этом не удаляя позицию целиком, то можете воспользоваться функцией wc_delete_order_item_meta().

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Если вам нужна помощь с сайтом или разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда будем рады вам помочь!

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, если же код – меньше одной строчки, то можно и в <code></code>.