问题描述
我需要一些帮助来将自定义运费与 WooCommerce 中的购物车商品折扣价格结合起来.
I need some help to combine custom shipping cost with discounted cart item prices in WooCommerce.
在下面的代码中,第一个函数负责根据选择的交付选项添加 50% 的折扣和第二个负责计算篮子中每件商品的 50% 折扣,特定类别(及其子类别)除外.
In the below code, the first function is responsible for adding a 50% discount depending on the selected delivery option andthe 2nd one is responsible for calculating a 50% discount for each item in the basket, except for specific category (and its subcategories).
我想确定客户何时选择自取"交付显示-50%"仅针对未包含在特定类别及其子类别中的商品添加的折扣(对于主类别 ID 37
).
I would like to make sure when a customer chooses "Pickup" delivery to display "-50%" of discount that is added only for goods not included in specific category and its subcategories (for main category ID 37
).
第一个函数:
add_filter('woocommerce_package_rates', 'local_pickup_percentage_discount', 12, 2);
function local_pickup_percentage_discount( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
// HERE define the discount percentage
$percentage = 50; // 50%
$subtotal = WC()->cart->get_subtotal();
// Loop through the shipping taxes array
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false;
// Targeting "Local pickup"
if( 'local_pickup' === $rate->method_id ){
// Add the Percentage to the label name (optional
$rates[$rate_key]->label .= ' ( - ' . $percentage . '% )';
// Get the initial cost
$initial_cost = $new_cost = $rates[$rate_key]->cost;
// Calculate new cost
$new_cost = -$subtotal * $percentage / 100;
// Set the new cost
$rates[$rate_key]->cost = $new_cost;
// Taxes rate cost (if enabled)
$taxes = [];
// Loop through the shipping taxes array (as they can be many)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
// Get the initial tax cost
$initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key];
// Get the tax rate conversion
$tax_rate = $initial_tax_cost / $initial_cost;
// Set the new tax cost
$taxes[$key] = $new_cost * $tax_rate;
$has_taxes = true; // Enabling tax
}
}
if( $has_taxes )
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
第二个:
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 10, 1 );
function custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$parent_id = 37; // premium-rolls id
$taxonomy = 'product_cat';
foreach ( $cart->get_cart() as $cart_item ){
$product_id = $cart_item['product_id'];
$terms_ids = get_term_children( $parent_id, $taxonomy, $product_id ); // get children terms ids array
array_unshift( $terms_ids, $parent_id ); // insert parent term id to children terms ids array
if ( ! has_term( $terms_ids, $taxonomy, $product_id ) ){
$new_price = $cart_item['data']->get_price() / 2; // Get 50% of the initial product price
$cart_item['data']->set_price( $new_price ); // Set the new price
}
}
}
推荐答案
这是使其适用于购物车项目和特定运输方式的方法,不包括产品类别及其子类别(代码已注释):
Here is the way to make it work for cart items and specific shipping method excluding a product category and its subcategories (code is commented):
// Custom conditional function that check cart items for specific category and its children terms ids
function has_targeted_terms( $cart_item ){
$parent_id = 37; // <= Targeted main product category
$taxonomy = 'product_cat';
$terms_ids = get_term_children( $parent_id, $taxonomy, $cart_item['product_id'] ); // get children terms ids array
array_unshift( $terms_ids, $parent_id ); // insert parent term id to children terms ids array
return has_term( $terms_ids, $taxonomy, $cart_item['product_id'] );
}
// For shipping rate costs (discount)
add_filter('woocommerce_package_rates', 'local_pickup_percentage_discount', 12, 2);
function local_pickup_percentage_discount( $rates, $package ){
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return $rates;
$percentage = 50; // <= The percentage discount
$shipping_method = 'local_pickup'; // <= Targeted shipping method id
$subtotal = WC()->cart->get_subtotal();
$others_found = false; // Initializing
// Loop through cart items for the current package
foreach( $package['contents'] as $cart_item ) {
if ( ! has_targeted_terms( $cart_item ) ) {
$others_found = true;
break; // stop the loop
}
}
// Loop through the shipping methods
foreach ( $rates as $rate_key => $rate ){
$has_taxes = false; // Initializing
// Targeting "Local pickup"
if( $shipping_method === $rate->method_id && $others_found ){
// Add the Percentage to the label name (optional
$rates[$rate_key]->label .= ' ( - ' . $percentage . '% )';
// Get the initial cost
$initial_cost = $new_cost = $rates[$rate_key]->cost;
// Calculate new cost
$new_cost = -$subtotal * $percentage / 100;
// Set the new cost
$rates[$rate_key]->cost = $new_cost;
// Taxes rate cost (if enabled)
$taxes = [];
// Loop through the shipping taxes array (as they can be many)
foreach ($rates[$rate_key]->taxes as $key => $tax){
if( $rates[$rate_key]->taxes[$key] > 0 ){
// Get the initial tax cost
$initial_tax_cost = $new_tax_cost = $rates[$rate_key]->taxes[$key];
// Get the tax rate conversion
$tax_rate = $initial_tax_cost / $initial_cost;
// Set the new tax cost
$taxes[$key] = $new_cost * $tax_rate;
$has_taxes = true; // Enabling tax
}
}
if( $has_taxes )
$rates[$rate_key]->taxes = $taxes;
}
}
return $rates;
}
// For cart items price discount
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 10, 1 );
function custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( did_action( 'woocommerce_before_calculate_totals' ) >= 2 )
return;
$shipping_method = 'local_pickup'; // <= Targeted shipping method id
$is_local_pickup = false;
// Loop through chosen shipping methods
foreach ( WC()->session->get('chosen_shipping_methods') as $chosen_shipping_method ){
if( strpos( $chosen_shipping_method, $shipping_method ) !== false ) {
$is_local_pickup = true;
break;
}
}
// If "Local pickup" is not the chosen shipping method, we exit
if( ! $is_local_pickup ) {
return;
}
foreach ( $cart->get_cart() as $cart_item ){
if ( ! has_targeted_terms( $cart_item ) ) {
$new_price = $cart_item['data']->get_price() / 2; // Get 50% of the initial product price
$cart_item['data']->set_price( $new_price ); // Set the new price
}
}
}
// Cart page: Refreshing cart items on shipping method change
add_action( 'wp_footer', 'custom_cart_jquery_script' );
function custom_cart_jquery_script() {
// Only on cart page
if( is_cart() ):
?>
<script type="text/javascript">
(function($){
var a = 'input[name^="shipping_method"]';
$(document.body).on('change', a, function() {
setTimeout(function(){
$(document.body).trigger('added_to_cart');
}, 300);
console.log('change');
});
})(jQuery);
</script>
<?php
endif;
}
代码位于活动子主题(或活动主题)的functions.php 文件中.它应该有效.
Code goes in functions.php file of the active child theme (or active theme). It should works.
注意:需要一些 jQuery 代码来在运输方式更改时刷新购物车项目(在购物车页面上).
Note: Some jQuery code is required to refresh cart items on shipping method change (on cart page).
这篇关于在 WooCommerce 中将折扣运费与折扣购物车商品价格相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!