Related
I have a Checkout page using Woocommerce where I have Discount added using the following code since I have a checkbox where user could check and the discount will apply. Here is the products page, please add any of them and proceed to Checkout page where you will get that Discount Checbox with label "Senior, Military, etc.". You can try entering "SAVE15" for the coupon code to apply.
// Add a custom checkbox fields after billing fields
function action_woocommerce_after_checkout_billing_form( $checkout ) {
// Add a custom checkbox field
echo '<h3 class="discount-type">' . __('DISCOUNT TYPE') . '</h3>';
woocommerce_form_field( 'discount30', array(
'type' => 'checkbox',
'label' => __( ' Senior, Military, Police, Firefighter, EMT Discount, Teacher',
'woocommerce' ),
'class' => array( 'form-row-wide' ),
), '' );
}
add_action( 'woocommerce_after_checkout_billing_form',
'action_woocommerce_after_checkout_billing_form', 10, 1 );
// Remove "(optional)" label on "discount30" field
function filter_woocommerce_form_field( $field, $key, $args, $value ) {
// Only on checkout page
if ( $key === 'discount30' && is_checkout() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) .
')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
add_filter( 'woocommerce_form_field' , 'filter_woocommerce_form_field', 10, 4 );
// jQuery - Ajax script
function action_wp_footer() {
// Only on Checkout
if ( is_checkout() && ! is_wc_endpoint_url() ) :
if ( WC()->session->__isset('enable_fee') )
WC()->session->__unset('enable_fee')
?>
<script type="text/javascript">
jQuery( function($){
if ( typeof wc_checkout_params === 'undefined' )
return false;
$( 'form.checkout' ).on( 'change', 'input[name=discount30]', function(e) {
var fee = $(this).prop('checked') === true ? '1' : '';
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'enable_fee',
'enable_fee': fee,
},
success: function (result) {
$('body').trigger('update_checkout');
},
});
});
});
</script>
<?php
endif;
}
add_action( 'wp_footer', 'action_wp_footer' );
// Get Ajax request and saving to WC session
function get_enable_fee() {
if ( isset($_POST['enable_fee']) ) {
WC()->session->set( 'enable_fee', ( $_POST['enable_fee'] ? true : false ) );
}
die();
}
add_action( 'wp_ajax_enable_fee', 'get_enable_fee' );
add_action( 'wp_ajax_nopriv_enable_fee', 'get_enable_fee' );
// Add a custom 3 Cents Discount
function action_woocommerce_cart_calculate_fees( $cart ) {
// Only on checkout
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_checkout() )
return;
// Get number of items in the cart.
$items_in_cart = $cart->get_cart_contents_count();
// Calculate
$discount = 0.03 * $items_in_cart;
// Apply discount
if ( WC()->session->get('enable_fee') ) {
$cart->add_fee( __( 'Discount', 'woocommerce' ), -$discount );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1
);
Now, I'm using Coupon Code as well but don't want it to get mixed up so, how can I make a condition that if someone enter the Coupon Code, the discount that ABOVE code applies should be removed?
I am implementing the custom Buy Now button in my plugin. I had placed the Buy Now button on the product page using this hook
add_action( 'woocommerce_after_add_to_cart_button', 'myCustomBuyNowButton');
So, my next step is to add the product to the cart with quantity, variation details, which I am able to achieve by writing the following function i.e
(function ($) {
$(document).on('click', '.single_add_to_cart_button', function (e) {
e.preventDefault();
var $thisbutton = $(this),
$form = $thisbutton.closest('form.cart'),
id = $thisbutton.val(),
product_qty = $form.find('input[name=quantity]').val() || 1,
product_id = $form.find('input[name=product_id]').val() || id,
variation_id = $form.find('input[name=variation_id]').val() || 0;
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: product_id,
product_sku: '',
quantity: product_qty,
variation_id: variation_id,
};
$(document.body).trigger('adding_to_cart', [$thisbutton, data]);
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
beforeSend: function (response) {
$thisbutton.removeClass('added').addClass('loading');
},
complete: function (response) {
$thisbutton.addClass('added').removeClass('loading');
},
success: function (response) {
if (response.error && response.product_url) {
window.location = response.product_url;
return;
} else {
$(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
}
},
});
return false;
});
})(jQuery);
& ajax is calling the following hook
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
function woocommerce_ajax_add_to_cart() {
$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 = absint($_POST['variation_id']);
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {
do_action('woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX :: get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
echo wp_send_json($data);
}
wp_die();
}
But I am stuck in adding the custom plugin data to the cart along with the quantity and variation details.
For ex: If the admin has installed a custom product fields plugin that helps them to add the custom fields on their product page to collect extra information. I need to add that information also to the cart.
Can anyone please help me to resolve this issue? Thanks in advance.
Use these hooks
// Add item data to the cart or define custom variable
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_datax',10, 3 );
// Display item data to the cart or show custom variable
add_filter( 'woocommerce_get_item_data', 'get_cart_item_data', 10, 2 );
function add_cart_item_datax( $cart_item_data, $productId, $variationId ) {
if ( empty( $cart_item_data['basicpluginstr'] ) ) {
$cart_item_data['basicpluginstr'] = array();
}
$data[] = array(
'name' => 'Name',
'value' => 'valus',
'price' => 50
);
$cart_item_data['basicpluginstr'] = array_merge( $cart_item_data['basicpluginstr'], $data);
return $cart_item_data;
}
function get_cart_item_data( $data, $cartItem ) {
if ( isset( $cartItem['basicpluginstr'] ) ) {
foreach ( $cartItem['basicpluginstr'] as $basicpluginstr ) {
$name = 'PPPPPPP'; //$basicpluginstr['name'];
$value = '12364'; //$basicpluginstr['value'];
$price = '150'; //$basicpluginstr['price'];
}
$data[] = array(
'name' => $name,
'value' => $value,
'display' => 0
);
}
return $data;
}
//Add meta to order - WC 2.x or save the data when the order is made
add_action( 'woocommerce_add_order_item_meta', 'add_order_item_meta' , 10, 2 );
function add_order_item_meta( $item_id, $values ) {
if ( ! empty( $values['basicpluginstr'] ) ) {
foreach ( $values['basicpluginstr'] as $basicpluginstr ) {
$name = $basicpluginstr['name'];
$value = $basicpluginstr['value'];
woocommerce_add_order_item_meta( $item_id, $name, $value );
//woocommerce_add_order_item_meta( $item_id, 'basicpluginstr', 'basicpluginstr value' );
}
}
}
I have added a custom Field in admin and try to add itemdata in cart
<?php
/*
* Plugin Name: Custom Woo option
* Author: Gaurav Dev
* Text Domain: custom-woo-option
* Description: This is the Custom Woo option plugin
* Version: 1.0.0
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
define( 'basicpluginstr_VERSION', '1.0.0' );
define( 'basicpluginstr_URI', plugin_dir_url( __FILE__ ) );
class basicpluginstr
{
//https://stackoverflow.com/questions/21650019/woocommerce-add-input-field-to-every-item-in-cart
function __construct()
{
// Product data tabs
add_filter( 'woocommerce_product_data_tabs', array( $this,'basicpluginstr_product_data_tabs') );
// Product data panels
add_action( 'woocommerce_product_data_panels', array( $this,'basicpluginstr_product_data_panels') );
// Add to cart
add_filter('woocommerce_add_cart_item', array($this, 'add_cart_item'), 999999999999999999, 1);
// Add item data to the cart or define custom variable
add_filter( 'woocommerce_add_cart_item_data', array($this,'add_cart_item_data'),10, 3 );
// Display item data to the cart or show custom variable
add_filter( 'woocommerce_get_item_data', array($this,'get_cart_item_data'), 10, 2 );
// Load cart data per page load
add_filter( 'woocommerce_get_cart_item_from_session', array( $this, 'get_cart_item_from_session' ), 999999999999999999, 2 );
//Add meta to order - WC 2.x or save the data when the order is made
add_action( 'woocommerce_add_order_item_meta', array($this,'add_order_item_meta') , 10, 2 );
//Save post
add_action( 'save_post', array($this,'custom_wp_bakery_save_post_fun'), 12, 1);
//Add Field on single Product Page
add_action( 'woocommerce_before_add_to_cart_button', array($this,'add_name_on_tshirt_field'));
}
/*
* Defined Product Data Tab
*/
function basicpluginstr_product_data_tabs( $tabs ) {
$tabs['basicpluginstr'] = array(
'label' => esc_html__( 'basicpluginstr', 'cus-price-cal' ),
'target' => 'basicpluginstr_settings',
'class' => array( 'show_if_basicpluginstr' ),
);
return $tabs;
}
/*
* Define Product Data Panel
*/
function basicpluginstr_product_data_panels() {
global $post;
$post_id = $post->ID;
$_core_price = get_post_meta( $post_id, '_core_price', true );
?>
<div id='basicpluginstr_settings' class='panel woocommerce_options_panel basicpluginstr_options_panel'>
<h1>Core Price</h1>
<input type="Text" name="_core_price" id="_core_price" value="<?php echo $_core_price;?>">
</div>
<?php
}
function add_cart_item($cart_item) {
if ( isset( $cart_item['basicpluginstr'] ) ) {
foreach ( $cart_item['basicpluginstr'] as $basicpluginstr ) {
$_core_price = $basicpluginstr['_core_price'];
}
$cart_item['data']->set_price($_core_price);
//$cart_item['data']->adjust_price( $extra_cost );
}
return $cart_item;
}
function add_cart_item_data( $cart_item_data, $productId, $variationId ) {
if ( empty( $cart_item_data['basicpluginstr'] ) ) {
$cart_item_data['basicpluginstr'] = array();
}
$data[] = array(
'name' => 'Core Price',
'value' => '10',
'_core_price' => 10
);
$cart_item_data['basicpluginstr'] = array_merge( $cart_item_data['basicpluginstr'], $data);
return $cart_item_data;
}
function get_cart_item_data( $data, $cartItem ) {
if ( isset( $cartItem['basicpluginstr'] ) ) {
foreach ( $cartItem['basicpluginstr'] as $basicpluginstr ) {
$name = $basicpluginstr['name'];
$value = $basicpluginstr['value'];
}
$data[] = array(
'name' => $name,
'value' => $value,
'display' => 0
);
}
return $data;
}
function get_cart_item_from_session($cart_item, $values) {
if ( ! empty( $values['basicpluginstr'] ) ) {
$cart_item['basicpluginstr'] = $values['basicpluginstr'];
$cart_item = $this->add_cart_item( $cart_item );
}
return $cart_item;
}
function add_order_item_meta( $item_id, $values ) {
if ( ! empty( $values['basicpluginstr'] ) ) {
foreach ( $values['basicpluginstr'] as $basicpluginstr ) {
$name = $basicpluginstr['name'];
$value = $basicpluginstr['value'];
woocommerce_add_order_item_meta( $item_id, $name, $value );
//woocommerce_add_order_item_meta( $item_id, 'basicpluginstr', 'basicpluginstr value' );
}
}
}
function custom_wp_bakery_save_post_fun($post_id){
if (isset($_POST['_core_price'])) {
update_post_meta($post_id, '_core_price', $_POST['_core_price']);
}
}
function add_name_on_tshirt_field() {
$_core_price = get_post_meta( get_the_ID(), '_core_price', true );
if (!empty($_core_price)) {
echo '<table class="variations" cellspacing="0">
<tbody>
<tr>
<td class="label"><label for="color">Core Price</label></td>
<td class="value">
<input type="text" name="_core_price" value="'.$_core_price.'" />
</td>
</tr>
</tbody>
</table>';
}
}
}
new basicpluginstr();
}
Please try the example in your working environment and modify it accordingly
Based on Update fee dynamically based on radio buttons in Woocommerce checkout anser code. I'm trying to make it work with different packaging options on WooCommerce checkout.
The idea is to be able to provide options for gift wrapping, packaging in a bag and so forth.
Problem is, it gives me selectable options but it's all messed up as it is printing out the HTML for the tags and what not.
This is the code I am working with:
add_action( 'woocommerce_form_field_radio', 'gift_bag_none', 20, 4 );
function gift_bag_none( $field, $key, $args, $value ) {
if ( ! empty( $args['options'] ) && is_checkout() ) {
$field = str_replace( '</label><input ', '</label><br><input ', $field );
$field = str_replace( '<label ', '<label style="display:inline;margin-left:8px;" ', $field );
}
return $field;
}
add_action( 'woocommerce_cart_calculate_fees', 'gift_bag_none_fee', 20, 1 );
function gift_bag_none_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
$packing_fee = WC()->session->get( 'chosen_packing' );
if( $packing_fee === 'box' )
$fee = 29.00;
else if( $packing_fee === 'none' )
$fee = 0.00;
else if( $packing_fee === 'both' )
$fee = 25.00;
else
$fee = 5.00;
$cart->add_fee( __( 'Packaging Cost', 'woocommerce' ), $fee );
}
add_action( 'woocommerce_review_order_after_shipping', 'checkout_packing_addition', 20 );
function checkout_packing_addition() {
$domain = 'woocommerce';
echo '<tr><th>' . __('Packaging Options', $domain) . '</th><td>';
echo '<tr class="packing-select"><th>' . __('In a bag?<br>Boxed and wrapped as gift?<br><span style="color:red;">Boxed, wrapped and in a bag?</span><br>Or just the product?', $domain) . '</th><td>';
$chosen = WC()->session->get('chosen_packing');
$chosen = empty($chosen) ? WC()->checkout->get_value('radio_packing') : $chosen;
$chosen = empty($chosen) ? 'none' : $chosen;
woocommerce_form_field( 'radio_packing', array(
'type' => 'radio',
'class' => array( 'form-row-wide packing' ),
'options' => array(
'bag' => __('Yes, give it to me in a bag for '.wc_price(5.00), $domain),
'box' => __('Giftbox + Wrapping for '.wc_price(29.00), $domain),
'both' => __('Wrapped Giftbox in a Bag for '.wc_price(25.00), $domain),
'none' => __('Just the product at no extra cost '.wc_price(0.00), $domain)
),
'default' => $chosen,
), $chosen );
echo '</td></tr>';
}
add_action( 'wp_footer', 'checkout_packing_script' );
function checkout_packing_script(){ ?>
<script type="text/javascript">
jQuery( function($) {
$('form.checkout').on('change', 'input[name=radio_packing]', function(e){
e.preventDefault();
var p = $(this).val();
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'woo_get_ajax_data',
'packing': p,
},
success: function (result) {
$('body').trigger('update_checkout');
},
error: function(error){
}
});
});
});
</script>
<?php
}
add_action('wp_ajax_woo_get_ajax_data', 'packing_ajax_data');
add_action('wp_ajax_nopriv_woo_get_ajax_data', 'packing_ajax_data');
function packing_ajax_data() {
if ( isset($_POST['packing']) ){
$packing = sanitize_key( $_POST['packing'] );
WC()->session->set('chosen_packing', $packing );
echo json_encode( $packing );
}
die();
}
Updated: 10/2021 - tested in WordPress 5.8.1 & WooCommerce 5.7.1
Your code has some minor mistakes
Use add_filter( 'woocommerce_form_field_radio' instead of add_action(..
Use strip_tags( wc_price() ) against wc_price()
So you get:
// Customizing WooCommerce radio form field
function filter_woocommerce_form_field_radio( $field, $key, $args, $value ) {
// Specific key and apply on checkout page
if ( ! empty( $args['options'] ) && $key == 'radio_packing' && is_checkout() ) {
$field = str_replace( '</label><input ', '</label><br><input ', $field );
$field = str_replace( '<label ', '<label style="display:inline;margin-left:8px;" ', $field );
}
return $field;
}
add_filter( 'woocommerce_form_field_radio', 'filter_woocommerce_form_field_radio', 20, 4 );
function action_woocommerce_cart_calculate_fees( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Dynamic packing fee
$packing_fee = WC()->session->get( 'chosen_packing' );
// Determine packing fee
if ( $packing_fee === 'bag' ) {
$fee = 5.00;
} else if( $packing_fee === 'box' ) {
$fee = 29.00;
} else if( $packing_fee === 'both' ) {
$fee = 25.00;
} else {
$fee = 0.00;
}
// Add fee: name - amount - taxable
$cart->add_fee( __( 'Packaging fee', 'woocommerce' ), $fee, true );
}
add_action( 'woocommerce_cart_calculate_fees', 'action_woocommerce_cart_calculate_fees', 10, 1 );
// Add a custom radio fields for packaging selection
function action_woocommerce_review_order_after_shipping() {
// Domain
$domain = 'woocommerce';
// Output
echo '<tr class="packing-select"><th>' . __('Packing options', $domain ) . '</th><td>';
$chosen = WC()->session->get( 'chosen_packing' );
$chosen = empty( $chosen ) ? WC()->checkout->get_value( 'radio_packing' ) : $chosen;
$chosen = empty( $chosen ) ? 'none' : $chosen;
// Add a custom checkbox field
woocommerce_form_field( 'radio_packing', array(
'type' => 'radio',
'class' => array( 'form-row-wide packing' ),
'options' => array(
'bag' => sprintf( __( 'Yes, give it to me in a bag for %s', $domain ), strip_tags( wc_price( 5.00 ) ) ),
'box' => sprintf( __( 'Giftbox + Wrapping for %s', $domain ), strip_tags( wc_price( 29.00 ) ) ),
'both' => sprintf( __( 'Wrapped Giftbox in a Bag for %s', $domain ), strip_tags( wc_price( 25.00 ) ) ),
'none' => sprintf( __( 'Just the product at no extra cost %s', $domain ), strip_tags( wc_price( 0.00 ) ) )
),
'default' => $chosen,
), $chosen );
echo '</td></tr>';
}
add_action( 'woocommerce_review_order_after_shipping', 'action_woocommerce_review_order_after_shipping', 10, 0 );
// jQuery - Ajax script
function action_wp_footer() {
if ( ! is_checkout() )
return; // Only checkout page
?>
<script type="text/javascript">
jQuery( function($){
$('form.checkout').on('change', 'input[name=radio_packing]', function(e){
e.preventDefault();
var p = $(this).val();
$.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: {
'action': 'woo_get_ajax_data',
'packing': p,
},
success: function (result) {
$('body').trigger('update_checkout');
console.log('response: '+result); // just for testing | TO BE REMOVED
},
error: function(error){
console.log(error); // just for testing | TO BE REMOVED
}
});
});
});
</script>
<?php
}
add_action( 'wp_footer', 'action_wp_footer', 10, 0 );
// Php Ajax (Receiving request and saving to WC session)
function woo_get_ajax_data() {
if ( isset($_POST['packing']) ){
$packing = sanitize_key( $_POST['packing'] );
WC()->session->set('chosen_packing', $packing );
echo json_encode( $packing );
}
die(); // Always at the end (to avoid server error 500)
}
add_action( 'wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data' );
add_action( 'wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data' );
In WooCommerce, I use a code that shows the steak weight selection form, saves the selection data and displays this data in the cart, on the checkout page, when editing the order and in email notifications.
// Display Custom Checkbox Field
add_action('woocommerce_product_options_general_product_data', 'steak_custom_field_add');
function steak_custom_field_add(){
global $post;
// Checkbox
woocommerce_wp_checkbox(
array(
'id' => '_steak_checkbox',
'label' => __('Steak Weight', 'woocommerce' ),
'description' => __( 'If necessary, enable steak weight selection', 'woocommerce' )
)
);
}
// Save Custom Checkbox Field
add_action('woocommerce_process_product_meta', 'steak_custom_field_save');
function steak_custom_field_save($post_id){
// Custom Product Checkbox Field
$steak_checkbox = isset( $_POST['_steak_checkbox'] ) ? 'yes' : 'no';
update_post_meta($post_id, '_steak_checkbox', esc_attr( $steak_checkbox ));
}
// Display Custom Select Box
add_action( 'woocommerce_before_add_to_cart_button', 'display_steak_custom_field', 0 );
function display_steak_custom_field() {
global $product;
// If is single product page and have the "steak_checkbox" enabled we display the field
if ( $product->get_meta( '_steak_checkbox' ) === 'yes' ) {
echo '<div class="steak_select_box">';
$select = woocommerce_form_field( 'steak_custom_options', array(
'type' => 'select',
'class' => array('my-steak-select-box form-row-wide'),
'label' => __('Steak Weight'),
'required' => false,
'return' => false,
'options' => array(
'' => 'Select...',
'300g' => '300g',
'400g' => '400g',
'500g' => '500g',
'600g' => '600g',
'700g' => '700g',
'800g' => '800g',
'900g' => '900g',
'1000g' => '1000g'
)
), '' );
echo $select;
echo '</div>';
}
}
// Add as custom cart item data
add_filter( 'woocommerce_add_cart_item_data', 'add_custom_steak_cart_item_data', 10, 21 );
function add_custom_steak_cart_item_data($cart_item_data, $product_id, $variation_id ){
if( isset( $_POST['steak_custom_options'] ) ) {
$cart_item_data['steak_option'] = wc_clean( $_POST['steak_custom_options'] );
}
return $cart_item_data;
}
// Add custom fields values under cart item name in cart
add_filter( 'woocommerce_cart_item_name', 'steak_custom_field_add_cart', 10, 21 );
function steak_custom_field_add_cart( $item_name, $cart_item, $cart_item_key ) {
if( ! is_cart() )
return $item_name;
if( isset($cart_item['steak_option']) ) {
$item_name .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . '</div>';
}
return $item_name;
}
// Display custom fields values under item name in checkout
add_filter( 'woocommerce_checkout_cart_item_quantity', 'steak_custom_checkout_cart_item_name', 10, 21 );
function steak_custom_checkout_cart_item_name( $item_qty, $cart_item, $cart_item_key ) {
if( isset($cart_item['steak_option']) ) {
$item_qty .= '<div class="my-steak-class"><strong>' . __("Steak Weight", "woocommerce") . ':</strong> ' . $cart_item['steak_option'] . 'гр.</div>';
}
return $item_qty;
}
// Save chosen select field value to each order item as custom meta data and display it everywhere
add_action('woocommerce_checkout_create_order_line_item', 'save_order_item_steak_field', 10, 21 );
function save_order_item_steak_field( $item, $cart_item_key, $values, $order ) {
if( isset($values['steak_option']) ) {
$key = __('Steak Weight', 'woocommerce');
$value = $values['steak_option'];
$item->update_meta_data( $key, $value ,$item->get_id());
}
}
add_action('wp_footer','add_footer_steak_script');
function add_footer_steak_script(){
?>
<script>
( function( $ ) {
$( document ).ready( function() {
$(document).on('change', '#steak_custom_options' ,function() {
$('.add_to_cart_button').data('steak_custom_options', this.value)
});
});
}( jQuery ) );
</script>
<?php
}
But unfortunately, I do not know how to solve one problem ...
The price of this product is calculated per 100 grams. The minimum order quantity is 300 grams. And I need that, when choosing the weight of the product, the final cost of this product should be calculated accordingly.
For example:
for 300g - $regular_price * 3 = $new_price
for 500g - $regular_price * 5 = $new_price
for 1000g - $regular_price * 10 = $new_price
etc.
The total cost of this product should be shown next to the main price per 100 grams.
I think this code will be useful to other developers as well. I will be very happy for your help!
To adjust the product price, on the cart page, etc.. based on the weight selected from the dropdown, add the following code
function my_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
// Loop through cart items
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if( isset( $cart_item['steak_option'] ) ) {
// Remove the last 2 zeros (100g becomes 1, 300g becomes 3, 1000g becomes 10, etc...)
// Remove 'g' from grams
// convert string to integer
$chosen_weight = (int) str_replace( '00', '', str_replace('g', '', $cart_item['steak_option']) );
// Get current price
$current_price = $cart_item['data']->get_price();
// Set new price, price is already known per 100g
$cart_item['data']->set_price( $current_price * $chosen_weight );
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'my_before_calculate_totals', 10, 1 );
To change the price on the single product page, based on the dropdown menu, add this
function add_footer_steak_script() {
global $woocommerce, $product;
?>
<script type="text/javascript">
jQuery(document).ready(function ($) {
console.log('JS works!');
var price = <?php echo $product->get_price(); ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>';
$( '[name=steak_custom_options]' ).change(function(){
if (!(this.value < 1)) {
var dropdown_val = this.value;
var remove_g = dropdown_val.replace( 'g', '' );
var remove_double_zero = remove_g.replace( '00', '' );
var product_total = parseFloat( price * remove_double_zero );
$( '.woocommerce-Price-amount' ).html( currency + product_total.toFixed(2));
}
});
});
</script>
<?php
}
add_action('wp_footer','add_footer_steak_script');
I'm trying to ad a custom fee to the order total upon checkout.
I've added a checkbox within woocommerce
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( $checkout ) {
echo '<div id="message_fields">';
woocommerce_form_field( 'add_gift_box', array(
'type' => 'checkbox',
'class' => array('add_gift_box form-row-wide'),
'label' => __('Ilość pudełek ozdobnych - 25 PLN/szt'),
'placeholder' => __(''),
), $checkout->get_value( 'add_gift_box' ));
}
Included a custom js file which schould handle the event
jQuery( document ).ready(function( $ ) {
$('#add_gift_box').click(function(){
var data = {
action: 'woocommerce_add_gift_box',
state: '200',
};
jQuery.ajax({
type: 'POST',
url: wc_checkout_params.ajax_url,
data: data,
success: function (code) {
console.log(code);
jQuery('body').trigger('update_checkout');
},
dataType: 'html'
});
});
});
And a php fee handling function
function woo_add_cart_fee( $data ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) || ! $_POST ) return;
$extracost = 0;
if (isset($_POST['state'])) {
$extracost = intval($_POST['state']);
}
WC()->cart->add_fee( 'Ozdobne pudełka:', $extracost );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
add_action('wp_ajax_woocommerce_add_gift_box', 'woo_add_cart_fee', 10);
add_action('wp_ajax_nopriv_woocommerce_add_gift_box', 'woo_add_cart_fee', 10);
For some reasons the value of $_POST['state'] isn't added, the function works when I give a hard coded value, I've tried many option but cant get this to work.
I've seen similar posts but none of them had the answer.
The post data is sent by the AJAX functions in 'post_data', serialized. So to get the value of your checkbox, you only need to parse_str() this!
parse_str( $_POST['post_data'], $post_data );
then you can get your 'add_gift_box' option from $post_data['add_gift_box']. Note that upon order completion, this 'post_data' element is not available anymore and everything is in $_POST.
Complete example, based on your code:
1) adding the checkbox to the checkout
add_action( 'woocommerce_after_checkout_billing_form', 'add_box_option_to_checkout' );
function add_box_option_to_checkout( $checkout ) {
echo '<div id="message_fields">';
woocommerce_form_field( 'add_gift_box', array(
'type' => 'checkbox',
'class' => array('add_gift_box form-row-wide'),
'label' => __('Ilość pudełek ozdobnych - 25 PLN/szt'),
'placeholder' => __(''),
), $checkout->get_value( 'add_gift_box' ));
echo '</div>';
}
2) script to update cart when checkbox clicked (no need for extra AJAX requests!)
add_action( 'wp_footer', 'woocommerce_add_gift_box' );
function woocommerce_add_gift_box() {
if (is_checkout()) {
?>
<script type="text/javascript">
jQuery( document ).ready(function( $ ) {
$('#add_gift_box').click(function(){
jQuery('body').trigger('update_checkout');
});
});
</script>
<?php
}
}
3) action to add the fee
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
function woo_add_cart_fee( $cart ){
if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
return;
}
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST; // fallback for final checkout (non-ajax)
}
if (isset($post_data['add_gift_box'])) {
$extracost = 25; // not sure why you used intval($_POST['state']) ?
WC()->cart->add_fee( 'Ozdobne pudełka:', $extracost );
}
}
This is awesome!! Thanks a lot. I've changed it a little bit to add a percentage instead. I know this is not a better answer but I have no reputation to push your answer up. For whoever was stuck like me..
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' ); function woo_add_cart_fee( $cart ){
global $woocommerce;
if ( ! $_POST || ( is_admin() && ! is_ajax() ) ) {
return;
}
if ( isset( $_POST['post_data'] ) ) {
parse_str( $_POST['post_data'], $post_data );
} else {
$post_data = $_POST; // fallback for final checkout (non-ajax)
}
if (isset($post_data['add_gift_box'])) {
$percentage = 0.01;
$surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
}