Reputation: 29
In WooCommerce I want to have a checkbox that, when pressed, it adds a product to my cart, and the price of that product is 3% of the total cart price.
Based on "Checkbox field that add to cart a product in Woocommerce checkout page" answer thread and edited a bit to suit my needs, here is my code:
// Display a custom checkout field
add_action( 'woocommerce_checkout_before_terms_and_conditions', 'custom_checkbox_checkout_field' );
function custom_checkbox_checkout_field() {
$value = WC()->session->get('add_a_product');
woocommerce_form_field( 'cb_add_product', array(
'type' => 'checkbox',
'label' => ' ' . __('Add Assembly Service (3% extra)'),
'class' => array('form-row-wide'),
), $value == 'yes' ? true : false );
}
// The jQuery Ajax request
add_action( 'wp_footer', 'checkout_custom_jquery_script' );
function checkout_custom_jquery_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// Remove "ship_different" custom WC session on load
if( WC()->session->get('add_a_product') ){
WC()->session->__unset('add_a_product');
}
if( WC()->session->get('product_added_key') ){
WC()->session->__unset('product_added_key');
}
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on( 'change', '#cb_add_product', function(){
var value = $(this).prop('checked') === true ? 'yes' : 'no';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'add_a_product',
'add_a_product': value,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log(result);
}
});
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax PHP receiver
add_action( 'wp_ajax_add_a_product', 'checkout_ajax_add_a_product' );
add_action( 'wp_ajax_nopriv_add_a_product', 'checkout_ajax_add_a_product' );
function checkout_ajax_add_a_product() {
if ( isset($_POST['add_a_product']) ){
WC()->session->set('add_a_product', esc_attr($_POST['add_a_product']));
echo $_POST['add_a_product'];
}
die();
}
// Add remove free product
add_action( 'woocommerce_before_calculate_totals', 'adding_removing_specific_product');
function adding_removing_specific_product( $cart ) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// HERE the specific Product ID
$product_id = 1514;
$result = WC()->session->get('add_a_product');
if( strpos($result, 'yes') !== false && ! WC()->session->get('product_added_key') )
{
$cart_item_key = $cart->add_to_cart( $product_id );
WC()->session->set('product_added_key', $cart_item_key);
}
elseif( strpos($result, 'no') !== false && WC()->session->get('product_added_key') )
{
$cart_item_key = WC()->session->get('product_added_key');
$cart->remove_cart_item( $cart_item_key );
WC()->session->__unset('product_added_key');
}
}
function woocommerce_custom_price_to_cart_item( $cart ) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
if( !WC()->session->__isset( "reload_checkout" )) {
global $woocommerce;
$totalPriceBeforeService = $cart->cart_contents_total;
$servicePrice = (float) ceil($totalPriceBeforeService) * 0.03;
foreach ( $cart->cart_contents as $key => $value ) {
$product_idnew = $value['data']->get_id();
if($product_idnew == 1514){
//set new prices
$value['data']->set_price($servicePrice);
$new_price = $value['data']->get_price();
echo" $new_price ";
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'woocommerce_custom_price_to_cart_item' );
It adds the product fine, and all is good. However, when I set the price, its not updating.
Okay, So here is the checkbox unselected.
And here is the checkbox after checking it. As you can see, the value of the item is 46.5, but its not updating in the cart. Any idea how to fix this?
Upvotes: 1
Views: 1823
Reputation: 29624
You use 2x woocommerce_before_calculate_totals
, I reduced it to 1.
$cart->get_cart_contents_total();
also include the original product price (of the new added product), so this will be deducted before the final calculation.
// Display a custom checkout field
add_action( 'woocommerce_checkout_before_terms_and_conditions', 'custom_checkbox_checkout_field' );
function custom_checkbox_checkout_field() {
$value = WC()->session->get('add_a_product');
woocommerce_form_field( 'cb_add_product', array(
'type' => 'checkbox',
'label' => ' ' . __('Add a demo product to your order'),
'class' => array('form-row-wide'),
), $value == 'yes' ? true : false );
}
// The jQuery Ajax request
add_action( 'wp_footer', 'checkout_custom_jquery_script' );
function checkout_custom_jquery_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// Remove "ship_different" custom WC session on load
if( WC()->session->get('add_a_product') ){
WC()->session->__unset('add_a_product');
}
if( WC()->session->get('product_added_key') ){
WC()->session->__unset('product_added_key');
}
// jQuery Ajax code
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
$('form.checkout').on( 'change', '#cb_add_product', function(){
var value = $(this).prop('checked') === true ? 'yes' : 'no';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'add_a_product',
'add_a_product': value,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log(result);
}
});
});
});
</script>
<?php
endif;
}
// The Wordpress Ajax PHP receiver
add_action( 'wp_ajax_add_a_product', 'checkout_ajax_add_a_product' );
add_action( 'wp_ajax_nopriv_add_a_product', 'checkout_ajax_add_a_product' );
function checkout_ajax_add_a_product() {
if ( isset($_POST['add_a_product']) ){
WC()->session->set('add_a_product', esc_attr($_POST['add_a_product']));
echo $_POST['add_a_product'];
}
die();
}
// Add remove free product
function adding_removing_specific_product( $cart ) {
if (is_admin() && !defined('DOING_AJAX'))
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// HERE the specific Product ID
$product_id = 1514;
if( WC()->session->get('add_a_product') == 'yes' && ! WC()->session->get('product_added_key') ) {
$cart_item_key = $cart->add_to_cart( $product_id );
WC()->session->set('product_added_key', $cart_item_key);
}
elseif( WC()->session->get('add_a_product') == 'no' && WC()->session->get('product_added_key') ) {
$cart_item_key = WC()->session->get('product_added_key');
$cart->remove_cart_item( $cart_item_key );
WC()->session->__unset('product_added_key');
}
if( !WC()->session->__isset( "reload_checkout" )) {
// Get cart total
$cart_total = $cart->get_cart_contents_total();
if ( isset( $cart_total ) && $cart_total != 0 ) {
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
// Get product id
$product_id_new = $cart_item['product_id'];
// Get original product price
$exclude_original_product_price = $cart_item['data']->get_price();
if( $product_id_new == $product_id ) {
// Calculate new cart total
$new_cart_total = $cart_total - $exclude_original_product_price;
// Caclulate new price ( 3% )
$new_price = $new_cart_total * 3 / 100;
$cart_item['data']->set_price( $new_price );
break;
}
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'adding_removing_specific_product', 10, 1 );
Upvotes: 1