Skip to content

Instantly share code, notes, and snippets.

@Micemade
Last active February 2, 2024 17:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Micemade/96c239b188a230552c2bfcfc9a350f7f to your computer and use it in GitHub Desktop.
Save Micemade/96c239b188a230552c2bfcfc9a350f7f to your computer and use it in GitHub Desktop.
WooCommerce display price with applied coupon(s) per item in cart
<?php
/**
* Woocommerce cart - display prices with coupons applied, per cart item.
*
* @param string $subtotal
* @param array $cart_item
* @param string $cart_item_key
* @return $subtotal
*
* Inspired by:
* @sourcecode https://businessbloomer.com/?p=21881
* @author Rodolfo Melogli
*/
function prefix_cart_item_coupon_subtotal( $subtotal, $cart_item, $cart_item_key ) {
$cart = WC()->cart;
$coupons = $cart->get_coupons();
// If no coupons, just go with subtotal.
if ( empty( $coupons ) ) {
return $subtotal;
}
// Set defaults.
$label = '';
$discounted_price = 0;
$amount_prev = 0;
$newsubtotal = '';
$iterator = 1;
$coupons_count = is_countable( $coupons ) ? count( $coupons ) : 0;
foreach ( $coupons as $coupon ) {
$data = $coupon->get_data();
$coupon_code = $data['code'];
$amount = $data['amount'];
$type = $data['discount_type'];
if ( $cart->has_discount( $coupon_code ) && $coupon->is_valid() ) {
$label = __( 'Coupon: ', 'textdomain' ) . $coupon_code;
// Sequentially apply coupons is applying next coupon to already disconted price, not original price.
$apply_seq = 'yes' === get_option( 'woocommerce_calc_discounts_sequentially', 'no' ) ? true : false;
// Price to be discounted - already discounted or original.
$price_to_discount = ( $apply_seq && $discounted_price ) ? $discounted_price : $cart_item['data']->get_price();
// Calculate the discount, depending on the discount type.
if ( 'percent' === $type ) {
$discounted_price = $price_to_discount - ( $price_to_discount * ( ( $amount + $amount_prev ) / 100 ) );
} elseif ( 'fixed_product' === $type ) {
$discounted_price = $price_to_discount - ( $amount + $amount_prev );
}
// Add the currency and html to new subtotal (after multiplied with quantity).
$wc_html_subtotal = wc_price( $discounted_price * $cart_item['quantity'] );
// New subtotal for each coupon discount and the final newsubtotal.
if ( $iterator < $coupons_count ) {
$newsubtotal .= sprintf( '<div class="discount"><small class="coupon-code">%s</small><s>%s</s></div>', $label, $wc_html_subtotal );
} else {
$newsubtotal .= sprintf( '<div class="discount"><small class="coupon-code">%s</small>%s</div>', $label, $wc_html_subtotal );
}
}
// If coupons not applied sequentially, apply all the coupons combined to the original price.
$amount_prev = ! $apply_seq ? $amount : 0;
$iterator++;
}
// Subtotal with new subtotal(s) added (applied coupons).
$subtotal = sprintf( '<s>%s</s> %s', $subtotal, $newsubtotal );
return $subtotal;
}
add_filter( 'woocommerce_cart_item_subtotal', 'prefix_cart_item_coupon_subtotal', 99, 3 );
/**
* Styles added inside head tag, for testing purposes.
* For live application, add these styles to your existing enqueued styles,
* or enqueue this separately (don't use wp_head hook).
*/
add_filter(
'wp_head',
function () {
?>
<style>
.woocommerce table.shop_table .product-subtotal s,
.woocommerce table.shop_table .product-total > s {
font-size: 0.95em;
font-weight: normal;
margin: 0px !important;
opacity: 0.7;
}
.woocommerce table.shop_table .product-subtotal s,
.woocommerce table.shop_table .product-subtotal > span,
.woocommerce table.shop_table .product-total s,
.woocommerce table.shop_table .product-total > span {
line-height: 1.4;
margin: 5px;
}
.woocommerce table.shop_table .product-subtotal > span,
.woocommerce table.shop_table .product-total > span {
font-weight: bold;
}
.discount {
position: relative;
display: block;
}
.discount > * {
display: inline-block;
}
.coupon-code {
padding: 1px 4px 0px;
border: 1px solid #ddd;
line-height: 1.5;
background: #fbf2e5;
margin-right: 4px;
text-transform: uppercase;
font-size: 9px;
font-weight: bold !important;
border-radius: 4px;
opacity: 0.8;
}
@media screen and (max-width: 480px) {
.coupon-code {
display: none;
}
}
</style>
<?php
}
);
@BeHelpfull
Copy link

BeHelpfull commented Jul 28, 2022

Hi!
Micemade.
Greetings for the day.
As I have used the above code it works fine. But there is a problem with the above code. It is not working properly on coupons created only for a specific product.
Suppose there is a product named 'Shirt'. I have created a coupon "SALE5" that will apply only to this product "Shirt". But when I add some other product along with this product 'Shirt' in the cart and use coupon "SALE5".As per your code, it appears applied on all products and the amount of coupon is reduced on all products in the cart appears. Whereas this coupon amount should appear as a deductible only on the product concerned for which it was created.

Please give me a solution to my concern.

Thanks & Regards.

@BeHelpfull
Copy link

Screenshot (1031)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment