Woocommerce根据体积和重量算运费

看了很多插件,包括收费和免费的,都很能满足我的需求,我的需求是重量和泡重谁最大,就用谁来做运费计算,并且还要支持阶梯运费,比如 2 公斤之内,2 公斤以上,每增加一公斤,增加多少钱之类的计算逻辑。

我自己从来没有完整的写个 wordpress 插件,然后我就求助 chatgpt,终于把这个能力给实现了一个初版本,还不能直接在后台配置,但是通过代码已经实现,先让客户可以正常计算运费,颗粒度不是特别细,有比没有要好。

怎么样实现

实现一个继承自 WC_Shipping_Method 的类就可以实现自定义的物流计费方式,以下代码来自于 chatgpt.

### 使用说明

你可以将以下代码复制并粘贴到你的 WooCommerce 插件文件中,或者创建一个新的插件文件。这段代码定义了一个名为 `WC_Tesl_Shipping_Method` 的新的物流方式,并且按照给定的规则计算运费。

确保在添加此代码之前,在 WordPress 站点上安装并激活了 WooCommerce 插件。

### 代码

```php
<?php
/**
 * Plugin Name: Tesl Shipping Method for WooCommerce
 * Description: Custom shipping method for WooCommerce.
 * Version: 1.0.0
 * Author: Your Name
 */

if ( ! defined( 'WPINC' ) ) {
    die;
}

function tesl_shipping_init() {
    if ( ! class_exists( 'WC_Tesl_Shipping_Method' ) ) {
        class WC_Tesl_Shipping_Method extends WC_Shipping_Method {
            public function __construct() {
                $this->id                 = 'tesl'; 
                $this->method_title       = __( 'Tesl Shipping', 'woocommerce' );
                $this->method_description = __( 'Custom Shipping Method for Tesl', 'woocommerce' );

                // Availability & Countries
                $this->availability = 'including';
                $this->countries = array(
                    'US',
                    // Add other countries as needed
                );

                $this->init();

                $this->enabled = isset( $this->settings['enabled'] ) ? $this->settings['enabled'] : 'yes';
                $this->title   = isset( $this->settings['title'] ) ? $this->settings['title'] : __( 'Tesl Shipping', 'woocommerce' );
            }

            function init() {
                // Load the settings API
                $this->init_form_fields();
                $this->init_settings();

                // Save settings in admin if you have any defined
                add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
            }

            /**
             * Calculate shipping cost.
             *
             * @param array $package Package information.
             */
            public function calculate_shipping( $package = array() ) {
                $weight = 0;
                $length = 0;
                $width  = 0;
                $height = 0;
                $cost   = 0;
                $longest_side = 0;

                foreach ( $package['contents'] as $item_id => $values ) {
                    $_product = $values['data'];
                    $weight += $_product->get_weight();
                    $dimensions = $_product->get_dimensions(false);
                    $length = max($length, $dimensions['length']);
                    $width  = max($width, $dimensions['width']);
                    $height = max($height, $dimensions['height']);
                    $longest_side = max($dimensions['length'], $dimensions['width'], $dimensions['height']);
                    $volumetric_weight = ($dimensions['length'] * $dimensions['width'] * $dimensions['height']) / 6000;
                    
                    if ($weight < 1 && $volumetric_weight < 1 && ($dimensions['length'] + $dimensions['width'] + $dimensions['height']) < 90) {
                        $cost = 10;
                    } elseif ($weight >= 1 && $weight < 2 && $volumetric_weight >= 1 && $volumetric_weight < 2 && ($dimensions['length'] + $dimensions['width'] + $dimensions['height']) < 90) {
                        $cost = 20;
                    } elseif ($weight > 2 || $volumetric_weight > 2) {
                        $base_cost = 20;
                        $additional_weight = max($weight, $volumetric_weight) - 2;
                        $additional_cost = $additional_weight * 8;
                        $cost = $base_cost + $additional_cost;

                        if ($longest_side > 120) {
                            $cost += 20; // Surcharge for long items
                        }
                    }
                }

                $rate = array(
                    'id'    => $this->id,
                    'label' => $this->title,
                    'cost'  => $cost,
                );

                $this->add_rate( $rate );
            }
        }
    }
}

add_action( 'woocommerce_shipping_init', 'tesl_shipping_init' );

function add_tesl_shipping_method( $methods ) {
    $methods['tesl'] = 'WC_Tesl_Shipping_Method';
    return $methods;
}



add_filter( 'woocommerce_shipping_methods', 'add_tesl_shipping_method' );

这段代码最不友好的地方是支持运送的国家写死在代码里面,最好是可以在 zone 区域进行配置,可能还需要花点时间理解怎么样在 zone 里面配置。

参考

https://www.cloudways.com/blog/create-woocommerce-custom-shipping-method-plugin/

https://code.tutsplus.com/create-a-custom-shipping-method-for-woocommerce–cms-26098t

How to create new shipping method in WooCommerce (webkul.com)