Вопрос или проблема
В хуке woocommerce_checkout_create_order_line_item я хочу изменить метаданные элементов заказа на странице оформления заказа для количества больше одного, и теперь мне нужна цена вариации для этого расчета.
function wpler_add_quantities_to_order_items($item, $cart_item_key, $values, $order) {
setlocale(LC_MONETARY, 'de_DE');
//$product = $values['data']; // Объект продукта вариации
//$product = $item->get_product();
$product = wc_get_product($item->get_variation_id());
$price1 = $product->get_rpice(); //$product->get_variation_regular_price('min');
$price2 = $product->get_sale_price(); //$product->get_variation_sale_price('min');
$r = $order->get_billing_postcode();
$rabatt = !empty($r)&&is_numeric($r)&&$r>0 ? doubleval($r) : 0;
$ep1 = calcPrices($price1, $price2, intval($values['quantity']), $rabatt);
$ep2 = calcPrices($price1, $price2, intval($values['quantity10']), $rabatt);
$ep3 = calcPrices($price1, $price2, intval($values['quantity20']), $rabatt);
$item->add_meta_data("Цена за {$values['quantity']} шт.", money_format('%.2n', $ep1));
$item->add_meta_data("Цена за {$values['quantity10']} шт.", money_format('%.2n', $ep2));
$item->add_meta_data("Цена за {$values['quantity20']} шт.", money_format('%.2n', $ep3));
}
add_filter('woocommerce_checkout_create_order_line_item', 'wpler_add_quantities_to_order_items', 10, 4);
На обычной цене указана нормальная цена за первую единицу. На скидочной цене указана цена за остальные единицы.
Пример:
вариативный товар, обычная цена = 5.00, цена со скидкой = 1.00
заказ на 50 x вариативного товара
Итак, я вычисляю ((49 x 1)+5) = 54.00
Но мы также хотим показать различные предложения по количеству с 500 и 5000 единицами, которые должны отображаться на странице оформления заказа.
Моя проблема с функцией выше в том, что мне нужны обычная и скидочная цена вариативного продукта. Как я могу это получить?
Спасибо,
Стефан
Хорошо, я нашел решение:
В объекте $item я нашел это:
$item->legacy_values['variation_id']
что дает мне ID. Также в массиве $item->legacy_values[]
у меня есть обе цены, которые я теперь использую:
function wpler_add_quantities_to_order_items($item, $cart_item_key, $values, $order) {
setlocale(LC_MONETARY, 'de_DE');
$price1 = doubleval($item->legacy_values['price1']);
$price2 = doubleval($item->legacy_values['price2']);
$r = $order->get_billing_postcode();
$rabatt = !empty($r)&&is_numeric($r)&&$r>0 ? doubleval($r) : 0;
$ep1 = calcPrices($price1, $price2, intval($values['quantity']), $rabatt);
$ep2 = calcPrices($price1, $price2, intval($values['quantity10']), $rabatt);
$ep3 = calcPrices($price1, $price2, intval($values['quantity20']), $rabatt);
$item->add_meta_data("Цена за {$values['quantity']} шт.", money_format('%.2n', $ep1));
$item->add_meta_data("Цена за {$values['quantity10']} шт.", money_format('%.2n', $ep2));
$item->add_meta_data("Цена за {$values['quantity20']} шт.", money_format('%.2n', $ep3));
}
add_filter('woocommerce_checkout_create_order_line_item', 'wpler_add_quantities_to_order_items', 10, 4);
Ответ или решение
Вопрос, который вы подняли, обращается к хук woocommerce_checkout_create_order_line_item
, который предоставляет возможность изменять метаданные элементов заказа на этапе оформления. В данном случае вам необходимо получить цены вариаций товаров для расчета, исходя из различных количеств.
Решение проблемы
На начальном этапе вы правильно заметили, что доступ к ценам вариации можно получить через объект $item
, который уже содержит необходимую информацию в массиве наследия.
Ваш оригинальный код, как вы уже выяснили, использует $item->legacy_values
для доступа к ценам и другим важным данным. Для более точного и профессионального подхода мы можем улучшить ваш код, следуя современным стандартам программирования на PHP и практикам WordPress.
Улучшенный код
function wpler_add_quantities_to_order_items($item, $cart_item_key, $values, $order) {
// Устанавливаем локаль для форматирования цен
setlocale(LC_MONETARY, 'de_DE');
// Получаем цены из legacy_values
$price1 = doubleval($item->legacy_values['price1']); // Обычная цена
$price2 = doubleval($item->legacy_values['price2']); // Скидочная цена
$r = $order->get_billing_postcode();
// Определяем размер скидки в зависимости от почтового индекса
$rabatt = !empty($r) && is_numeric($r) && $r > 0 ? doubleval($r) : 0;
// Рассчитываем итоговые цены для заданных количеств
$ep1 = calcPrices($price1, $price2, intval($values['quantity']), $rabatt);
$ep2 = calcPrices($price1, $price2, intval($values['quantity10']), $rabatt);
$ep3 = calcPrices($price1, $price2, intval($values['quantity20']), $rabatt);
// Добавляем метаданные с рассчитанными ценами к элементу заказа
$item->add_meta_data("Цена для {$values['quantity']} штук", money_format('%.2n', $ep1));
$item->add_meta_data("Цена для {$values['quantity10']} штук", money_format('%.2n', $ep2));
$item->add_meta_data("Цена для {$values['quantity20']} штук", money_format('%.2n', $ep3));
}
// Подключаем функцию к хуку
add_filter('woocommerce_checkout_create_order_line_item', 'wpler_add_quantities_to_order_items', 10, 4);
Объяснение ключевых моментов
-
Получение цен: Использование
$item->legacy_values['price1']
и$item->legacy_values['price2']
обеспечивает корректное извлечение цен для вариаций, что является главной частью решения вашей задачи. -
Расчет сумм: Функция
calcPrices
должна быть реализована таким образом, чтобы учитывать разницу между ценой одной единицы и ценой для оставшихся единиц. Ваше объяснение об использовании цены со скидкой для всех, кроме первой единицы, вполне правильное. -
Добавление метаданных: Использование
add_meta_data
для сохранения дополнительных данных о цене в элемент заказа создает полезную информацию для последующего анализа и отображения в административной панели WooCommerce. -
Форматирование цен: Применение
money_format
помогает правильно отображать цены в соответствии с выбранной локалью, что улучшает пользовательский опыт.
Заключение
Данное решение полностью соответствует вашим требованиям к изменению метаданных в процессе оформления заказа и дает возможность эффективно работать с ценами на вариации товаров в WooCommerce. Надеюсь, что предложенный код и объяснения окажутся полезными для вашего проекта. Если возникнут дополнительные вопросы или потребуется помощь, пожалуйста, дайте знать.