разделить 1 товар в корзине на имеющийся в наличии и заказанный обратно

Вопрос или проблема

Если у меня есть остаток товара 2 и я разрешаю предварительные заказы, а клиент добавляет количество 5 в корзину, корзина показывает 1 элемент с количеством 5 на предварительном заказе.

Есть ли способ разбить эту запись в корзине на 2, одну строку с количеством на складе и вторую с количеством предварительного заказа?

Таким образом, если у меня есть 2 на складе, и пользователь добавляет 5 в корзину, они увидят два элемента:

Название продукта – Количество: 2

Название продукта (предварительный заказ) – Количество: 3

Вот плагин, который делает это, если кому-то еще это нужно. Просто сохраните это в

<?php
/*
Plugin Name: WC Split Cart Backorders 
Plugin URI: https://www.creativemonarchy.com
Description: Простой плагин, который помогает вам разделить товары на складе и предварительные заказы для одного и того же продукта в вашей корзине.
Author: Sohrab Iravani
Version: 1.0
Author URI: https://www.creativemonarchy.com
Requires at least: 4.9
Tested up to: 5.2.3
Text Domain: wc_split_cart_backorder
Domain Path: /languages/
*/

// Разделить заказы на складе и предварительные заказы в корзине
add_action( 'woocommerce_add_to_cart', 'split_bkorders', 10, 6 );
function split_bkorders( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ) {
    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $quantity;
        $product = $cart_item['data'];
        $stock_qty = $product->get_stock_quantity();
        $item_qty  = $cart_item['quantity'];
        if ($quantity > $stock_qty && $stock_qty > 0) {
            WC()->cart->set_quantity( $cart_item_key, $stock_qty );
            $backorder = $item_qty - $stock_qty;
            $cart_item_data['unique_key'] = md5( microtime() . rand() . "xxx" );
            $cart_item_data['pr_field'] = 'backorder';
            WC()->cart->add_to_cart( $product_id, 1, $variation_id, $variation, $cart_item_data );
            $count = 0;
            foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
                if ($count == 1) {
                    WC()->cart->set_quantity( $cart_item_key, $backorder );
                    break;
                }
                $count++;
            }
        } elseif ($stock_qty < 0) {
            $cart_item_data="backorder";
            WC()->cart->cart_contents[$cart_item_key]['pr_field'] = $cart_item_data;
        }
        break;
    }
}
// Добавить пользовательское поле "backorder" к элементу корзины
function plugin_republic_get_item_data( $item_data, $cart_item_data ) {
    if( isset( $cart_item_data['pr_field'] ) ) {
        $item_data[] = array(
            'key' => __( 'Тип', 'plugin-republic' ),
            'value' => wc_clean( $cart_item_data['pr_field'] )
        );
    }
    return $item_data;
}
// Добавить пользовательское поле "backorder" повсюду
add_filter( 'woocommerce_get_item_data', 'plugin_republic_get_item_data', 10, 2 );
function plugin_republic_checkout_create_order_line_item( $item, $cart_item_key, $values, $order ) {
    if( isset( $values['pr_field'] ) ) {
        $item->add_meta_data(
            __( 'Тип', 'plugin-republic' ),
            $values['pr_field'],
            true
        );
    }
}
add_action( 'woocommerce_checkout_create_order_line_item', 'plugin_republic_checkout_create_order_line_item', 10, 4 );
// Отключить уведомление о предварительном заказе по умолчанию в корзине
function inline_css() {
    echo "<style>.backorder_notification{display: none;}</style>";
}
add_action( 'wp_head', 'inline_css', 0 );
// Отключить редактирование количества в корзине
add_filter( 'woocommerce_cart_item_quantity', 'wc_cart_item_quantity', 10, 3 );
function wc_cart_item_quantity( $product_quantity, $cart_item_key, $cart_item ){
    if( is_cart() ){
        $product_quantity = sprintf( '%2$s <input type="hidden" name="cart[%1$s][qty]" value="%2$s" />', $cart_item_key, $cart_item['quantity'] );
    }
    return $product_quantity;
}
// Создать новый статус заказа "Частичный заказ"
add_filter( 'woocommerce_register_shop_order_post_statuses', 'bbloomer_register_custom_order_status' );
function bbloomer_register_custom_order_status( $order_statuses ){
    $order_statuses['wc-partial-order'] = array(
        'label'                     => _x( 'Частичный заказ', 'Статус заказа', 'woocommerce' ),
        'public'                    => false,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'Частичный заказ <span class="count">(%s)</span>', 'Частичный заказ <span class="count">(%s)</span>', 'woocommerce' ),
    );
    return $order_statuses;
}
add_filter( 'wc_order_statuses', 'bbloomer_show_custom_order_status' );
function bbloomer_show_custom_order_status( $order_statuses ) {
    $order_statuses['wc-partial-order'] = _x( 'Частичный заказ', 'Статус заказа', 'woocommerce' );
    return $order_statuses;
}
add_filter( 'bulk_actions-edit-shop_order', 'bbloomer_get_custom_order_status_bulk' );
function bbloomer_get_custom_order_status_bulk( $bulk_actions ) {
    $bulk_actions['mark_partial-order'] = 'Изменить статус на частичный заказ';
    return $bulk_actions;
}
// Обновить смешанный заказ на Частичный заказ
add_filter( 'woocommerce_thankyou_order_received_text', 'misha_thank_you_title', 20, 2 );
function misha_thank_you_title( $thank_you_title, $order ){
    $items = $order->get_items();
    $backorders = 0;
    $order_count = 0;
    foreach ( $items as $item_id => $item ) {
        if (wc_get_order_item_meta( $item_id, 'Тип', true) == 'backorder') {
            $backorders++;
        }
        $order_count++;
    }
    if ($backorders > 0) {
        if ($order_count == $backorders) {
            $order->update_status('backordered', 'order_note');
        } else {
            $order->update_status('partial-order', 'order_note');
        }
    }
}
?>

.

Ответ или решение

Разделение элементов корзины на доступные и бэкоордерные товары в WooCommerce

В условиях современного онлайн-торговли нехватка товара на складе встречается довольно часто. Это порождает необходимость в деликатном управлении заказами, особенно когда клиент добавляет в корзину больше товаров, чем есть в наличии. Данная статья посвящена тому, как грамотно разделить одну строку заказа на два элемента — один с доступными товарами, другой — с бэкоордерами. Мы рассмотрим необходимый вами функционал на примере WooCommerce, популярного плагина для WordPress.

Проблема

Представим ситуацию, когда в наличии имеется 2 единицы товара, а клиент решает добавить в корзину 5 единиц данного товара. В стандартной конфигурации WooCommerce система добавит в корзину только одну строку с количеством 5, помечая все как товары на бэкоордере. Однако, это не совсем удобно для пользователей, и в итоге возникает вопрос: возможно ли разбить этот элемент корзины на две строки — с количеством, доступным для немедленной отгрузки, и с количеством, на которое придется подождать?

Решение

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

Код плагина

Приведём пример кода, который выполняет данную задачу:


<?php
/*
Plugin Name: WC Split Cart Backorders 
Plugin URI: https://www.creativemonarchy.com
Description: A simple plugin that helps you split the WooCommerce in stock and backorder stock items for the same product in your cart.
Author: Sohrab Iravani
Version: 1.0
Author URI: https://www.creativemonarchy.com
Requires at least: 4.9
Tested up to: 5.2.3
Text Domain: wc_split_cart_backorder
Domain Path: /languages/
*/

// Основная функция для разделения бэкоордеров
add_action('woocommerce_add_to_cart', 'split_bkorders', 10, 6);
function split_bkorders($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
    foreach (WC()->cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        $stock_qty = $product->get_stock_quantity();
        $item_qty = $cart_item['quantity'];

        // Проверка на превышение доступного количества
        if ($quantity > $stock_qty && $stock_qty > 0) {
            WC()->cart->set_quantity($cart_item_key, $stock_qty);
            $backorder = $item_qty - $stock_qty;
            $cart_item_data['unique_key'] = md5(microtime() . rand() . "xxx");
            $cart_item_data['pr_field'] = 'backorder';
            WC()->cart->add_to_cart($product_id

Оцените материал
Добавить комментарий

Капча загружается...