This will change the text into "Add again?" when the customer clicks "Add to cart" and I'm wondering how to change this into applying a discount each time the button is clicked.
Code:
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_add_to_cart_again' );
function woo_add_to_cart_again() {
global $woocommerce;
foreach($woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if( get_the_ID() == $_product->id ) {
return __('Add Again', 'woocommerce');
}
}
return __('Add to cart', 'woocommerce');
}
When clicked the first time, add to cart as normal but change the button text into "Buy again & Get 5% OFF", after pressed the 2nd time, text changes into "Buy 3 and get 10% OFF" and the discount should apply to the product, not the cart.
I would like for this to be a checkbox option beside "Downloadable" in WooCommerce Admin when creating a new product. Any help is highly appreciated.
first to change the text based on the quantity i just added an if condition to your function to check the quantity for that specific product in the cart and change the text accordingly as follow:
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_add_to_cart_again' );
function woo_add_to_cart_again() {
global $woocommerce;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $values['quantity'] == 1 && get_the_ID() == $_product->id ) {
return __( 'Buy again & Get 5% OFF', 'woocommerce' );
}
if ( $values['quantity'] == 2 && get_the_ID() == $_product->id ) {
return __( 'Buy 3 and get 10% OFF', 'woocommerce' );
}
if ( $values['quantity'] > 2 && get_the_ID() == $_product->id ) {
return __( 'Add Again', 'woocommerce' );
}
}
return __( 'Add to cart', 'woocommerce' );
}
Note: if you want to change the text in the archive page too you can use woocommerce_product_add_to_cart_text hook and added it to the above code as follow:
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_add_to_cart_again' );
add_filter( 'woocommerce_product_add_to_cart_text', 'woo_add_to_cart_again' );
Then we need to calculate the price for those products which is qualified for the discount and add the discount based on the product prices.
We are going to use woocommerce_cart_calculate_fees to insert this discount to our cart as follow :
add_action( 'woocommerce_cart_calculate_fees', 'add_discount' );
function add_discount( WC_Cart $cart ) {
$discounts = []; //Store the disocunts in array
foreach ( $cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $values['quantity'] == 2 ) {
// Calculate the discount amount
$product_price = ( $_product->get_sale_price() ) ? $_product->get_sale_price() : $_product->get_regular_price();
$price = $product_price * 2;
array_push( $discounts, $price * 0.05 ); //Push the discount
}
if ( $values['quantity'] > 2 ) {
// Calculate the discount amount
$product_price = ( $_product->get_sale_price() ) ? $_product->get_sale_price() : $_product->get_regular_price();
$price = $product_price * $values['quantity'];
$discount = $price * 0.1;
array_push( $discounts, $price * 0.1 );//Push the discount
}
}
$cart->add_fee( 'Your Disocunt', -array_sum( $discounts ) );
}
Updated:
To Change the add_to_cart text when using Ajax actually it's already answered in here By #LoicTheAztec at this link and with little modification you can achieve your target goal as follow:
add_action( 'wp_footer', 'change_add_to_cart_jquery' );
function change_add_to_cart_jquery() {
if ( is_shop() || is_product_category() || is_product_tag() ) : ?>
<script type="text/javascript">
(function ($) {
$('a.add_to_cart_button').click(function () {
$this = $(this);
if (typeof $($this).attr('data-qty') == 'undefined') {
$($this).text('Buy again & Get 5% OFF');
$($this).attr('data-qty', 1);
return;
}
if ($($this).attr('data-qty') == 1) {
$($this).text('Buy 3 and get 10% OFF');
$($this).attr('data-qty', 2);
return
}
$($this).text('Add Again');
});
})(jQuery);
</script>
<?php
endif;
}
of course the code above has been tested.
Related
Based on Add a checkout checkbox field that enable a percentage fee in Woocommerce answer code, I've got a custom checkbox on which I need to offer discount to customers.
I'm trying to apply the custom discount of say $0.03 x product quantity e.g.
If quantity is 50 then the discount would be 50 x $0.03 = $1.5
Right now, it's deducting $0.03 from the Cart Total. Can anyone help me with achieving the required results?
Here is my code attempt:
// Add a custom checkbox fields after billing fields
add_action( 'woocommerce_after_checkout_billing_form', 'add_custom_checkout_checkbox', 20 );
function add_custom_checkout_checkbox(){
// Add a custom checkbox field
woocommerce_form_field( 'discount30', array(
'type' => 'checkbox',
'label' => __(' Senior'),
'class' => array( 'form-row-wide' ),
), '' );
}
// Remove "(optional)" label on "Installement checkbox" field
add_filter( 'woocommerce_form_field' , 'remove_order_comments_optional_fields_label', 10, 4 );
function remove_order_comments_optional_fields_label( $field, $key, $args, $value ) {
// Only on checkout page for Order notes field
if( 'discount30' === $key && is_checkout() ) {
$optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) .
')</span>';
$field = str_replace( $optional, '', $field );
}
return $field;
}
// jQuery - Ajax script
add_action( 'wp_footer', 'checkout_fee_script' );
function checkout_fee_script() {
// 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;
}
// Get Ajax request and saving to WC session
add_action( 'wp_ajax_enable_fee', 'get_enable_fee' );
add_action( 'wp_ajax_nopriv_enable_fee', 'get_enable_fee' );
function get_enable_fee() {
if ( isset($_POST['enable_fee']) ) {
WC()->session->set('enable_fee', ($_POST['enable_fee'] ? true : false) );
}
die();
}
// Add a custom 3 Cents Discount
add_action( 'woocommerce_cart_calculate_fees', 'custom_discount', 20, 1 );
function custom_discount( $cart ) {
// Only on checkout
if ( ( is_admin() && ! defined( 'DOING_AJAX' ) ) || ! is_checkout() )
return;
$discount = -0.03;
if( WC()->session->get('enable_fee') )
$cart->add_fee( __( 'Discount', 'woocommerce'), ( $discount ) );
}
To determine the discount based on the number of items in the cart, you can use WC()->cart->get_cart_contents_count();
Which then can be applied in the woocommerce_cart_calculate_fees action hook.
So you get:
// Add a custom checkbox fields after billing fields
function action_woocommerce_after_checkout_billing_form( $checkout ) {
// Add a custom checkbox field
woocommerce_form_field( 'discount30', array(
'type' => 'checkbox',
'label' => __( ' Senior', '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 );
Note: to get the number of products in cart opposite the number of items in cart
Change
// Get number of items in the cart.
$items_in_cart = $cart->get_cart_contents_count();
// Calculate
$discount = 0.03 * $items_in_cart;
To
// Products in cart
$products_in_cart = count( $cart->get_cart() );
// Calculate
$discount = 0.03 * $products_in_cart;
I am using the following code to auto apply a coupon when customer has $100 or more in cart.
add_action( 'woocommerce_checkout_before_order_review' , 'add_coupon_notice' );
function add_coupon_notice() {
$cart_total = WC()->cart->get_subtotal();
$minimum_amount = 100;
$currency_code = get_woocommerce_currency();
wc_clear_notices();
if ( $cart_total < $minimum_amount ) {
WC()->cart->remove_coupon( '20OFF100' );
wc_print_notice( "Get 20% off if you spend more than $$minimum_amount", 'notice' );
} else {
WC()->cart->apply_coupon( '20OFF100' );
wc_print_notice( '20% off $100 or more - Discount Applied!', 'notice' );
}
wc_clear_notices();
}
However, I want to exclude a specific product from this $100 minimum.
The specific product is on sale, and I've checked "Exclude Sale Items" in the coupon admin screen, but the code below is ignoring that.
Why isn't the 'Exclude Sale Items' working, and/or how can I go about this?
The biggest misconception in your code is that even though you checked "Exclude sale items" in the coupon admin screen, that the use of WC()->cart->get_subtotal() does not take this into account.
The solution:
You can use the woocommerce_before_calculate_totals hook
To avoid problems, use a coupon code without capital letters
When going through the cart content, we keep track of the total, except for the excluded products
Based on the current amount threshold and whether or not the coupon code has already been applied, we will display notices
So you get:
function action_woocommerce_before_calculate_totals( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// Coupon code
$coupon_code = 'coupon1';
// Total amount threshold
$amount_threshold = 100;
// Targeted product IDs, several can be entered, separated by a comma
$targeted_product_ids = array( 30, 813 );
// Initializing variables
$total_amount = 0;
$applied_coupons = $cart->get_applied_coupons();
// Loop through cart contents
foreach( $cart->get_cart_contents() as $cart_item ) {
// Excluding targeted product IDs
if ( ! in_array( $cart_item['data']->get_id(), $targeted_product_ids ) ) {
// Get the cart total amount
$total_amount += $cart_item['line_total'] + $cart_item['line_tax'];
}
}
// Applying coupon
if ( ! in_array( $coupon_code, $applied_coupons ) && $total_amount >= $amount_threshold ) {
$cart->apply_coupon( $coupon_code );
wc_clear_notices();
wc_add_notice( __( 'Succeeded', 'woocommerce' ), 'notice' );
}
// Buy more
elseif ( ! in_array( $coupon_code, $applied_coupons ) && $total_amount < $amount_threshold ) {
wc_clear_notices();
wc_add_notice( __( 'Buy more', 'woocommerce' ), 'notice' );
}
// Removing coupon
elseif ( in_array( $coupon_code, $applied_coupons ) && $total_amount < $amount_threshold ) {
$cart->remove_coupon( $coupon_code );
wc_clear_notices();
wc_add_notice( __( 'Removed', 'woocommerce' ), 'notice' );
}
}
add_action( 'woocommerce_before_calculate_totals', 'action_woocommerce_before_calculate_totals', 10, 1 );
I want to restrict the customer to place order of less than INR 400 for 2 states. So far i have tried this
add_action( 'woocommerce_check_cart_items', 'set_min_total' );
function set_min_total() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Set minimum cart total
$minimum_cart_total = 400;
?>
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery('#billing_state').on('change',function(){
var optionText = jQuery("#billing_state option:selected").val();
});
});
<?php $selected_state = '<script type="text/javascript">optionText</script>'?>
</script>;
<?php
$allowed_state = 'UP';
if($allowed_state != $selected_state) {
$total = WC()->cart->subtotal;
if( $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Minimum of %s %s is required before checking out.</strong>'
.'<br />Current cart\'s total: %s %s',
$minimum_cart_total,
get_option( 'woocommerce_currency'),
$total,
get_option( 'woocommerce_currency') ),
'error' );
}
}
}
}
but it didn't worked, please advice where am i doing wrong.
add_action( 'woocommerce_check_cart_items', 'cldws_set_min_total');
function cldws_set_min_total() {
// Only run in the Cart or Checkout pages
if( is_cart() || is_checkout() ) {
global $woocommerce;
// Set minimum cart total
$minimum_cart_total = 100;
// A Minimum of 100 AUD is required before checking out.
$total = WC()->cart->subtotal;
// Compare values and add an error is Cart's total
if( $total <= $minimum_cart_total ) {
// Display our error message
wc_add_notice( sprintf( '<strong>A Minimum of %s %s is required before checking out.</strong>'
.'<br />Current cart\'s total: %s %s',
$minimum_cart_total,
get_option( 'woocommerce_currency'),
$total,
get_option( 'woocommerce_currency') ),
'error' );
}
}
}
Please check with above code , here amount is 100 you can use as you need
Add the follows codes snippet to achieve the above task -
/**
* Set a minimum order amount for checkout
*/
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
// Set minimum order value
$minimum = 400;
if ( WC()->cart->total < $minimum ) {
if( is_cart() ) {
wc_print_notice(
sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order ' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
} else {
$billing_state = ( $_POST && isset( $_POST['billing_state'] ) ) ? $_POST['billing_state'] : '';
if( in_array( $billing_state, array( 'UP' ) ) ) {
wc_add_notice(
sprintf( 'Your current order total is %s — you must have an order with a minimum of %s to place your order' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
}
}
}
}
Codes goes to your active theme's functions.php.
I have this code which tells the customer how much is left to spend until shipping is free. But, it shows as soon as you visit a product page no matter if the product is added to the cart or not.
I would like it to show (see the various hooks) only after a product is added to cart. Any ideas?
Here is the code:
add_action( 'woocommerce_before_single_product', 'free_shipping_cart_notice_zones' );
add_action( 'woocommerce_checkout_before_order_review', 'free_shipping_cart_notice_zones' );
add_action( 'woocommerce_cart_totals_after_order_total', 'free_shipping_cart_notice_zones' );
function free_shipping_cart_notice_zones() {
global $woocommerce;
if ( WC()->cart->get_cart_contents_count() != 0 ) {
$default_zone = new WC_Shipping_Zone(0);
$default_methods = $default_zone->get_shipping_methods();
foreach( $default_methods as $key => $value ) {
if ( $value->id === "free_shipping" ) {
if ( $value->min_amount > 0 ) $min_amounts[] = $value->min_amount;
}
}
$delivery_zones = WC_Shipping_Zones::get_zones();
foreach ( $delivery_zones as $key => $delivery_zone ) {
foreach ( $delivery_zone['shipping_methods'] as $key => $value ) {
if ( $value->id === "free_shipping" ) {
if ( $value->min_amount > 0 ) $min_amounts[] = $value->min_amount;
}
}
}
if ( is_array($min_amounts) ) {
$min_amount = min($min_amounts);
$current = WC()->cart->subtotal;
if ( $current < $min_amount ) {
$shipping_text = esc_html__('You are ', 'woocommerce' ) . wc_price( $min_amount - $current ) . esc_html__(' away from FREE SHIPPING!', 'woocommerce' );
echo '<p class="delivery-message">' . $shipping_text . '</p>';
}
}
}
}
Any advice is highly appreciated.
Just inside the hook to display message check if cart empty
global $woocommerce;
if ( WC()->cart->get_cart_contents_count() != 0 ) {
// other codes here
}
I want woocommerce to display price in cart without tax, reduced by using a coupon.
I want to have:
price without tax
coupon value
price without tax reduced by coupon
tax
price with tax
Can anybody help me please?
I was trying to play wit this code:
add_action( 'woocommerce_cart_calculate_fees','new_customers_discount', 10, 1 );
function new_customers_discount( $wc_cart ) {
if ( is_admin() && ! defined('DOING_AJAX') ) // We exit
// Only for logged in users
if ($woocommerce->cart->applied_coupons) // We exit
// Only for new customers without orders
if ( wc_get_customer_order_count( get_current_user_id() ) != 10000 ) return; // We exit
// Calculation
$discount = $wc_cart->cart_contents_total - $coupon ;
$wc_cart->add_fee( __( 'Netto po rabacie', 'woocommerce')."", $discount);
echo '<div id="product-meta"><span class="detaliczna"><p class="item-description" style="text-align:center; font-size: 14px; display: none; ">' . $wc_cart->add_fee( __( 'TEST', 'woocommerce')."", -$discount ) . ' zł netto</p></span></div>';
but no luck. I am not a programmer. :)
I got it, but i want to change the order. I want to move the nett price on top of VAT
add_action( 'woocommerce_cart_totals_before_order_total', 'bbloomer_wc_discount_total_30', 10, 1 );
add_action( 'woocommerce_review_order_before_order_total', 'bbloomer_wc_discount_total_30', 10, 1 );
function bbloomer_wc_discount_total_30() {
global $woocommerce;
$discount_total = 0;
foreach ( $woocommerce->cart->get_cart() as $cart_item_key => $values) {
$_product = $values['data'];
if ( $_product->get_regular_price() ) {
$regular_price = $_product->get_regular_price();
$sale_price = $_product->get_sale_price();
$discount = ($regular_price - $coupon) ;
$discount_total += $discount;
}
}
if ( $discount_total > 0 ) {
echo '<tr class="cart-discount">
<th>'. __( 'Razem netto', 'woocommerce' ) .'</th>
<td data-title=" '. __( 'Razem netto', 'woocommerce' ) .' ">'
. wc_price( $discount_total - $woocommerce->cart->discount_cart ) .'</td>
</tr>';
}
}