Woocommerce coupon apply automatically on cart and checkout page - woocommerce

I need a coupon to be applied automatically when a product selects a custom field in it ( a checkbox as custom field) .If that checkbox is ticked in that product then woo commerce coupon should be applied automatically on cart and checkout page also well..I have written a custom code for it and its working fine .But if the checkbox is not selected and customer comes to checkout page - there is a default apply coupon code input box , if the customer puts the same coupon and apply's the coupon gets applied .But it shouldn't. The coupon was created on the back-end .
The code is :
add_action( 'woocommerce_before_checkout_form', 'apply_matched_coupons');
function apply_matched_coupons() {
$coupon_code = 'promo25';
if (WC()->cart->has_discount($coupon_code))
return;
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// this is your product ID
$autocoupon = array(968);
if (in_array($cart_item['product_id'], $autocoupon)) {
if (isset($cart_item[WCPA_CART_ITEM_KEY])) {
foreach ($cart_item[WCPA_CART_ITEM_KEY] as $field) {
if ($field['name'] == 'carpet-steam1') {
WC()->cart->add_discount($coupon_code);
wc_print_notices();
}
}
}
}
}
}
When promo25 is applied on checkout page, the coupon should not be applied.

Related

Disable Woocommerce Add to Cart button if cart is not empty

I am trying to hide the Add to Cart button and replace it with a message if the cart is not empty.
Reason: We can only process one order in the cart at a time, regardless of the product type.
Goal: If a customer has already added an item to the cart, they will not see the Add to Cart button on other items. But instead will see a message that states, "Before you can add another product to your cart, please complete your purchase that currently exists in your cart."
I have tested numerous conditional plugins, but none can provide a condition that checks if the cart is empty. I have also viewed various posts in this forum that discuss disabling the Add to Cart button under other conditions, but I have yet to see a code that can hide the Add to Cart button, replace it with a message, if the shopping cart is not empty.
Thanks!
You can achieve this by using a few custom functions.
First we'll make every product non purchasable when something exists in the cart.
add_filter( 'woocommerce_is_purchasable', 'products_no_purchasable_when_other_product_in_cart', 99, 1 );
function products_no_purchasable_when_other_product_in_cart( $is_purchasable ) {
if ( WC()->cart->get_cart_contents_count() > 0) {
$is_purchasable = false;
}
return $is_purchasable;
}
This function alone is enough to prevent users from adding more than one product in the cart. But they would still be able to see and click the "Add to cart" button.
The "Add to cart" button is typically seen in 2 places: on the product page and inside of the product loop, meaning archive pages, shop pages, related products etc.
When the button is displayed inside the loop, we can use filter and replace the the text and the url of the button. In the function below, we replace "Add to cart" text with a long message explaining why a customer can't buy the product and the url is linking to the checkout page.
// On WooCommerce shop and archives pages
add_filter( 'woocommerce_loop_add_to_cart_link', 'change_add_to_cart_button_in_a_loop', 10, 3 );
function change_add_to_cart_button_in_a_loop( $sprintf, $product, $args ) {
// When cart NOT empty
if ( WC()->cart->get_cart_contents_count() > 0 ) {
$button_text = 'Before you can add another product to your cart, please complete your purchase that currently exists in your cart.';
// Button URL
$new_button_url = wc_get_page_permalink( 'checkout' );
// New link + text
$sprintf = sprintf(
'%s',
esc_url( $new_button_url ),
esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ),
esc_html( $button_text )
);
}
return $sprintf;
}
On the product page, the button will be removed automatically when the product is not purchasable and we are making sure it's not purchasable in the first code snippet. Now we only have to fill the void with some message explaining why the "Add to cart" button is not there. We do it using woocommerce_single_product_summary hook. You can use any other hook on the product page to move this message around.
add_action( 'woocommerce_single_product_summary', 'message_when_other_product_already_in_cart', 10 );
function message_when_other_product_already_in_cart() {
if ( WC()->cart->get_cart_contents_count() > 0) {
$message = 'Before you can add another product to your cart, please complete your purchase that currently exists in your cart.';
echo '<p>'.$message.'</p>';
}
}
And finally, most themes will have ajax "add to cart" buttons. This means the page is not reloaded after you add or remove a product from the cart. For example, you are on the shop page and add one product in the cart. The buttons on other products will still be visible. Or when you open a small cart in the header and remove the product from the cart, the shop/product page won't enable "add to cart" buttons automatically.
That's why we add a simple javasctipt that will reload the page when added_to_cart or removed_from_cart javascript events are triggered. We add this code only to WooCommerce pages.
add_action( 'wp_footer', 'custom_footer_scripts' );
function custom_footer_scripts() {
if ( is_woocommerce() ) {
?>
<script>
jQuery( document.body ).on( 'added_to_cart', function() {
window.location = window.location.href;
});
jQuery( document.body ).on( 'removed_from_cart', function() {
window.location = window.location.href;
});
</script>
<?php
}
}
I tested this on the Storefront theme and with WooCommerce 7.2.2

Change Buy button for variants in backorder Woocommerce

Dears,
The following code works ok to change the Add to Cart text on single products when it is on Backorder enabled.
add_filter( 'woocommerce_product_single_add_to_cart_text', 'change_add_to_cart_single_prod', 10, 2 );
function change_add_to_cart_single_prod( $text, $product ){
if ( $product->is_on_backorder( 1 ) ) {
return __( 'Reservar', 'woocommerce' );
}
return __( 'Comprar', 'woocommerce' );
}
But it does not work with variations unless the every variation is in backorders or out of stock. What may be the best way to change the Add to Cart button to a variations with Backorders allowed?
I am guessing it has to be done with js.
When a product variation is selected, a hidden input field is set in the variation form with the id of the selected product variation. For example:
<input type="hidden" name="variation_id" class="variation_id" value="44">
If the selected attributes do not match any product variation, the
value will be blank.
All possible product variations are in the data-product_variations attribute of the variation form element.
Then you can use this jQuery script to change the button name. It will be Reservar if the product variation allows backorders while Comprar if it does not.
// change the text of the add to cart button based on product backorders
add_action( 'wp_footer', 'change_the_text_of_the_add_to_cart_button' );
function change_the_text_of_the_add_to_cart_button() {
?>
<script type="text/javascript">
jQuery(function($){
$('input[name=variation_id].variation_id').change(function(){
const variationID = $(this).val();
const variationData = $('form.variations_form').data("product_variations");
$(variationData).each(function(index,variation){
if ( variationID == variation.variation_id ) {
if ( variation.backorders_allowed ) {
$('form.variations_form button[type=submit]').text('Reservar');
} else {
$('form.variations_form button[type=submit]').text('Comprar');
}
}
});
});
});
</script>
<?php
}
The code has been tested and works. Add it to your active theme's functions.php.

Programmatically Hide Woocommerce Product

I want to conditionally hide a group of Woocommerce products on a category page depending on the current shopping cart contents. I have a category called boxes with four products. Two of them are also in the cardboard category and two are in the plastic category.
If product with ID 23 is in the cart already, I want to show plastic boxes. If it isn't, I want to hide them. I know how to check the cart contents, but once I have that answer, how do I hide products from the plastic category from that page?
add_action( 'woocommerce_before_shop_loop', 'my_before_shop_loop' );
function my_before_shop_loop() {
global $woocommerce;
$flag = 0;
foreach($woocommerce->cart->get_cart() as $key => $val ) {
$_product = $val['data'];
if ($_product->id == '23') {
$flag = 1;
}
}
if ($flag == 0) {
// hide products that are in the plastic category
// this is where I need help
}
}
The hook which you are using right now, is triggerred after products are fetch from database. You can filter the products from the query itself. In below code, you can pass products which you want to hide on front end.
function custom_pre_get_posts_query( $q ) {
// Do your cart logic here
// Get ids of products which you want to hide
$array_of_product_id = array();
$q->set( 'post__not_in', $array_of_product_id );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );

Woocommerce Hook for Custom Behaviour for Place Order

I wonder if there's a hook for changing Place Order Button behaviour upon click. I am trying to replace/change a product upon placing order as the product selection (all available products) are also in the Checkout Page.
So far I have been trying to manipulate woocommerce_checkout_order_review hook & failed.
add_action('woocommerce_checkout_order_review', 'remove_woocommerce_product');
function remove_woocommerce_product(){
if (isset($_POST['woocommerce_checkout_place_order'])){
global $woocommerce;
$woocommerce->cart->empty_cart(); // Empty the cart
$selectedproduct = $_POST['selectedproductid']; // Get the selected product
WC()->cart->add_to_cart( $selectedproduct ); // Insert the selected product in the the cart
return esc_url( wc_get_checkout_url() ); // Redirect to Payment Gateway Page
}
}
The hook above is not triggered upon Place Order. Maybe there's something wrong with my code or maybe what I suspected is wrong hook applied. Any ideas?
Nevermind... found the answer...
add_action('woocommerce_checkout_process', 'change_product_upon_submission');
function change_product_upon_submission() {
if ( !empty( $_POST['_wpnonce'] ) && !empty($_POST['selectedproductid']) ) {
$selectedproduct = $_POST['selectedproductid']; // Get the selected product
WC()->cart->empty_cart(); //Empty the cart
WC()->cart->add_to_cart( $selectedproduct ); // Insert the selected product in the cart
}
}
For more explanation, see Woocommerce Replace Product in Cart Upon Place Order in Checkout Page

Woocommerce customize the product name in the cart and order pages

Actually, I already got hook to customize the price in the cart page and all other page.
This is the hook to customize the product price
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 10; // This will be your custome price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
Actually, I am using woocommerce plugin. I want a hook to customize the product name displayed in the cart page and all other pages next to cart page.
I want to customize the Product name , i want to add the some static attributes to product name displayed in the cart page, order page ,order details page and all the pages next to cart page.
Thanks in advance
I wanted to share this as I managed to figure out something for my needs. (I only ever have a single item in the order as I've customised WooCommerce for holiday bookings.)
<?php
add_action( 'woocommerce_product_title', 'add_custom_name' );
function add_custom_name( $title ) {
return 'test name';
}
?>
Hopefully someone can elaborate on this further or take what has been done with the custom price code an properly re-purpose it for product names.

Resources