Managing conditional coupons and additional fees on cart/checkout Woocommerce - woocommerce

I am having problems in managing contemporarly disocunt coupons and custom additional fields on the cart and checkout page.
I created a function that adds a discount only if a product is present in the cart with more than a variation and the discount is applied only on the second (or third) variation, NOT on the first one. You can find my final code here Woocommerce conditional part cart discount on the same product present with > 1 variation
However I had to go further on, as I have a particular tricky situation. Normally the condition described above cannot be applied when other discounts are in the cart (i.e. standard discount coupons). I hence added these two lines just after getting the cart
$has_coupons = count(WC()->cart->applied_coupons)>0?true:false;
if(!$has_coupons) {
//here goes the function that I did
} else return;
Everything is fine, and it works. However there is a particular situation in which I have to apply a coupon to the cart (not %) that detracts to teh whole cart a specific amount. This particular coupon CAN go with the discount created in the function I wrote!
/* get coupon code*/
function get_coupon_code() {
global $woocommerce;
if ( !empty( $woocommerce->cart->applied_coupons ) ) {
$my_coupon_code = $woocommerce->cart->get_coupons() ;
foreach($my_coupon_code as $coupon){
if ( $post = get_post( $coupon->id ) ) {
$coupon_code= $coupon->code;
}
}
}
return $coupon_code;
}
/* get coupon amount*/
function get_coupon_amount() {
global $woocommerce;
if ( ! empty( $woocommerce->cart->applied_coupons ) ) {
$my_coupon_amount = $woocommerce->cart->get_coupons() ;
foreach($my_coupon_amount as $coupon){
$coupon_amount =$coupon->coupon_amount;
}
}
return $coupon_amount;
}
function cart_discount() {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
global $woocommerce;
//get the code and amount of the coupon applied
$coupon_code = get_coupon_code();
$coupon_amount = get_coupon_amount();
//check if the code corresponds to the coupon exception I want to accept
if ($coupon_code == 'wa-1'){
//if it is the code I need to apply, then I remove it from the cart
WC()->cart->remove_coupon($coupon_code);
//I use the amount to add it as additional fee at negative
$coupon_discount = -($coupon_amount);
//I add the ex-coupon amount to an additional field
$discount_agency_text = __( 'Detracted agency fee', 'woocommerce' );
WC()->cart->add_fee( $discount_agency_text, $coupon_discount, false );
}
//and following the function previously mentioned
$cart = WC()->cart->get_cart();
$has_coupons = count(WC()->cart->applied_coupons)>0?true:false;
//check if there are other coupons or if the coupon applied are the case I want to pass through my function
if(!$has_coupons || $coupon == 'wa-1') {
//here follows the strings to apply a 10% discount on the second (third) variation of the product and not on the first one
foreach($cart as $cart_item_key => $values) {
$product_id = $values['product_id']; // product ID
$variation_id = $values['variation_id']; // product quantity
$cart_lines_total = $values["line_total"];
$cart_lines_quantity = $values["quantity"];
//product id to be considered for this discount
//$product = 1394 = Spedizioni CSR eng
//$product = 1389 = Spedizioni IDP eng
//$product = 13888 = Spedizioni CSR ita
//$product = 13910 = Spedizioni IDP ita
if($product_id == '1394' || $product_id == '1389' || $product_id == '13888' || $product_id == '13910')
{
$cart_array []= array( $product_id , $variation_id, $cart_lines_quantity, $cart_lines_total);
}
}
$conteggio = count($cart_array); //counts the number of items in teh cart
// percent is 5%
$percent = -0.10;
if ($conteggio < 3 && $cart_array[0][0] == $cart_array[1][0])
{
$discount = $percent * $cart_array[1][3];
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
if ($conteggio < 4 && $cart_array[0][0] == $cart_array[1][0] && $cart_array[0][0] == $cart_array[2][0])
{
$discount = ($percent * $cart_array[1][3]) + ($percent * $cart_array[2][3]);
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
if ($conteggio < 5 && $cart_array[0][0] == $cart_array[1][0] && $cart_array[0][0] == $cart_array[2][0] && $cart_array[0][0] == $cart_array[3][0])
{
$discount = ($percent * $cart_array[1][3]) + ($percent * $cart_array[2][3]) + ($percent * $cart_array[3][3]);
$discount_text = __( '10% discount on subsequent week(s)', 'woocommerce' );
WC()->cart->add_fee( $discount_text, $discount, false );
}
} else return;
}
add_action( 'woocommerce_cart_calculate_fees','cart_discount' );
The problem I have is that part concernign the management of teh discount coupon doesn't work. It gets the $coupon_code and $coupon_amount, but doesn't add it to the additional fields section.
Anybody can help me please?

Nicely presented !
This plugin may solve the problem easy, it allows you to charge extra fees in cart, based on the combination of multiple conditional rules that you configure in your woocommerce store.
I hope it may help!
WooCommerce Conditional Product Fees For Checkout

I am still stuck on the argument but I try now to make it simpler.
I can actually simply use a coupon discount that works together with my function (which, in case I have a product with > then a variation, it adds 10% discount only the following variation and not on the first one).
The problem is that if I use a coupon (=80€) applied on the cart, it anyway spread over the various items and the 10% discount is calculated on a lower price (not on the regular price).
My problem would be solved if I can apply the coupon on the final cart total, instead of being spread over the single items. Is that possible?
Just to give you an example, my $cart_array before applying the coupon is
Array
(
[0] => Array
(
[0] => 1394 //product_id
[1] => 1851 //variation_id
[2] => 1 //quantity
[3] => 906 //regular price
)
[1] => Array
(
[0] => 1394 //product_id
[1] => 1852 //variation_id
[2] => 1 //quantity
[3] => 906 //regular price
)
)
If at this point I apply the coupon, the array changes in:
Array
(
[0] => Array
(
[0] => 1394
[1] => 1851
[2] => 1
[3] => 866 //price after coupon
)
[1] => Array
(
[0] => 1394
[1] => 1852
[2] => 1
[3] => 866 //price after coupon
)
)
As you see the second item is no more 906 but 866 and thus the 10% discount is less.
Is there a way to apply the coupon only to the first item of the array? Or apply it at the final total (after the additional fee has been calculated)?

Related

Request - How to add Handling Fee based on Category of Product? [duplicate]

I already found this code here and it works for like 80/90% for me (see below).
This code adds 60 euro to my cart when there is a product from category ID 349 in the cart. When I add a product from that category to my cart when the cart is empty it works fine. But when there is already a product in my cart from a different category and then I add the product with category 349 it doesn't add the 60 euro extra fee. How is this possible?
function woo_add_cart_fee() {
$category_ID = '349';
global $woocommerce;
foreach ($woocommerce->cart->cart_contents as $key => $values ) {
// Get the terms, i.e. category list using the ID of the product
$terms = get_the_terms( $values['product_id'], 'product_cat' );
// Because a product can have multiple categories, we need to iterate through the list of the products category for a match
foreach ($terms as $term) {
// 349 is the ID of the category for which we want to remove the payment gateway
if($term->term_id == $category_ID){
$excost = 60;
}
}
$woocommerce->cart->add_fee('Extra bezorgkosten kunstgras', $excost, $taxable = false, $tax_class = '');
}
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
The code you are using is a bit outdated and you should use has_term() Wordpress conditional function to target a product category this way:
add_action( 'woocommerce_cart_calculate_fees','custom_pcat_fee', 20, 1 );
function custom_pcat_fee( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
// Set HERE your categories (can be term IDs, slugs or names) in a coma separated array
$categories = array('349');
$fee_amount = 0;
// Loop through cart items
foreach( $cart->get_cart() as $cart_item ){
if( has_term( $categories, 'product_cat', $cart_item['product_id']) )
$fee_amount = 60;
}
// Adding the fee
if ( $fee_amount > 0 ){
// Last argument is related to enable tax (true or false)
WC()->cart->add_fee( __( "Extra bezorgkosten kunstgras", "woocommerce" ), $fee_amount, false );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
A fee of 60 will always be added if there is in cart an item from 349 product category ID.
I found a solution like the following. Note that I kept adding a fee, because I started from a previous snippet. You can apply an existing discount or calculate a different total according to your needs.
In this case, I apply a negative fee - like a discount - according to a >= 300 total value of the cart, whose values would be -25% only for local_pickup shipping method, calculating taxes in addition.
function discount_to_cat(){
// thanks to LoicTheAztec's snippet
$cat_in_cart = false;
// Loop through all products in the Cart
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( has_term( 'category_to_pick', 'product_cat', $cart_item['product_id'] ) ) {
$cat_in_cart = true;
$tot_category_price = $cart_item['data']->get_price();
$tot_category_qty = $cart_item['quantity'];
$tot_category = $tot_category_price * $tot_category_qty;
break;
}
} global $product;
$total = WC()->cart->subtotal;
$discount_label = "";
if($total >= 300){
$discount_label=15;
}
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = explode(':',$chosen_methods[0]);
if($chosen_shipping[0]=='local_pickup'){
$discount_label=25;
}
$discount_applied = ($total-$tot_category)*$discount_label/100;
if($discount_label!=""){
$discount_applied_net = ($discount_applied/1.1); //1.1 according taxes for shipping
WC()->cart->add_fee( "Discount applied: ($discount_label%)", -$discount_applied_net, false );
}
}
add_action( 'woocommerce_cart_calculate_fees','discount_to_cat' );

Prevent WooCommerce checkout if minimum quantity for a category is not reached unless another category is added

I am doing a check in the cart to apply a rule that if a item from the chilled category is added, a minimum of 3 chilled category items are required to check out. - This works.
However, if an item from the bundles category is also added, then the above chilled rule should not be enforced.
e.g. Minimum of 3 chilled category items required, unless a bundle item is in the cart, in which case, disregard the chilled rule.
I have the minimum 3 chilled rule working, but I can't get the code to exclude this rule if a item from the bundles category is detected?
Based on Prevent WooCommerce checkout if minimum quantity for a specific category is not reached answer code, this is my attempt:
function action_woocommerce_check_cart_items() {
// Only run on the cart or checkout pages
if ( is_cart() || is_checkout() ) {
// Minimum
$minimum = 3;
// Category
$category = 'chilled';
$category2 = 'bundles';
// Initialize
$total = 0;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Product id
$product_id = $cart_item['product_id'];
// Has certain category
if ( has_term( $category, 'product_cat', $product_id ) ) {
// Add to total
$total += $cart_item['quantity'];
}elseif (has_term ($category2, 'product_cat', $product_id)) {
break;
}
}
// When total is greater than 0 but less than the minimum
if ( $total > 0 && $total < $minimum ) {
// Notice
wc_add_notice( sprintf( __( '<strong>A minimum of %s products are required from the CHILLED category before checking out.</strong>', 'woocommerce' ), $minimum ), 'error' );
// Optional: remove proceed to checkout button
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
}
}
add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );
End the execution in the current loop will not suffice, you also need to add an extra rule to the if condition.
So you get:
function action_woocommerce_check_cart_items() {
// Only run on the cart or checkout pages
if ( is_cart() || is_checkout() ) {
// Minimum
$minimum = 3;
// Category
$category = 'chilled';
$category_2 = 'bundles';
// Initialize
$total = 0;
$flag = true;
// Loop through cart items
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
// Product id
$product_id = $cart_item['product_id'];
// Has certain category
if ( has_term( $category, 'product_cat', $product_id ) ) {
// Add to total
$total += $cart_item['quantity'];
// Has other category
} elseif ( has_term( $category_2, 'product_cat', $product_id ) ) {
// Break loop
$flag = false;
break;
}
}
// When total is greater than 0 but less than the minimum & flag is still true
if ( ( $total > 0 && $total < $minimum ) && $flag ) {
// Notice
wc_add_notice( sprintf( __( 'A minimum of %s products are required from the %s category before checking out.', 'woocommerce' ), $minimum, $category ), 'error' );
// Optional: remove proceed to checkout button
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
}
}
}
add_action( 'woocommerce_check_cart_items' , 'action_woocommerce_check_cart_items', 10, 0 );

Edit WooCommerce Prices Programmatically for ALL products [duplicate]

I have created a product on WooCommerce, and added two options on product detail page using the hook woocommerce_before_add_to_cart_button. Now when customers add product to cart from product detail page they have two options their. They can choose one option from these two options.
Then I have stored the user selected value in cart meta using the woocommerce hook woocommerce_add_cart_item_data.
I am using the code from this answer: Save product custom field radio button value in cart and display it on Cart page
This is my code:
// single Product Page options
add_action("woocommerce_before_add_to_cart_button", "options_on_single_product");
function options_on_single_product(){
$dp_product_id = get_the_ID();
$product_url = get_permalink($dp_product_id);
?>
<input type="radio" name="custom_options" checked="checked" value="option1"> option1<br />
<input type="radio" name="custom_options" value="option2"> option2
<?php
}
//Store the custom field
add_filter( 'woocommerce_add_cart_item_data', 'save_custom_data_with_add_to_cart', 10, 2 );
function save_custom_data_with_add_to_cart( $cart_item_meta, $product_id ) {
global $woocommerce;
$cart_item_meta['custom_options'] = $_POST['custom_options'];
return $cart_item_meta;
}
And this is what I have tried:
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price', 10, 1);
function add_custom_price( $cart_obj ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart_obj->get_cart() as $key => $value ) {
$product_id = $value['product_id'];
$custom_options = $value['custom_options'];
$coupon_code = $value['coupon_code'];
if($custom_options == 'option2')
{
if($coupon_code !='')
{
global $woocommerce;
if ( WC()->cart->has_discount( $coupon_code ) ) return;
(WC()->cart->add_discount( $coupon_code ))
//code for second discount
}
else{
$percentage = get_post_meta( $product_id , 'percentage', true );
//print_r($value);
$old_price = $value['data']->regular_price;
$new_price = ($percentage / 100) * $old_price;
$value['data']->set_price( $new_price );
}
}
}
}
Now what I am trying to get with that last snippet is:
If Option1 is selected by the customer then woocommerce regular process is run.
If Option2 is selected then firstly coupon code applied to cart (if code entered by the customer) and then the price is divide by some percentage (stored in product meta) is applied afterward.
But it’s not working as expected because the changed product price is maid before and coupon discount is applied after on this changed price.
What I would like is that the coupon discount will be applied first on the product regular price and then after change this price with my custom product discount.
Is this possible? How can I achieve that?
Thanks.
This is not really possible … Why? … Because (the logic):
You have the product price
Then the coupon discount is applied to that price (afterwards)
==> if you change the product price, the coupon is will be applied to that changed price
What you can do instead:
You don't change product price
if entered the coupon is applied and …
If "option2" product is added to cart:
Apply a custom discount (a negative fee) based on the product price added after using WC_cart add_fee() method…
For this last case you will have to fine tune your additional discount.
If the coupon has not been applied or it's removed there is no additional discount.
Your custom function will be hooked in woocommerce_cart_calculate_fees action hook instead:
add_action( 'woocommerce_cart_calculate_fees', 'option2_additional_discount', 10, 1 );
function option2_additional_discount( $cart_obj ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
$discount = 0;
$applied_coupons = $cart_obj->get_applied_coupons();
foreach ( $cart_obj->get_cart() as $item_values ) {
if( 'option2' == $item_values['custom_options'] && !empty($applied_coupons) ){
$product_id = $item_values['product_id'];
$percentage = get_post_meta( $product_id , 'percentage', true );
$quantity = $item_values['quantity'];
$product_reg_price = $item_values['data']->regular_price;
$line_total = $item_values['line_total'];
$line_subtotal = $item_values['line_subtotal'];
$percentage = 90;
## ----- CALCULATIONS (To Fine tune) ----- ##
$item_discounted_price = ($percentage / 100) * $product_reg_price * $item_values['quantity'];
// Or Besed on line item subtotal
$discounted_price = ($percentage / 100) * $line_subtotal;
$discount += $product_reg_price - $item_discounted_price;
}
}
if($discount != 0)
$cart_obj->add_fee( __( 'Option2 discount', 'woocommerce' ) , - $discount );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.
Adding a negative fee using the WC_Cart->add_fee() method wasn't working for me. When i check the WC Cart class, it even states you are not allowed to use a negative ammount.
See the docs.
I did the following:
create a placeholder coupon with a 'secure' code, e.g. custom_discount_fjgndfl28. Set a discount ammount of 0, so when somebody (somehow) uses this coupon outside your program the discount is still 0.
Use filter woocommerce_get_shop_coupon_data, and set all the coupon data you want for that coupon/session.
Hook into woocommerce_before_calculate_totals and set your custom coupon to the cart.
At this point the Cart should calculate everything correctly. And when it becomes an order, it also has the correct discount ammount.
Note: the coupon code is also used as a label in some templates. Use filter woocommerce_cart_totals_coupon_label to change it.
Example functions:
/**
* NOTE: All the hooks and filters below have to be called from your own
* does_it_need_custom_discount() function. I used the 'wp' hook for mine.
* Do not copy/paste this to your functions.php.
**/
add_filter('woocommerce_get_shop_coupon_data', 'addVirtualCoupon', 10, 2);
function addVirtualCoupon($unknown_param, $curr_coupon_code) {
if($curr_coupon_code == 'custom_discount_fjgndfl28') {
// possible types are: 'fixed_cart', 'percent', 'fixed_product' or 'percent_product.
$discount_type = 'fixed_cart';
// how you calculate the ammount and where you get the data from is totally up to you.
$amount = $get_or_calculate_the_coupon_ammount;
if(!$discount_type || !$amount) return false;
$coupon = array(
'id' => 9999999999 . rand(2,9),
'amount' => $amount,
'individual_use' => false,
'product_ids' => array(),
'exclude_product_ids' => array(),
'usage_limit' => '',
'usage_limit_per_user' => '',
'limit_usage_to_x_items' => '',
'usage_count' => '',
'expiry_date' => '',
'apply_before_tax' => 'yes',
'free_shipping' => false,
'product_categories' => array(),
'exclude_product_categories' => array(),
'exclude_sale_items' => false,
'minimum_amount' => '',
'maximum_amount' => '',
'customer_email' => '',
'discount_type' => $discount_type,
);
return $coupon;
}
}
add_action('woocommerce_before_calculate_totals', 'applyFakeCoupons');
function applyFakeCoupons() {
global $woocommerce;
// $woocommerce->cart->remove_coupons(); remove existing coupons if needed.
$woocommerce->cart->applied_coupons[] = $this->coupon_code;
}
add_filter( 'woocommerce_cart_totals_coupon_label', 'cart_totals_coupon_label', 100, 2 );
function cart_totals_coupon_label($label, $coupon) {
if($coupon) {
$code = $coupon->get_code();
if($code == 'custom_discount_fjgndfl28') {
return 'Your custom coupon label';
}
}
return $label;
}
Please Note: i copied these functions out of a class that handles much more, it's only to help you get going.

Woocommerce - Calcutlate Shipping cost on total amount of order, but without coupon

first of all I am not a pro developer and for a customer we have the following request.
Currently, in Woocommerce the shipping cost is calcutlated on basis of the total order amount ([fee percent="8"]) --> 8% of the order amount.
The customer wants now that if a coupon is applied the shipping cost should be calculated on the basis of the original amount NOT the new total amount with the coupon amount.
Any idea to resolve that smoothly ?
Thanks !
Julian
You need to use woocommerce_package_rates filter hook in which get total cart amount except coupon amount and changes shiiping cost for each shipping rates in loop. Let me know if you getting any issue.
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 10, 2 );
function custom_shipping_costs( $rates, $package ) {
$carttotal = WC()->cart->get_cart_subtotal();
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
$taxes[$key] = $carttotal * 0.08;
}
}
$rates[$rate_key]->taxes = $taxes;
}
Here are my solutions:
1.
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
global $woocommerce;
if (!empty(WC()->cart->applied_coupons)){
$totalfees = WC()->cart->get_fees(); //$order->get_total_fees();
$producttotal = WC()->cart->subtotal; // $order->get_subtotal();
$total = (float)$totalfees + (float)$producttotal;
// New shipping cost (can be calculated)
$new_cost = $total * .08;
$tax_rate = array();
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( $rate->method_id != 'free_shipping'){
// Set rate cost
$rates[$rate_key]->cost = $new_cost;
// Set taxes rate cost (if enabled)
$taxes = array();
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 )
$taxes[$key] = $new_cost * $tax_rate;
}
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
}
if(!empty( $order->get_used_coupons() )) {
$totalfees = $order->get_total_fees();
$producttotal = $order->get_subtotal();
$total = (float)$totalfees + (float)$producttotal;
// Get the customer country code
$country_code = $order->get_shipping_country();
// Set the array for tax calculations
$calculate_tax_for = array(
'country' => $country_code,
'state' => '', // Can be set (optional)
'postcode' => '', // Can be set (optional)
'city' => '', // Can be set (optional)
);
// Optionally, set a total shipping amount
$new_ship_price = $total * .08;
// Get a new instance of the WC_Order_Item_Shipping Object
$item = new WC_Order_Item_Shipping();
$item->set_method_title( "Flat rate" );
$item->set_method_id( "flat_rate:14" ); // set an existing Shipping method rate ID
$item->set_total( $new_ship_price ); // (optional)
$item->calculate_taxes($calculate_tax_for);
$order->add_item( $item );
$order->calculate_totals();
$order->update_status('on-hold');
// $order->save(); // If you don't update the order status
}
Resources 1 , 2, 3, 4

Woocommerce : programmatically set a discount for the first item ordered, but inventory based

I'm building a website where i'll sell some fine art prints and i would like to set an automated discount when a customer buy the first print of a serie. Each of my prints are limited to 15 pieces and i would like to set a 30% discount for the first sell (#1/15) of each series. Then, for the next prints (#2 to #15), price goes back to normal.
Edit :
I did progress on my problem ! I did some research and tried a lot of different things and i found how to set the custom price i wanted on my product page (regular price + discount price) with the rule to only apply it if the related item available stock is 15.
regular price + discount price
And here's the code is used :
// Generating the product "regular price"
add_filter( 'woocommerce_product_get_regular_price', 'dynamic_regular_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_regular_price', 'dynamic_regular_price', 10, 2 );
function dynamic_regular_price( $regular_price, $product ) {
$stock_qte = $product->get_stock_quantity();
if( empty($regular_price) || $regular_price == 0 )
return $product->get_price();
else
return $regular_price;
}
// Generating the product "sale price"
add_filter( 'woocommerce_product_get_sale_price', 'dynamic_sale_price', 10, 2 );
add_filter( 'woocommerce_product_variation_get_sale_price', 'dynamic_sale_price', 10, 2 );
function dynamic_sale_price( $sale_price, $product ) {
$stock_qte = $product->get_stock_quantity();
if( $stock_qte == '15')
return $product-> get_regular_price() * 0.7;
else
//return $product->get_regular_price();
return $regular_price;
};
// Displayed formatted regular price + sale price
add_filter( 'woocommerce_get_price_html', 'dynamic_sale_price_html', 20, 2 );
function dynamic_sale_price_html( $price_html, $product ) {
$stock_qte = $product->get_stock_quantity();
if( $stock_qte == '15')
$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), wc_get_price_to_display( $product, array( 'price' => $product->get_sale_price() ) ) ) . $product->get_price_suffix();
else
$price_html = wc_price(wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ). $product->get_price_suffix());
return $price_html;
}
It's almost working but the code related to the cart values updates is not fully working. The cart sub-total is good and take count of the discount but the individual price of each product is not updated and shown as without discount. It's the same on the cart page.
cart (from mini cart)
cart (cart page)
add_action( 'woocommerce_before_calculate_totals', 'alter_price_cart', 9999 );
function alter_price_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ) return;
// IF CUSTOMER NOT LOGGED IN, DONT APPLY DISCOUNT
//if ( ! wc_current_user_has_role( 'customer' ) ) return;
// LOOP THROUGH CART ITEMS & APPLY 30% DISCOUNT
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data'];
$price = $product->get_price();
$cart_item['data']->set_price( $price * 0.7 );
}
}
I'll also have to add the stock availability logic for the mini-cart / cart / checkout page but i'll do that in a second time.
I must have made some mistakes in the loop throught the cart but i cannot catch the issue :( Any idea about how to hook the price of each product and change the displayed value ?
Have a nice day,
Quentin

Resources