Данный функционал подойдет для магазина тканей. Суть в том что можно отмерить определенную длину товара (ткани) и указать количества таких кусков. При этом ширина у каждого товара является фиксированной, либо можно сделать выбор ширины в виде вариаций.
Произвольное поле Длина, влияющее на цену
Данное решение конфликтует с плагином Free Product Sample for WooCommerce.
// Произвольное поле влияющее на цену
add_action( 'woocommerce_before_add_to_cart_button', 'custom_product_price_field', 5 );
function custom_product_price_field(){
echo '<div class="choice-length">
<p>Рекомендуемый размер</p>
<ul class="recommended">
<li leight="1.8">1.8 м</li>
<li leight="2.8">2.8 м</li>
<li leight="10">10 м</li>
</ul>
<p>Индивидуальный размер</p>
<div id="slider-cont"><div id="slider"></div></div>
<div class="custom-product-field">
<p>Длина ткани (пог. м):</p>
<input type="number" name="custom_price" value="0.2" min="1" max="10" step="0.2" placeholder="Длина" class="product-leight">
</div>
</div>';
//get_woocommerce_currency_symbol(); текущая валюта
}
function line_price_start(){ echo '<div class="line-price">'; }
add_action( 'woocommerce_before_add_to_cart_button', 'line_price_start', 6 );
function line_price_end(){ echo '</div>'; }
add_action( 'woocommerce_after_add_to_cart_button', 'line_price_end', 15 );
// Получить значение настраиваемого поля, рассчитать цену нового товара, сохранить его как данные настраиваемого товара в корзине
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data', 20, 2 );
function add_custom_field_data( $cart_item_data, $product_id ){
if (! isset($_POST['custom_price']))
return $cart_item_data;
$custom_price = (float) sanitize_text_field( $_POST['custom_price'] );
if( empty($custom_price) )
return $cart_item_data;
$product = wc_get_product($product_id); // The WC_Product Object
$base_price = (float) $product->get_price(); // Product price
// New price calculation
$new_price = $base_price * $custom_price;
// Set the custom amount in cart object
$cart_item_data['custom_data']['extra_charge'] = (float) $custom_price;
$cart_item_data['custom_data']['new_price'] = (float) $new_price;
$cart_item_data['custom_data']['unique_key'] = md5( microtime() . rand() ); // Make each item unique
return $cart_item_data;
}
// Установить новую рассчитанную цену товара в корзине (Итого)
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;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
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'] );
}
}
// Отображение сведений о пользовательской цене товара в корзине (Цена в каждой позиции)
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']['extra_charge']) ) {
$product = $cart_item['data'];
$product_price = wc_price( wc_get_price_to_display( $product, array( 'price' => $product->get_price() ) ) );
//$product_price .= '<br>' . wc_price( $cart_item['custom_data']['extra_charge'] ).' ';
//$product_price .= __("Extra Charge", "woocommerce" );
}
return $product_price;
}
// Changing the cart item name
add_action( 'woocommerce_before_calculate_totals', 'customizing_cart_items_name', 20, 1 );
function customizing_cart_items_name( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through each cart items
foreach ( $cart->get_cart() as $cart_item ) {
$product = $cart_item['data'];
// Continue if we get the custom 'sample_name' for the current cart item
if( !empty( $cart_item['custom_data']['extra_charge'] ) ){
// Get an instance of the WC_Product Object
$product = $cart_item['data'];
// Get the product name (Added compatibility with Woocommerce 3+)
$product_name = method_exists( $product, 'get_name' ) ? $product->get_name() : $product->post->post_title;
// The new string composite name
$product_name .= ' (' . $cart_item['custom_data']['extra_charge'] . ' пог. м)';
// Set the new composite name (WooCommerce versions 2.5.x to 3+)
if( method_exists( $product, 'set_name' ) )
$product->set_name( $product_name );
else
$product->post->post_title = $product_name;
}
}
}
Визуализация изменения длины
Добавим к полю выбор популярных длин, а также бегунок для выбора длины.
Для этого нужно подключить jquery-ui (css и js) slider.
И инициировать скрипт:
$(document).ready(function() {
$("#slider").slider({
min: 1,
max: 10,
value: 1,
step: 0.2,
create: setInputsFrom2Slider,
slide: setInputsFrom2Slider,
stop: setInputsFrom2Slider
});
function setInputsFrom2Slider() {
$(".product-leight").val($("#slider").slider("value"));
}
$("input.product-leight").change(function(e) {
$("#slider").slider("value", $(this).val());
});
$(".recommended li").click(function(e) {
var leight = $(this).attr("leight");
$(".product-leight").val(leight);
$("#slider").slider("value", leight);
});
});
Количество резов
Можно усложнить и посчитать количество резов ткани по формуле:
- Если длина куска кратна длине всего рулона, то делим длину рулона на длину куска и вычитаем 1.
- Если длина куска не кратна длине всего рулона, то просто делим длину рулона на длину куска.
Для добавления к стоимости нужно добавить еще одно скрытое поле.
[site-socialshare]