Расчет цены товара в корзине на основе различных базовых цен в Woocommerce - PullRequest
0 голосов
/ 27 августа 2018

В Woocommerce я использую настраиваемые поля для расчета цены товара, основываясь на этом коде - Расчет цены товара в корзине на основе выбранного поля «дни» в Woocommerce . Большое спасибо за помощь LoicTheAztec.

// HERE your rental days settings
function get_rental_days_options() {
    return array(
            '2' => __("2 Days", "woocommerce"),
            '4' => __("4 Days", "woocommerce"),
    );
}

// Add a custom field before single add to cart
add_action('woocommerce_before_add_to_cart_button', 'display_single_product_custom_fields', 5);

function display_single_product_custom_fields() {
    // Get the rental days data options
    $options = array('' => __("Choosen period", "woocommerce")) + get_rental_days_options();

    echo '<div class="custom-text text"> < h3 > '.__("Rental", "woocommerce").
    ' < /h3> < label > '.__("Start Date", "woocommerce").
    ': < /label> < input type = "date"
    name = "rental_date"
    value = ""
    class = "rental_date" / >
            < label > Period: < /label> < select class = "rental-days"
    id = "rental-days"
    name = "rental_days" > ';

    foreach($options as $key => $option) {
            echo '<option value="'.$key.
            '">'.$option.
            '</option>';
    }

    echo '</select> < /div>';
}

// Get custom field value, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 3);

function add_custom_field_data($cart_item_data, $product_id, $variation_id) {
    // HERE set the percentage rate to be applied to get the new price
    $percentage = 2;

    if (isset($_POST['rental_date']) && !empty($_POST['rental_date'])) {
            $cart_item_data['custom_data']['start_date'] = $_POST['rental_date'];
    }

    if (isset($_POST['rental_days']) && !empty($_POST['rental_days'])) {
            $cart_item_data['custom_data']['rental_days'] = esc_attr($_POST['rental_days']);

            $_product_id = $variation_id > 0 ? $variation_id : $product_id;

            $product = wc_get_product($_product_id); // The WC_Product Object
            $base_price = (float) $product - > get_regular_price(); // Get the product regular price

            $price_rate = $cart_item_data['custom_data']['rental_days'] * $percentage / 100;

            $cart_item_data['custom_data']['base_price'] = $base_price;
            $cart_item_data['custom_data']['new_price'] = $base_price * $price_rate;
    }

    // Make each cart item unique
    if (isset($cart_item_data['custom_data']['rental_days']) || isset($cart_item_data['custom_data']['start_date'])) {
            $cart_item_data['custom_data']['unique_key'] = md5(microtime().rand());
    }

    return $cart_item_data;
}

// Set the new calculated cart item price
add_action('woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1);

function extra_price_add_custom_price($cart) {
    if (is_admin() && !defined('DOING_AJAX'))
            return;

    foreach($cart - > get_cart() as $cart_item) {
            if (isset($cart_item['custom_data']['new_price']))
                    $cart_item['data'] - > set_price((float) $cart_item['custom_data']['new_price']);
    }
}

// Display cart item custom price details
add_filter('woocommerce_cart_item_price', 'display_cart_items_custom_price_details', 20, 3);

function display_cart_items_custom_price_details($product_price, $cart_item, $cart_item_key) {
    if (isset($cart_item['custom_data']['base_price'])) {
            $product = $cart_item['data'];
            $base_price = $cart_item['custom_data']['base_price'];
            $product_price = wc_price(wc_get_price_to_display($product, array('price' => $base_price))).
            '<br>';

            if (isset($cart_item['custom_data']['rental_days'])) {
                    $rental_days = get_rental_days_options();
                    $product_price. = $rental_days[$cart_item['custom_data']['rental_days']];
            }
    }
    return $product_price;
}

// Display in cart item the selected date
add_filter('woocommerce_get_item_data', 'display_custom_item_data', 10, 2);

function display_custom_item_data($cart_item_data, $cart_item) {
    if (isset($cart_item['custom_data']['start_date'])) {
            $cart_item_data[] = array(
                    'name' => __("Rental start date", "woocommerce"),
                    'value' => date('d.m.Y', strtotime($cart_item['custom_data']['start_date'])),
            );
    }

    if (isset($cart_item['custom_data']['rental_days'])) {
            $rental_days = get_rental_days_options();
            $cart_item_data[] = array(
                    'name' => __("Rental period", "woocommerce"),
                    'value' => $rental_days[$cart_item['custom_data']['rental_days']],
            );
    }

    return $cart_item_data;
}

// Save and display custom field in orders and email notifications (everywhere)
add_action('woocommerce_checkout_create_order_line_item', 'custom_fields_update_order_item_meta', 20, 4);

function custom_fields_update_order_item_meta($item, $cart_item_key, $values, $order) {
    if (isset($values['custom_data']['date'])) {
            $date = date('d.m.Y', strtotime($values['custom_data']['date']));
            $item - > update_meta_data(__('Start date', 'woocommerce'), $date);
    }
    if (isset($values['custom_data']['rental_days'])) {
            $rental_days = get_rental_days_options();
            $item - > update_meta_data(__('Rental period', 'woocommerce'), $rental_days[$values['custom_data']['rental_days']]);
    }
}

Я не ожидал нового условия для расчета цены пользователя ((Это последнее.

Если пользователь покупает продукт с базовой ценой, превышающей 6660, то стандартный расчет следует из кода, показанного выше.

Если пользователь покупает продукт, базовая цена которого составляет менее 6 660, то новая цена составляет 999 в день. Далее пользователь выбирает срок аренды. Если он выбирает 2 дня, то 999 * 2. Если он выбирает 4 дня, то 999 * 4.

Насколько я понимаю, мне нужно добавить условия, если base_price> 6600 (здесь и далее идет стандартный код расчета) и если base_price <6600 (тогда рассчитывать, основываясь на выборе пользователя 999 * 2 или 999 * 4). </p>

Мне нужно сделать вывод о цене ['new_price'] рядом с базовой ценой на отдельной странице продукта.

Но я не совсем понимаю, как правильно это реализовать.

Я буду очень рад вашей помощи!


ОБНОВЛЕНИЕ: Я поставил чистую версию Wordpress без плагинов. Активирована тема Витрины. Добавлены демонстрационные данные.

В файл functions.php добавили код вместе с вашими правками:

// HERE your rental days settings
function get_rental_days_options() {
return array(
        '2' => __("2 Days", "woocommerce"),
        '4' => __("4 Days", "woocommerce"),
);
}

// Add a custom field before single add to cart
add_action('woocommerce_before_add_to_cart_button', 'display_single_product_custom_fields', 5);

function display_single_product_custom_fields() {
// Get the rental days data options
$options = array('' => __("Choosen period", "woocommerce")) + get_rental_days_options();

echo '<div class="custom-text text">
<h3>'.__("Rental", "woocommerce").'</h3>
<label>'.__("Start Date", "woocommerce").': </label>
<input type="date" name="rental_date" value="" class="rental_date" />
<label>Period: </label>
<select class="rental-days" id="rental-days" name="rental_days">';

foreach($options as $key => $option) {
        echo '<option value="'.$key.'">'.$option.'</option>';
}
echo '</select></div>';
}

// Get custom field value, calculate new item price, save it as custom cart item data
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 3);

function add_custom_field_data($cart_item_data, $product_id, $variation_id) {
// HERE set the percentage rate to be applied to get the new price
$percentage = 2;

if (isset($_POST['rental_date']) && !empty($_POST['rental_date'])) {
        $cart_item_data['custom_data']['start_date'] = $_POST['rental_date'];
}

if (isset($_POST['rental_days']) && !empty($_POST['rental_days'])) {
        $cart_item_data['custom_data']['rental_days'] = esc_attr($_POST['rental_days']);

        $_product_id = $variation_id > 0 ? $variation_id : $product_id;

        $product = wc_get_product($_product_id); // The WC_Product Object
        $base_price = (float) $product->get_regular_price(); // Get the product regular price
        $rental_days = $cart_item_data['custom_data']['rental_days'];

        // Below is the old/original code for your reference.
        /*$price_rate = $cart_item_data['custom_data']['rental_days'] * $percentage / 100;

        $cart_item_data['custom_data']['base_price'] = $base_price;
        $cart_item_data['custom_data']['new_price'] = $base_price * $price_rate;*/
        // Above is the old/original code for your reference. The new code is what follows (below):

        // Set base price.
        $cart_item_data['custom_data']['base_price'] = $base_price;

        // Set new price.
        if ( $base_price > 6660 ) {
            $price_rate = $rental_days * $percentage / 100;
            $cart_item_data['custom_data']['new_price'] = $base_price * $price_rate;
        } else {
            $cart_item_data['custom_data']['new_price'] = 999 * $rental_days;
        }
}

// Make each cart item unique
if (isset($cart_item_data['custom_data']['rental_days']) || isset($cart_item_data['custom_data']['start_date'])) {
        $cart_item_data['custom_data']['unique_key'] = md5(microtime().rand());
}

return $cart_item_data;
}

// Set the new calculated cart item price
add_action('woocommerce_before_calculate_totals', 'extra_price_add_custom_price', 20, 1);

function extra_price_add_custom_price($cart) {
if (is_admin() && !defined('DOING_AJAX'))
        return;

foreach($cart->get_cart() as $cart_item) {
        if (isset($cart_item['custom_data']['new_price']))
                $cart_item['data']->set_price((float) $cart_item['custom_data']['new_price']);
}
}

// Display cart item custom price details
add_filter('woocommerce_cart_item_price', 'display_cart_items_custom_price_details', 20, 3);

function display_cart_items_custom_price_details($product_price, $cart_item, $cart_item_key) {
if (isset($cart_item['custom_data']['base_price'])) {
        $product = $cart_item['data'];
        $base_price = $cart_item['custom_data']['base_price'];
        $product_price = wc_price(wc_get_price_to_display($product, array('price' => $base_price))).
        '<br>';

        if (isset($cart_item['custom_data']['rental_days'])) {
                $rental_days = get_rental_days_options();
                $product_price .= $rental_days[$cart_item['custom_data']['rental_days']];
        }
}
return $product_price;
}

// Display in cart item the selected date
add_filter('woocommerce_get_item_data', 'display_custom_item_data', 10, 2);

function display_custom_item_data($cart_item_data, $cart_item) {
if (isset($cart_item['custom_data']['start_date'])) {
        $cart_item_data[] = array(
                'name' => __("Rental start date", "woocommerce"),
                'value' => date('d.m.Y', strtotime($cart_item['custom_data']['start_date'])),
        );
}

if (isset($cart_item['custom_data']['rental_days'])) {
        $rental_days = get_rental_days_options();
        $cart_item_data[] = array(
                'name' => __("Rental period", "woocommerce"),
                'value' => $rental_days[$cart_item['custom_data']['rental_days']],
        );
}

return $cart_item_data;
}

// Save and display custom field in orders and email notifications (everywhere)
add_action('woocommerce_checkout_create_order_line_item', 'custom_fields_update_order_item_meta', 20, 4);

function custom_fields_update_order_item_meta($item, $cart_item_key, $values, $order) {
if (isset($values['custom_data']['date'])) {
        $date = date('d.m.Y', strtotime($values['custom_data']['date']));
        $item->update_meta_data(__('Start date', 'woocommerce'), $date);
}
if (isset($values['custom_data']['rental_days'])) {
        $rental_days = get_rental_days_options();
        $item->update_meta_data(__('Rental period', 'woocommerce'), $rental_days[$values['custom_data']['rental_days']]);
}
}

Вот скриншоты:

enter image description here

enter image description here

enter image description here

Небольшая проблема с расчетом цены.

Если базовая цена> 6660, она не считается и не отображается в корзине. Если базовая цена <6660, то все работает правильно. </p>

Мне нужно, чтобы оба условия были рассчитаны и отображены в корзине.

Если покупатель покупает оба товара, а один из них не работает по цене, это плохо ((


ОБНОВЛЕНИЕ 2: Я обновил код. Вот скриншот корзины:

enter image description here

Вместо 680 долларов - 5100 долларов.

Вместо 1360 долларов, должно быть 10200 долларов.

17000/100 * 15 = 2550

2550 * 2 = 5100

2550 * 4 = 10200

А как показать новую цену на одной странице товара, рядом с базовой ценой?

1 Ответ

0 голосов
/ 30 августа 2018

(обновленный / новый ответ)

ШАГ 1: Над этим кодом:

// HERE your rental days settings
function get_rental_days_options() {
... code removed, but nothing changed here.
}

Добавьте этот код, который вычисляет новую цену & mdash; и на основании нового расчета:

// Calculate new price based on rental period/days.
function calc_rental_new_price( $rental_days, $base_price ) {
    $percentage = 15;

    if ( $base_price > 6660 ) {
        $price_rate = $rental_days * $percentage / 100;
        return $base_price * $price_rate;
    } else {
        return 999 * $rental_days;
    }
}

ШАГ 2: Используйте этот новый add_custom_field_data() код & mdash; для ясности он переотрезан:

function add_custom_field_data($cart_item_data, $product_id, $variation_id) {
    if (isset($_POST['rental_date']) && !empty($_POST['rental_date'])) {
        $cart_item_data['custom_data']['start_date'] = $_POST['rental_date'];
    }

    if (isset($_POST['rental_days']) && !empty($_POST['rental_days'])) {
        $cart_item_data['custom_data']['rental_days'] = esc_attr($_POST['rental_days']);

        $_product_id = $variation_id > 0 ? $variation_id : $product_id;

        $product = wc_get_product($_product_id); // The WC_Product Object
        $base_price = (float) $product->get_regular_price();

        // Set base price.
        $cart_item_data['custom_data']['base_price'] = $base_price;

        // Set new price.
        $cart_item_data['custom_data']['new_price'] = calc_rental_new_price(
            $cart_item_data['custom_data']['rental_days'], $base_price
        );
    }

    // Make each cart item unique
    if (isset($cart_item_data['custom_data']['rental_days']) || isset($cart_item_data['custom_data']['start_date'])) {
        $cart_item_data['custom_data']['unique_key'] = md5(microtime().rand());
    }

    return $cart_item_data;
}

ШАГ 3: После этого кода:

function custom_fields_update_order_item_meta($item, $cart_item_key, $values, $order) {
... code removed, but nothing changed here.
}

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

// Adds the new price next to the base price. That new price is for 1 day rental period.
add_filter( 'woocommerce_get_price_html', 'add_new_price_html', 10, 2 );

function add_new_price_html( $html, $product ) {
    // Check if we're on a single Product page, the shop page, or a products archive page.
    if ( ! is_product() && ! is_shop() && ! is_product_taxonomy() ) {
        return $html;
    }

    $base_price = (float) ( 'variable' === $product->get_type() ?
        $product->get_variation_regular_price() : $product->get_regular_price() );
    $new_price = calc_rental_new_price( 1, $base_price );

    // If it's a Variable product, appends "From " to the new price.
    $text_from = ( 'variable' === $product->get_type() ) ? 'From ' : '';

    return $html . ' <span class="new-price">' . $text_from . wc_price( $new_price ) . ' / day</span>';
}

ОБНОВЛЕНО 04 сентября 2018

  • Исправлено $base_price.

  • Новая цена теперь также отображается на страницах архива магазина и продуктов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...