Получите динамическую расчетную плату на основе ввода почтового индекса в Woocommerce

Я пытаюсь передать переменную в woocommerce_cart_calculate_fees хук, но этот код не работает. Когда я пытаюсь передать статическое значение в переменной, это работает.

Вот мой код:

add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees', 20, 1);
function add_custom_fees( WC_Cart $cart){

$final_discount; // storing ajax value
$static_value = 5; // static value

if ($final_discount) {
/**
* custom discount for the cart in woocommerce
*/
// Hook before calculate fees
add_action('woocommerce_cart_calculate_fees', 'add_custom_fees');

/**
* Add custom fee if more than three article
* @param WC_Cart $cart
*/
function add_custom_fees(WC_Cart $cart) {
// Calculate the amount to reduce
global $final_discount;
$discount = $cart->subtotal * $final_discount / 100;
$cart->add_fee('10% discount has been added.', -$discount);
}
}
}

РЕДАКТИРОВАТЬ:

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

Переменная сеанса хранит из onchange ajax значение billing_postcode поле страницы проверки woocommerce.

Мой код JQuery (Ajax):

jQuery(document).ready(function () {
jQuery('#billing_postcode').on('change', function (event) {
//alert( this.value );
event.preventDefault();
var billing_postcode = jQuery('#billing_postcode').val();

console.log(billing_postcode);
var data = {
action: 'woocommerce_apply_state',
security: wc_checkout_params.apply_state_nonce,
billing_postcode: billing_postcode
};

jQuery.ajax({
type: "POST",
data: data,
url: wc_checkout_params.ajax_url,
success: function (code) {
console.log(code);
if (code === '0') {
jQuery('body').trigger('update_checkout');
}
},
dataType: 'html'
});
});
});

Мой PHP-код в файле functions.php моей темы:

wp_enqueue_script('zip_code', get_template_directory_uri() . '/assets/js/zipcode.js', array('jquery'));
wp_localize_script('zip_code', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));

add_action('wp_ajax_woocommerce_apply_state', 'discount', 10);
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'discount', 10);

function discount() {
if(isset($_POST['billing_postcode'])){
$billing_postcode = isset($_POST['billing_postcode'])?$_POST['billing_postcode']:'not yet';
global $wpdb;
$zipcodes = $wpdb->get_results(
$wpdb->prepare( "SELECT * FROM wp_zip_codes_value
WHERE zip_code_value = %d",
$billing_postcode
)
);

$zip_for_discount = array();
foreach ( $zipcodes as $zipcode ){
$zip_for_discount = $zipcode->zip_code_id;
}

$find_discount = $wpdb->get_results(
$wpdb->prepare( "SELECT * FROM wp_zip_codes
WHERE zip_code = %d",
$zip_for_discount
)
);

$final_discount = array();
if($find_discount){
foreach ( $find_discount as $discount ){
$final_discount[] = $discount->discount;
}
}
$final_discount[0];
WC()->session->set( 'final_discount', $final_discount[0] );
}
}

add_action('woocommerce_cart_calculate_fees' , 'add_custom_fees', 20, 1);

function add_custom_fees( WC_Cart $cart){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$percent = WC()->session->get( 'final_discount' );
if( $percent > 0 ){
$discount = $cart->subtotal * $percent / 100;
$cart->add_fee( __('Zip Code Discount', 'woocommerce' ) . " ($percent%)", -$discount);
}
}

1

Решение

Лучший способ добиться этого — установить $final_discount переменная с помощью WC_Sessions в другой функции раньше, таким образом:

WC()->session->set( 'final_discount', $final_discount );

Теперь вы можете получить это значение в любом месте внешнего интерфейса или кода, используя:

$final_discount = WC()->session->get( 'final_discount' );

Таким образом, ваш окончательный код скидки (отрицательная плата) будет выглядеть примерно так:

add_action('woocommerce_cart_calculate_fees', 'add_custom_fee', 20, 1 );
function add_custom_fee( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

// Get the data from WC_Sessions
$percent = WC()->session->get( 'final_discount' );

if( $percent > 0 ){
$discount = $cart->subtotal * $percent / 100;
$cart->add_fee( __('Discount', 'woocommerce' ) . " ($percent%)" . $percent, -$discount);
}
}

Код помещается в файл function.php вашей активной дочерней темы (active theme).

Проверено и работает.


Обновление относительно вашего обновленного вопроса:

Вот за работой Пример кода Ajax похож на ваш но упрощенный (поскольку у меня нет аналогичных пользовательских таблиц базы данных, чтобы получить процент за скидку).

Переменный процент скидки основан на вмененном значении почтового индекса…

Код PHP:

add_action( 'wp_enqueue_scripts', 'wc_zipcode_enqueue_scripts' );
function wc_zipcode_enqueue_scripts() {

// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;

// (For child themes use get_stylesheet_directory_uri() instead)
wp_enqueue_script('zip_code', get_template_directory_uri() . '/assets/js/zipcode.js', array('jquery'));
wp_localize_script('zip_code', 'wc_checkout_params', array('ajaxurl' => admin_url('admin-ajax.php')));
}

add_action('wp_ajax_woocommerce_apply_state', 'woocommerce_apply_state', 10 );
add_action('wp_ajax_nopriv_woocommerce_apply_state', 'woocommerce_apply_state', 10 );
function woocommerce_apply_state() {
global $wpdb;

if( isset($_POST['billing_postcode']) ){
$billing_postcode = $_POST['billing_postcode'];

if( empty($billing_postcode) || $billing_postcode == 0 ) die();

if( $billing_postcode < 30000 )
$final_discount = 10;
elseif( $billing_postcode >= 30000 && $billing_postcode < 60000 )
$final_discount = 15;
else
$final_discount = 20;

WC()->session->set( 'final_discount', $final_discount );
echo json_encode( WC()->session->get('final_discount' ) );
}
die(); // Alway at the end (to avoid server error 500)
}

add_action('woocommerce_cart_calculate_fees' , 'add_custom_discount', 20, 1);
function add_custom_discount( WC_Cart $cart){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;

// Get the data from WC_Sessions
$percent = WC()->session->get( 'final_discount' );

// If the billing postcode is not set we exit
$billing_postcode = WC()->session->get('customer')['postcode'];
if( empty($billing_postcode) ) return;

if( $percent > 0 ){
$discount = $cart->subtotal * $percent / 100;
$cart->add_fee( __('Zip Code Discount', 'woocommerce' ) . " ($percent%)", -$discount);
}
}

Код помещается в файл function.php вашей активной дочерней темы (active theme).

Код JavaScript:

jQuery(document).ready(function($) {
function postcodeAjax(){
$.ajax({
type: 'POST',
dataType: 'json'
data:  {
action: 'woocommerce_apply_state',
billing_postcode: $('#billing_postcode').val(),
security: wc_checkout_params.apply_state_nonce
},
url: wc_checkout_params.ajax_url,
success: function (response) {
$('body').trigger('update_checkout');
console.log('response');
}
});
}

if( $('#billing_postcode').val() > 0 )
postcodeAjax();

$('#billing_postcode').on('change blur', function(e){
e.preventDefault();
postcodeAjax();
$('body').trigger('update_checkout');
});
});

Быть сохраненным в файле с именем zipcode.js находится в папке вашей темы /assets/js/zipcode.js

Проверено и отлично работает

1

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

Других решений пока нет …

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