Multiply shipping cost in WooCommerce - php

I've tried to multiply shipping cost depending on how many pallets are in order. I think filter is wrong or something. It just doesnt change shipping price.
$calc = ceil($a+$b / 8); $a > is quantity of pallets, $b > is quantity of units what calculates how many pallets.
My code (function.php):
add_filter( 'woocommerce_cart_shipping_total', 'woocommerce_cart_shipping_total_filter_callback', 11, 2 );
function woocommerce_cart_shipping_total_filter_callback( $total, $cart )
{
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
if ( 0 < $cart->get_shipping_total() ) {
if ( $cart->display_prices_including_tax() ) {
$a = 0;
$b = 0;
foreach( WC()->cart->get_cart() as $cart_item ){
if (!empty(get_post_meta($cart_item['variation_id'], '_number_field', true))) {
$a += $cart_item['quantity'];
} else {
$atk = strstr(get_post_meta($cart_item['variation_id'], '_alus_al', true), 'tk', true);
$b += ceil($cart_item['quantity'] / $atk);
}
}
$calc = ceil($a+$b / 8); // 8 pallets maximum
$total = wc_price( ( $cart->shipping_total + $cart->shipping_tax_total ) * $calc );
if ( $cart->shipping_tax_total > 0 && ! wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$a = 0;
$b = 0;
foreach( WC()->cart->get_cart() as $cart_item ){
if (!empty(get_post_meta($cart_item['variation_id'], '_number_field', true))) {
$a += $cart_item['quantity'];
} else {
$atk = strstr(get_post_meta($cart_item['variation_id'], '_alus_al', true), 'tk', true);
$b += ceil($cart_item['quantity'] / $atk);
}
}
$calc = ceil($a+$b / 8); // 8 pallets maximum
$total = wc_price( $cart->shipping_total * $calc );
if ( $cart->shipping_tax_total > 0 && wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
return $total;
}
My problem is that it doesnt change shipping cost. So I excpect it doesnt work.

Like user #LoicTheAztec mentioned I should use woocommerce_package_rates to override custom prices for shipping plugin.
add_filter( 'woocommerce_package_rates', 'custom_shipping_costs', 20, 2 );
function custom_shipping_costs( $rates, $package ) {
$a = 0;
$b = 0;
foreach( WC()->cart->get_cart() as $cart_item ){
if (!empty(get_post_meta($cart_item['variation_id'], '_number_field', true))) {
$a += $cart_item['quantity'];
} else {
$atk = strstr(get_post_meta($cart_item['variation_id'], '_alus_al', true), 'tk', true);
$atb = $atk / 2;
if ($cart_item['quantity'] < $atb) {
$b += 0;
} else {
$b += ceil($cart_item['quantity'] / $atk);
}
}
}
$tt = $a+$b;
$calc = ceil($tt / 8);
foreach( $rates as $rate_key => $rate ){
// Excluding free shipping methods
if( $rate->method_id != 'free_shipping'){
// Set rate cost
$rates[$rate_key]->cost = $rates[$rate_key]->cost * $calc;
// 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;
}

Related

Infinite Loop at Checkout Woocommerce [woocommerce_package_rates]

I have written the following script to automatically apply a $350 credit to the shipping rates if the shipping rate is over $350. When removing this script from my functions.php there are no issues at Checkout, the shipping methods will populate. When leaving this script in functions.php, the Checkout page requires multiple refreshes to populate and does not end the spinning loading loop.
Is there something I am missing here?
add_filter('woocommerce_package_rates', 'custom_shipping_rate_label_based_on_cost', 100, 2);
function custom_shipping_rate_label_based_on_cost( $rates, $package ){
// Declare Variables
$subtotal = $package['cart_subtotal'];
$counter = 0;
$first = 0;
$category = 0;
$discount = 350;
// Set Category True if Walk In Tub
foreach ($package['contents'] as $product) {
$product_cats = wp_get_post_terms( $product['product_id'], 'product_cat', array('fields' => 'names') );
if( in_array('Walk In Tubs', $product_cats) ) {
$category = 1;
}
}
// Set First Shipping Rate Cost and Counter
foreach ( $rates as $key => $rate ) {
$rate_cost = $rate->cost;
if( $counter == 0 ) {
$firstcost = $rate_cost;
}
if( $counter == 1 ) {
$secondcost = $rate_cost;
}
$counter = $counter + 1;
}
if ($firstcost == 0) {
$firstcost = $secondcost;
}
// Over or Equal to 350
if ( $firstcost >= 350 && $subtotal >= 4500 && $category = 1 && is_checkout()) {
$rates[$key]->cost = $rates[$key]->cost - ( $discount );
wc_print_notice( __( '<div class="shippingdiscount">$350 Discount Applied to Total Shipping Cost</div>', 'woocommerce' ), 'notice' );
}
// Under 350
else if ( $firstcost < 350 && $firstcost != 0 && $subtotal >= 4500 && $category = 1 && is_checkout()) {
foreach ( $rates as $key => $rate ) {
$rates[$key]->cost = $rates[$key]->cost - ( $firstcost );
}
wc_print_notice( __( '<div class="shippingdiscount">Your order is eligible for Free Shipping</div>', 'woocommerce' ), 'notice' );
}
else {
return;
}
return $rates;
}
It seems the issue is stemming from: wc_print_notice

Add tag to WooCommerce products based on discount percentage

I combined the code from here Setting Woocommerce Product Tags and Categories via Custom Frontend Form with the code from here Display the discount percentage on the sale badge in Woocommerce 3 :) and it looks like its working but I am not confident, what do you think?
for testing purposes I just added an if
if ($percentage > 15) {
wp_set_object_terms($product->get_id(), array('tag5'), 'product_tag');
}
and I can see the tags on the back end/front end.
Thank you
add_filter( 'woocommerce_sale_flash', 'add_percentage_to_sale_badge', 20, 3 );
function add_percentage_to_sale_badge( $html, $post, $product ) {
if( $product->is_type('variable')){
$percentages = array();
// Get all variation prices
$prices = $product->get_variation_prices();
// Loop through variation prices
foreach( $prices['price'] as $key => $price ){
// Only on sale variations
if( $prices['regular_price'][$key] !== $price ){
// Calculate and set in the array the percentage for each variation on sale
$percentages[] = round( 100 - ( floatval($prices['sale_price'][$key]) / floatval($prices['regular_price'][$key]) * 100 ) );
}
}
// We keep the highest value
$percentage = max($percentages) . '%';
} elseif( $product->is_type('grouped') ){
$percentages = array();
// Get all variation prices
$children_ids = $product->get_children();
// Loop through variation prices
foreach( $children_ids as $child_id ){
$child_product = wc_get_product($child_id);
$regular_price = (float) $child_product->get_regular_price();
$sale_price = (float) $child_product->get_sale_price();
if ( $sale_price != 0 || ! empty($sale_price) ) {
// Calculate and set in the array the percentage for each child on sale
$percentages[] = round(100 - ($sale_price / $regular_price * 100));
}
}
// We keep the highest value
$percentage = max($percentages) . '%';
} else {
$regular_price = (float) $product->get_regular_price();
$sale_price = (float) $product->get_sale_price();
if ( $sale_price != 0 || ! empty($sale_price) ) {
$percentage = round(100 - ($sale_price / $regular_price * 100)) . '%';
} else {
return $html;
}
}
if ($percentage > 15) {
wp_set_object_terms($product->get_id(), array('tag5'), 'product_tag');
}
return '<span class="onsale">' . esc_html__( 'SALE', 'woocommerce' ) . ' ' . $percentage . '</span>'. $product->get_id();
}

How to calculate order total after check out

I have calculated a different custom order total in Woocommerce:
add_action( 'woocommerce_checkout_create_order', 'change_total_on_checking', 20, 1 );
function change_total_on_checking( $order ) {
// Get order total
$total = $order->get_total();
$orderproduct = $order->get_items();
$tax_rate = WC_Tax::get_rates( $orderproduct );
if ($tax_rate == "10") {
$percent10 = $total * $tax_rate;
}
if ( $tax_rate == "4" ){
$percent4 = $total * $tax_rate;
}
## -- fai check e calcoli -- ##
$new_total = $total + $percent4 + $percent10; // <== Fake calculation
// imposta un calcolo nuovo
$order->set_total( $new_total );
}
But my calculations don't work and I'm not able to make it for instance.
Any advice or help please?
Is there ever a time you would have both tax rates? Otherwise, I would think one variable for taxes would be enough, like so:
if ($tax_rate == "10") {
$tax_total = $total * $tax_rate;
}
if ( $tax_rate == "4" ){
$tax_total = $total * $tax_rate;
}
## -- fai check e calcoli -- ##
$new_total = $total + $tax_total
Also, what do you mean your calculations are working?
I think you didn't initiate the variables $percent10 and $percent4
try this:
add_action( 'woocommerce_checkout_create_order', 'change_total_on_checking', 20, 1 );
function change_total_on_checking( $order ) {
// Get order total
$total = $order->get_total();
$orderproduct = $order->get_items();
$tax_rate = WC_Tax::get_rates( $orderproduct );
$percent10 = 0; // if $tax_rate != "10", will sum zero in $new_total
$percent4 = 0; // if $tax_rate != "4", will sum zero in $new_total
if ($tax_rate == "10") {
$percent10 = $total * $tax_rate;
}
if ( $tax_rate == "4" ){
$percent4 = $total * $tax_rate;
}
## -- fai check e calcoli -- ##
$new_total = $total + $percent4 + $percent10; // <== Fake calculation
// imposta un calcolo nuovo
$order->set_total( $new_total );
}
Because you used the wrong parameter of tax function. You can try this
add_action( 'woocommerce_checkout_create_order', 'change_total_on_checking', 20, 1 );
function change_total_on_checking( $order ) {
// Get order total
$total = $order->get_total();
$orderproduct = $order->get_items();
foreach($orderproduct as $product){
$tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
if($tax_rate = $tax_rates[1]['rate']){
if ($tax_rate == 10) {
$percent10[] = $total * $tax_rate;
}
if ($tax_rate == 4) {
$percent4[] = $total * $tax_rate;
}
}
}
/* */
## -- fai check e calcoli -- ##
$new_total = $total + floatval((is_array($percent4))? array_sum($percent4): 0) + floatval((is_array($percent10))? array_sum($percent10): 0); // <== Fake calculation
// imposta un calcolo nuovo
$order->set_total( $new_total );
}

Change the displayed shipping total in WooCommerce

I need to change shipping price programmatically:
<?php
$percentage = 50;
$current_shipping_cost = WC()->cart->get_cart_shipping_total();
echo $current_shipping_cost * $percentage / 100;
?>
Unfortunately it's not working and I always get 0 (zero).
How to change the displayed shipping total with a total based on a calculated discount percentage?
The following will displayed shipping total based on a percentage. There is 2 ways:
1) First way with a custom function.
In the function.php file of your active child theme (or active theme):
function wc_display_cart_shipping_total( $percentage = 100 )
{
$cart = WC()->cart;
$total = __( 'Free!', 'woocommerce' );
if ( 0 < $cart->get_shipping_total() ) {
if ( $cart->display_prices_including_tax() ) {
$total = wc_price( ( $cart->shipping_total + $cart->shipping_tax_total ) * $percentage / 100 );
if ( $cart->shipping_tax_total > 0 && ! wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$total = wc_price( $cart->shipping_total * $percentage / 100 );
if ( $cart->shipping_tax_total > 0 && wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
return $totals;
}
Usage:
<?php echo wc_display_cart_shipping_total(50); ?>
2) Second way with a filter hook.
In the function.php file of your active child theme (or active theme):
add_filter( 'woocommerce_cart_shipping_total', 'woocommerce_cart_shipping_total_filter_callback', 11, 2 );
function woocommerce_cart_shipping_total_filter_callback( $total, $cart )
{
// HERE set the percentage
$percentage = 50;
if ( 0 < $cart->get_shipping_total() ) {
if ( $cart->display_prices_including_tax() ) {
$total = wc_price( ( $cart->shipping_total + $cart->shipping_tax_total ) * $percentage / 100 );
if ( $cart->shipping_tax_total > 0 && ! wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$total = wc_price( $cart->shipping_total * $percentage / 100 );
if ( $cart->shipping_tax_total > 0 && wc_prices_include_tax() ) {
$total .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
return $totals;
}
Usage:
<?php echo WC()->cart->get_cart_shipping_total(); ?>

How to shorten my function?

I have a function to calculate price as below. Im just interested to learn any other way to shorten my code.
PHP
function calculate_price( $quantity, $target_quantity, $price, $rate )
{
$total = 0;
if( $quantity > $target_quantity )
{
$total = $target_quantity * $price;
$quantity -= $target_quantity;
$tmp_price = $price;
do {
$tmp_price = $tmp_price * $rate;
$total += $tmp_price;
$quantity--;
} while( $quantity > 0 );
}
else
{
$total = $quantity*$price;
}
return $total;
}
echo calculate_price( 8, 5, 3, 0.5 );
You could combine the decrement in the while statement.
while( --$quantity > 0 );

Categories