Добавить настраиваемые поля выбранных значений вариации в объект корзины Woocommerce

В WooCommerce я использую переменные продукты, вариации которых зависят от наличия даты.

В бэкэнде я успешно добавил 2 пользовательских поля с пользовательскими ценами (для взрослых / детей) на каждую вариацию настроек различных продуктов. (2 пользовательских поля отображаются внизу):

Снимок экрана: Варианты Back-end: 2 пользовательских поля внизу

Необходимо, чтобы две цены отображались в одном и том же варианте, поскольку они связаны с одним и тем же атрибутом даты и количеством.

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

На самом деле я хотел бы также добавить в корзину еще один товар, соответствующий той же вариации, но с ценами и количеством детей, и атрибутом типа «Цена: дети».

Я думаю об использовании функции add_to_cart, например:

add_to_cart( $product_id , $quantity , $variation_id, $variation , array(__('Price:','ah')=>__('Children','ah)) );

С соответствующими $product_id, $variation_id а также $variation, с $quantity = количество входных дочерних элементов, но я не знаю, где и когда нужно подключить это правильно.

Что я пробовал (и не работает):

  • Я попытался подключиться к самому add_to_cart, но только удалось создать рекурсивный вызов, который заканчивается ошибкой.
  • Я также пытался подключиться к woocommerce_before_calculate_totals, но кажется, что это правильное место для изменения цены, но слишком поздно добавлять новый продукт и устанавливать для него количество.

Отображение количества и цен для взрослых и детей
Страница продукта изменена, чтобы показать 2 цены с каждым селектором количества, а также сценарий jQuery, который рассчитывает общее количество динамически:

Просмотр внешнего интерфейса с селектором цены и количества и автоматическим подсчетом итогов
Просмотр внешнего интерфейса с селектором цены и количества и автоматическим подсчетом итогов

Вот мой код:

function ah_activity_product_price_display() {
global $product;
$stock = $product->get_total_stock();
$pricepolicy = get_post_meta( $product->id, '_ah_pricing', true );
if( is_activity()) {
$price_list = array();
if ($pricepolicy == 'multiple') {
$variations=$product->get_available_variations();
foreach ($variations as $variation) {
$variation_id = $variation['variation_id'] ;
$start = $variation['attributes']['attribute_date'];
$price_list[$start]['adult_price'] = get_post_meta( $variation_id, '_adult_price', true );
$price_list[$start]['children_price'] = get_post_meta( $variation_id, '_children_price', true );
}
//var_dump($price_list,json_encode($price_list));
?>
<div class="multiple">
<p class="clear">
<div class="quantity">
<input class="minus" type="button" value="-">
<input type="number" step="1" min="1" max="<?php echo esc_attr( 0 < $stock ? $stock : '' ); ?>" name="nb_adulte" value="1" title="<?php echo esc_attr_x( 'Adult number', 'Product quantity input tooltip', 'ah' ); ?>" class="input-text qty text" size="4" pattern="" inputmode="" />
<input class="plus" type="button" value="+">
</div> <?php _e('Adult x ','ah'); ?> <span class="prix-adulte"><?php esc_html($adult_price); ?></span> €
</p>
<p class="clear">
<div class="quantity">
<input class="minus" type="button" value="-">
<input type="number" step="1" min="0" max="<?php echo esc_attr( 0 < $stock ? $stock : '' ); ?>" name="nb_enfant" value="0" title="<?php echo esc_attr_x( 'Children number', 'Product quantity input tooltip', 'ah' ); ?>" class="input-text qty text" size="4" pattern="" inputmode="" />
<input class="plus" type="button" value="+">
</div> <?php _e('Children (under 18) x ','ah'); ?> <span class="prix-enfant"><?php echo esc_html($children_price); ?></span> €
</p>
</div>
<?php
}
echo '<input type="hidden" id="pricelist" name="pricelist" value=\''.json_encode($price_list).'\'>';

} else {
woocommerce_get_price_html();
}

}

1

Решение

Мне почти удалось добиться того, чего я хочу. Вот код, добавленный в PHP:

/**
* Définition et paramètres des scripts pour ajout au panier
*/
add_action( 'wp_enqueue_scripts', 'ah_load_script', 20 );
function ah_load_script(){
wp_enqueue_script( 'ah_ajax_add_to_cart', get_stylesheet_directory_uri() . '/js/test.js' );
$i18n = array( 'ajax_url' => admin_url( 'admin-ajax.php' ), 'checkout_url' => get_permalink( wc_get_page_id( 'checkout' ) ) );
wp_localize_script( 'ah_ajax_add_to_cart', 'ah_add_to_cart_params', $i18n );
}
/**
* Fonction d'ajout au panier Ajax
*/
add_action('wp_ajax_myajax', 'ah_add_to_cart_callback');
add_action('wp_ajax_nopriv_myajax', 'ah_add_to_cart_callback');

/**
* AJAX add to cart.
*/
function ah_add_to_cart_callback() {
ob_start();
//$product_id        = 264;
$product_id        = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
$quantity          = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] );
$variation_id      = isset( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : '';
$variations         = ! empty( $_POST['variation'] ) ? (array) $_POST['variation'] : '';

$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations, $cart_item_data );
$product_status    = get_post_status( $product_id );
if ( $passed_validation && WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) && 'publish' === $product_status ) {
do_action( 'woocommerce_ajax_added_to_cart', $product_id );
wc_add_to_cart_message( $product_id );
} else {
// If there was an error adding to the cart, redirect to the product page to show any errors
$data = array(
'error'       => true,
'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id )
);
wp_send_json( $data );
}
die();
}

И это соответствующий js (извините, если код некрасив, но я не настоящий js-кодер, просто самообучающийся …):

jQuery(document).ready(function($){

$(".test-button").click(function(e){
e.preventDefault();  // Prevent the click from going to the link
$variation_form = $( this ).closest( '.variations_form' );
var product_id = $variation_form.find( 'input[name=product_id]' ).val();
var adult_qty = $variation_form.find( 'input[name=nb_adulte]' ).val();
var children_qty = $variation_form.find( 'input[name=nb_enfant]' ).val();
var adult_price = $variation_form.find( '.prix-adulte' ).text();
var children_price = $variation_form.find( '.prix-enfant' ).text();

var var_id = $variation_form.find( 'input[name=variation_id]' ).val();
var att_date = $variation_form.find( 'select[name=attribute_date]' ).val();
var att_adult = "adulte";
var att_children = "enfant";

$.ajax({
url: ah_add_to_cart_params.ajax_url,
method: 'post',
data: {
'action': 'myajax',
'product_id': product_id,
'quantity': adult_qty,
'price' : adult_price,
'variation_id': var_id,
'variation': { 'attribute_date': att_date, 'attribute_tarif': att_adult }
}
}).done( function (response) {
if( response.error != 'undefined' && response.error ){
//some kind of error processing or just redirect to link
// might be a good idea to link to the single product page in case JS is disabled
return true;
} else {
$.ajax({
url: ah_add_to_cart_params.ajax_url,
method: 'post',
data: {
'action': 'myajax',
'product_id': product_id,
'quantity': children_qty,
'price' : children_price,
'variation_id': var_id,
'variation': { 'attribute_date': att_date, 'attribute_tarif': att_children }
}
}).done( function (response) {
if( response.error != 'undefined' && response.error ){
//some kind of error processing or just redirect to link
// might be a good idea to link to the single product page in case JS is disabled
return true;
} else {
window.location.href = ah_add_to_cart_params.checkout_url;
}
});
}
});
});
});

Это добавляет 2 продукта с атрибутом «priceing» => «adult» или «children» и соответствующее количество, но цена является ценой варианта по умолчанию (не моей пользовательской ценой), потому что я не знаю, как включить его в WC()->cart->add_to_cart вызов (Посмотрите, как выглядит моя корзина с кодом выше для 5 взрослых, 2 детей).

2

Другие решения

Ладно, все готово!
В дополнение к моему предыдущему ответу, вот фрагмент кода, который я добавил, чтобы установить цену соответствующей вариации с ценой для взрослых / детей соответственно, на случай, если она может помочь кому-то еще:

/**
* Override price in cart in case of adult/children prices
*/
function ah_add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custom price
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
//var_dump($cart_item);
$my_item = $cart_item['variation'];
$adult_price = get_post_meta($cart_item['variation_id'], "_adult_price" , true );
$children_price = get_post_meta($cart_item['variation_id'], "_children_price" , true );
if ( array_key_exists('attribute_tarif', $my_item) ) {
if (( $my_item['attribute_tarif'] == "adulte" ) && ( isset($adult_price) ) ) {
$cart_item['data']->set_price($adult_price);
} elseif (( $my_item['attribute_tarif'] == "enfant" ) && ( isset($children_price) ) ) {
$cart_item['data']->set_price($children_price);
}
}

}
}
add_action( 'woocommerce_before_calculate_totals', 'ah_add_custom_price' );

И вот результат:
Страница товара с ценами для взрослых и детей

Корзина с индивидуальным атрибутом и индивидуальной ценой

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector