woocommerce_cart_calculate_fees: Update Fee on custom input change - php

Image Issue Example
At the WooCommerce "checkout" page:
I would like to input any number in the "Custom Fee Input"
- then it will be calculated in the "Total price table".
- After placing order the "Custom Fee" will be auto synchronized into the database.
Recommendation: using Plain JavaScript instead of jQuery is highly appreciated.
This is my codes:
html
<label>
Custom Fee
<input id="custom_fee" name="custom_fee" type="number" required>
</label>
Plain JavaScript
var $custom_fee = document.getElementById("custom_fee");
$custom_fee.addEventListener("change", function(){
var data = {
action: 'custom_fee',
security: wc_checkout_params.apply_state_nonce,
custom_fee_cost: $custom_fee.value,
};
var request = new XMLHttpRequest();
request.open('POST', wc_checkout_params.ajax_url, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
var resp = this.response;
console.log(resp);
} else {
var resp = this.response;
console.log(resp);
}
};
request.send(data);
});
function.php
add_action('wp_ajax_custom_fee', 'custom_fee_ajax', 10);
add_action('wp_ajax_nopriv_custom_fee', 'custom_fee_ajax', 10);
function custom_fee_ajax() {
if( ! is_checkout() ) return;
global $wpdb;
if( isset($_POST['custom_fee']) ){
$custom_fee = $_POST['custom_fee'];
WC()->session->set( 'custom_fee', $custom_fee );
echo json_encode( WC()->session->get('custom_fee' ) );
}
die();
}
//________________________________________________________
add_action('woocommerce_cart_calculate_fees', 'custom_fee');
function custom_fee() {
if( ! is_checkout() ) return;
session_start();
global $woocommerce;
if ( !defined( 'DOING_AJAX' ) ) return;
$fee = $_SESSION['custom_fee'];
$woocommerce->cart->add_fee( 'Custom Fee' , $fee, true, '' );
}
NOTE: The above code does not work correctly (bad request 400; php functions); so I would like to have someone help I to solve this issue.

Related

Update totals after applying or removing a coupon programmatically In WooCommerce

I have created a checkbox (It does not look like a checkbox anymore) that apply/remove a coupong on change. This works good. But the total does not update on the apply, the page has to be refreshed. I have build this function with some cut and paste from other functions, it was once a radio field, and it might not be the best practise. The coupong ads a discount for 500 SEK.
But how to do I recalculate the total after the coupong is applied?
As you can see in the end, I have tried WC()->cart->calculate_totals();.
This is the site and checkout: https://www.klubbtryck.se/nif/kassa/
This is my code:
// Add a custom checkout field
add_action( 'woocommerce_review_order_after_shipping', 'checkout_shipping_form_delivery_addition_nifny', 20 );
function checkout_shipping_form_delivery_addition_nifny(){
$domain = 'wocommerce';
if ( WC()->session->get( 'chosen_shipping_methods' )[0] == 'local_pickup:3' ) :
echo '<tr class="delivery-radio"><th>' . __('Gift Card', $domain) . '</th><td>';
$chosen = WC()->session->get('chosen_delivery');
$chosen = empty($chosen) ? WC()->checkout->get_value('delivery') : $chosen;
$chosen = empty($chosen) ? 0 : $chosen;
if( $chosen == 1){ $chosen = true; } else { $chosen = false; }
// Add a custom checkbox field
woocommerce_form_field( 'radio_delivery', array(
'type' => 'checkbox',
'label' => '<label for="radio_delivery" class="checkbox-label"><span class="presentkortbesk">I have a gift card</span><span class="priset">-500kr</span></label>',
'class' => array( 'form-row-wide' ),
'required' => false,
//'default' => false,
), $chosen );
echo '</td></tr>';
endif;
}
// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_delivery_script_nifny' );
function checkout_delivery_script_nifny() {
// Only checkout page
if ( ! is_checkout() ) return;
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on('change', 'input[name=radio_delivery]', function(e){
e.preventDefault();
var d = $(this).prop('checked') === true ? 1 : 0;
//var d = $(this).val();
//alert('value: '+d);
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'delivery',
'delivery': d,
},
success: function (result) {
$('body').trigger('update_checkout');
//console.log(result); // just for testing | TO BE REMOVED
},
error: function(error){
//console.log(error); // just for testing | TO BE REMOVED
}
});
});
});
</script>
<?php
}
// Get Ajax request and saving to WC session
add_action( 'wp_ajax_delivery', 'wc_get_delivery_ajax_data_nifny' );
add_action( 'wp_ajax_nopriv_delivery', 'wc_get_delivery_ajax_data_nifny' );
function wc_get_delivery_ajax_data_nifny() {
if ( isset($_POST['delivery']) ){
WC()->session->set('chosen_delivery', sanitize_key( $_POST['delivery'] ) );
echo json_encode( $delivery ); // Return the value to jQuery
}
die();
}
// Add a custom dynamic delivery fee
add_action( 'woocommerce_cart_calculate_fees', 'add_packaging_fee_nifny', 20, 1 );
function add_packaging_fee_nifny( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Only for targeted shipping method
if ( WC()->session->get( 'chosen_shipping_methods' )[0] != 'local_pickup:3' )
return;
if( WC()->session->get( 'chosen_delivery' ) == 1 ){
if (!in_array('nynashamn2020', WC()->cart->get_applied_coupons())) {
WC()->cart->apply_coupon('card2020');
//WC()->cart->calculate_totals();
}
} else {
if (in_array('nynashamn2020', WC()->cart->get_applied_coupons())) {
WC()->cart->remove_coupon('card2020');
}
}
}
You should replace woocommerce_cart_calculate_fees hook that is only made for Fees with similar woocommerce_before_calculate_totals more appropriated hook as follows:
// Add a custom dynamic delivery fee
add_action( 'woocommerce_before_calculate_totals', 'add_packaging_fee_nifny' );
function add_packaging_fee_nifny( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Only for targeted shipping method
if ( WC()->session->get( 'chosen_shipping_methods' )[0] != 'local_pickup:3' )
return;
if( WC()->session->get( 'chosen_delivery' ) == 1 ){
if (!in_array('nynashamn2020', WC()->cart->get_applied_coupons())) {
WC()->cart->apply_coupon('card2020');
//WC()->cart->calculate_totals();
}
} else {
if (in_array('nynashamn2020', WC()->cart->get_applied_coupons())) {
WC()->cart->remove_coupon('card2020');
}
}
}
Code goes in functions.php file of the active child theme (or active theme). It should better works.

Checkout distance Calculation Using Google Map API in WooCommerce 3.3

I posted a similar problem a few months back and I have been helped out there to solve it. It was working fine until Woocommerce version 3.1.2. I have been updating to latest version of WooCommerce hoping the problem will be solved.
I am adding dynamic fees based on the difference between customer's billing_area (customized dropdown) on checkout and the value of seller's billing_city (set in user profile). The code I was using as below -
This is the jQuery Script that runs to get the value of billing_area as changed:
add_action( 'woocommerce_after_checkout_form', 'custom_checkout_jquery_script', 10 );
function custom_checkout_jquery_script() {
?>
<script type="text/javascript">
(function($){
$( 'form.checkout' ).on( 'change', '#billing_area', function(){
var location = $('#billing_area option:selected').val();
document.cookie="cusarea="+location;
// Browser console output (Just for testing)
function readCookie(n){ for(var r=n+"=",t=document.cookie.split(";"),e=0;e<t.length;e++){
for(var i=t[e];" "==i.charAt(0);)i=i.substring(1,i.length);
if(0==i.indexOf(r))return i.substring(r.length,i.length)}return null}
$('body').trigger('update_checkout');
console.log('Selected Area: '+location+' | Cookie: '+readCookie("cusarea"));
//$('#order_review').load(document.URL + ' #order_review');
//window.location.reload(true)
});
})(jQuery);
</script>
<?php
}
This is the code for calculating fees:
add_action( 'woocommerce_cart_calculate_fees', 'distance_shipping_fee', 30, 1 );
function distance_shipping_fee( $wc_cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if( empty($_COOKIE ['cusarea']) ) return;
else $cookie = $_COOKIE ['cusarea'];
// Encoding the customer's location for Google API
$customer_area = rawurlencode( $cookie );
// Getting billing city of vendors
foreach( $wc_cart->get_cart() as $cart_item ){
$vendor_id = get_post_field( 'post_author', $cart_item['product_id'] );
$vendors[$vendor_id] = get_user_meta($vendor_id, 'billing_city', true);
}
foreach( $vendors as $vend_loc){
// Setting Google API URL ##
$gapi_key = MY_APY; // Set HERE your google api key
$shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$vend_loc";
$shippingurl .= "+dhaka+bangladesh&destinations=$customer_area+dhaka+bangladesh&key=$gapi_key";
// Now fetching json response from googleapis:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $shippingurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
// If google responds with a status of OK: Extract the distance text:
if($response['status'] == "OK")
$dist = $response['rows'][0]['elements'][0]['distance']['text'];
$dist_array[] = preg_replace("/[^0-9\.]/", '', $dist);
}
// Get the bigger distance
$dist_ance = max($dist_array);
$dist_abs = abs ($dist_ance);
if ( $dist_abs < 5) {
$wc_cart->add_fee( "Delivery - Distance Rate", 10 , true);
} else {
$wc_cart->add_fee( "Delivery - Distance Rate", 20 , true);
}
}
Problem is - It's not working anymore.
If I dump the value, it returns me the value of $dist_abs (something like 5.4 which is the distance between seller's location and customer's area). But, no fee is added to the cart.
Sometimes, when server or site is slow, I see the label (Delivery - Distance Rate) appears in order review, but it disappears once page loads properly.
Can anyone tell me why it's not working anymore? Is there something I'm missing?
I have found the way to make it work using ajax instead of cookies… So try the following:
add_action( 'woocommerce_after_checkout_form', 'custom_checkout_jquery_script', 30 );
function custom_checkout_jquery_script() {
if( ! is_checkout() ) return;
?>
<script type="text/javascript">
jQuery(function($){
// wc_checkout_params is required to continue
if ( typeof wc_checkout_params === 'undefined' )
return false;
var a = '#billing_myfield5', b = a+' option:selected';
$( 'form.checkout' ).on( 'change', a, function(){
console.log('Chosen area: '+$(b).html()); // To be removed (testing)
// Ajax: send the chosen customer location to php
$.ajax({
type: 'POST',
url:.ajax_url,
data: {
'action': 'set_customer_area',
'customer_area': $(b).html(),
},
success: function (response) {
$(document.body).trigger('update_checkout');
console.log('Response: '+response); // To be removed (testing)
}
});
});
});
</script>
<?php
}
// Wordpress Ajax: Saved the selected customer location to WC_Session
add_action( 'wp_ajax_nopriv_set_customer_area', 'set_customer_area_in_wc_sessions' );
add_action( 'wp_ajax_set_customer_area', 'set_customer_area_in_wc_sessions' );
function set_customer_area_in_wc_sessions() {
if( ! isset($_POST['customer_area']) ) return;
// Encoding the customer's location for Google API
$customer_area_enc = rawurlencode( $_POST['customer_area'] );
// Set the chosen customer location in WC_Sessions
WC()->session->set('customer_area', rawurlencode($_POST['customer_area']) );
// To be removed (testing: Send back the data to jQuery)
echo json_encode( WC()->session->get('customer_area' ) );
die(); // To avoid server error 500
}
// Add a fee based on the highest distance between customer and vendors
add_action( 'woocommerce_cart_calculate_fees', 'distance_shipping_fee', 30, 1 );
function distance_shipping_fee( $cart ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Get Url encoded customer area that is saved in WC_Session by ajax
$customer_area = WC()->session->get('customer_area' );
// Only when customer area has been selected
if( empty($customer_area) )
return;
// Getting billing city of vendors
foreach( $cart->get_cart() as $cart_item ){
$vendor_id = get_post_field( 'post_author', $cart_item['product_id'] );
$vendors[$vendor_id] = get_user_meta($vendor_id, 'billing_city', true);
}
$dist_array = array();
// Loop through vendors locations
foreach( $vendors as $vend_loc){
// Setting Google API URL ##
$gapi_key = MY_APY; // Set HERE your google api key
$shippingurl = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=$vend_loc";
$shippingurl .= "+dhaka+bangladesh&destinations=$customer_area+dhaka+bangladesh&key=$gapi_key";
// Now fetching json response from googleapis:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $shippingurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($ch), true);
// If google responds with a status of OK: Extract the distance text:
if($response['status'] == "OK")
$dist = $response['rows'][0]['elements'][0]['distance']['text'];
$dist_array[] = preg_replace("/[^0-9\.]/", '', $dist);
}
// Get the bigger distance
$distance = max ($dist_array);
$distance = abs ($distance);
$fee = $distance < 5 ? 10 : 20;
if ( $distance && $fee > 0 )
$cart->add_fee( "Delivery - Distance Rate", $fee , true);
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Once working, you will have to remove all related lines with // Testing ==> To be removed

Get a dynamic calculated fee based on postcode input in Woocommerce

I trying to pass a variable in woocommerce_cart_calculate_fees hook, but this code doesn't work. When I try to pass static value within a variable it works.
Here is my code:
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);
}
}
}
EDIT:
Now I am to pass a WC_Session value in woocommerce_cart_calculate_fees hook, the code works but session variable does not update before page refreshing.
The session variable is storing from onchange ajax value of billing_postcode field of woocommerce checkout page.
My jQuery code (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'
});
});
});
My PHP code in functions.php file of my theme:
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);
}
}
The best way to get that working is to set your $final_discount variable using WC_Sessions in another function before, this way:
WC()->session->set( 'final_discount', $final_discount );
Now you can get this value anywhere on front end hooks or code using:
$final_discount = WC()->session->get( 'final_discount' );
So your final discount (negative fee) code will be something like:
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);
}
}
Code goes in function.php file of your active child theme (active theme).
Tested and works.
Update regarding your updated question:
Here is a working Ajax example code similar to yours but simplified (as I don't have similar database custom tables to get the percentage for the discount).
The variable discount percentage is based on the imputed zip-code value…
The PHP code:
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);
}
}
Code goes in function.php file of your active child theme (active theme).
The javascript code:
jQuery(document).ready(function($) {
function postcodeAjax(){
$.ajax({
type: 'POST',
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('updating checkout…');
}
});
}
if( $('#billing_postcode').val() > 0 )
postcodeAjax();
$('#billing_postcode').on('change blur', function(e){
e.preventDefault();
postcodeAjax();
$('body').trigger('update_checkout');
});
});
To be saved in a file named zipcode.js located in your theme folder /assets/js/zipcode.js
Tested and perfectly works

Update Total in checkout of Woocommerce with Ajax Request

Before asking question on SO, I searched a lot about what I needed to make a ajax request with WordPress. All my code and the request is working, but is not doing what I need it to do.
What I need to do is When I click at the buttom on checkout page "Novo Dependente", the information with the values to calculate total must update. "Total" value must be updated with a value which I defined at product post type page on admin panel. This value I already get, but the updating the value is real problem to me.
This is the page that I working.
This is the form, that shows up when i click the button, when i Toogle the checkbox I need to add the second value to the Total, another request with ajax.
And here my code goes
Obs: it's a plugin.
Here is the php code.
public function add_total_value()
{
if (! $_POST['action'] || $_POST['action'] !== 'add_total_value' ) :
echo json_encode(
array(
'status' => 'failed',
'message' => 'erro'
)
);
wp_die();
endif;
$woocommerce;
$quantidadeDependentes = $_POST['quantiaDependentes'];
//$produto_valor = WC()->cart->total;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item )
{
$product = $cart_item['data'];
$item_id = $cart_item['product_id'];
$endereco_igual = get_post_meta( $item_id, 'adicional_mesmo', true);
$endereco_igual = str_replace(',', '.', $endereco_igual);
$endereco_igual = floatval( filter_var( $endereco_igual, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION ) );
$produtoValor = floatval( get_post_meta( $item_id, '_regular_price', true) );
$valorTotal = $produtoValor + ( $endereco_igual * $quantidadeDependentes );
WC()->cart->total = $valorTotal;
WC()->cart->calculate_totals();
wc_price($valorTotal);
}
echo json_encode(
array(
'status' => 'success',
'valorTotal' => wc_price($valorTotal)
));
wp_die();
}
My Ajax request
function contagemDependentes()
{
$contagem = jQuery('.woocommerce-dependentes-contagem');
var quantiaDependentes = jQuery('.woocommerce-dependentes-card').length;
if ( quantiaDependentes <= 0 ) {
var mensagemNumeroDependentes = 'Nenhum dependente informado';
} else if ( quantiaDependentes === 1 ) {
var mensagemNumeroDependentes = '1 dependente';
} else {
var mensagemNumeroDependentes = quantiaDependentes+' dependentes';
}
jQuery($contagem).html(mensagemNumeroDependentes);
var quantiaDependentes = jQuery('.woocommerce-dependentes-card').length + 1;
var dados = {
action: 'add_total_value',
quantiaDependentes: quantiaDependentes
};
jQuery.ajax({
type: 'POST',
url: custom_values.ajaxurl,
data: dados,
dataType: 'json',
success: function(response)
{
console.log(response);
if (response.status === 'success')
{
console.log(response.status);
console.log(response.valorTotal);
var html = "<tr class='order-total'>";
html += "<th>Total</th>";
html += "<td>";
html += response.valorTotal;
html += "</td>";
html += "</tr>";
jQuery( '.order-total' ).remove();
jQuery( 'tfoot' ).append( html );
jQuery( 'body' ).trigger( 'update_checkout' );
}
}
});
}
before function() in functions.php always must be such code
add_action('wp_ajax_your_function_name', 'your_function_name');
add_action('wp_ajax_nopriv_your_function_name', 'your_function_name');

Woocommerce added custom fee, trying to manipulate with checkbox via AJAX

i was hoping if i could get some information about whats going on in here.
I added an extra fee in the totals part of the checkout, it adds the 10% of the subtotal.
Now this works since i added the following code snippet via a plugin:
add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee' );
function endo_handling_fee() {
global $woocommerce;
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$subtotal = $woocommerce->cart->subtotal;
$fee_percentage = 0.1; // 10 percent
$fee = ($subtotal * $fee_percentage);
$woocommerce->cart->add_fee( 'Seguro de Envio', $fee, true, 'standard' );
}
And it actually works but i have to be able to activate it via a checkbox.
Check box was created by going into cart-totals and using this code:
<?php foreach ( WC()->cart->get_fees() as $fee ) : ?>
<tr class="fee">
<th><?php echo esc_html( $fee->name ); ?> <input type="checkbox" id="envio"> </th>
<td id="seguroenvio" data-title="<?php echo esc_html( $fee->name ); ?>"><? php wc_cart_totals_fee_html( $fee ); ?></td>
</tr>
<?php endforeach; ?>
Also at the bottom of cart-totals.php file, i added this:
<?php do_action( 'woocommerce_after_cart_totals' ); ?>
<script src="https://code.jquery.com/jquery-2.2.1.min.js"></script>
<script type="text/javascript">
$("#envio").on("change", function() {
var mee = ($(this).is(":checked") == true) ? "yes" : "no";
$.ajax({
type: 'post',
url: 'http://valaidp.com/mrelectronicstest/wp- content/plugins/woocommerce/templates/cart/fields.php',
data: {status:mee},
success: function(output) {
$('#seguroenvio').text(output);
}
});
});
</script>
<?php
function custom_checkbox_checker () {
if ( is_checkout() ) {
wp_enqueue_script( 'jquery' ); ?>
<script type="text/javascript">
jQuery(document).ready( function (e) {
var $ = jQuery;
// wc_checkout_params is required to continue, ensure the object exists
if ( typeof wc_checkout_params === 'undefined' )
return false;
var updateTimer,
dirtyInput = false,
xhr;
function update_shipping() {
if ( xhr ) xhr.abort();
var liftgate = $( '#envio:checked' ).val();
var data = {
action: 'woocommerce_update_order_review',
security: wc_checkout_params.update_order_review_nonce,
liftgate: liftgate,
post_data: $( 'form' ).serialize()
};
xhr = $.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function( response ) {
if ( response ) {
//$( '#order_review' ).html( $.trim( response ) );
$( '#order_review' ).find( '#envio:checked' ).trigger('click');
$( 'body' ).trigger('updated_checkout' );
}
}
});
}
jQuery('#envio').on('click', function() {
update_shipping();
$woocommerce->cart->add_fee( 'Seguro de Envio', $fee, true, 'standard' );
});
});
</script>
<?php }
}
And to finish off, in the same location of the cart-totals.php i added a fields.php file that i created adding this code:
<?php
global $woocommerce;
add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee' );
/*global $woocommerce;
$subtotal = $woocommerce->cart->subtotal;
$fee_percentage = 0.1; // 10 percent
$fee = ($subtotal * $fee_percentage);
$woocommerce->cart->add_fee( 'Seguro de Envio', $fee, true, 'standard' );
echo $fee." ";
require('../../../../../wp-includes/functions.php'); */
function endo_handling_fee() {
global $woocommerce;
if (is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$subtotal = $woocommerce->cart->subtotal;
$fee_percentage = 0.1; // 10 percent
$fee = ($subtotal * $fee_percentage);
if($_POST["status"] == "yes"){
$woocommerce->cart->add_fee( 'Seguro de Envio', $fee, true, 'standard' );
echo $fee." ";
}
else
{
$woocommerce->cart->add_fee( 'Seguro de Envio', 0, true, 'standard' );
echo "0";
}
echo 0;
}
?>
The checkbox appears but its not triggering anything when clicked.
Any help is much appreciated.
Woocommerce version 4.4.2
Site url: valaidp.com/mrelectronicstest

Categories