• Как соединить action и filter?

    kinnightt
    @kinnightt Автор вопроса
    Motion-дизайнер/Монтажёр/Видеограф/Фотограф
    На StackOverFlow помог один парень с ником LoicTheAztec, он решил:
    // 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;
        // HERE define the discount percentage
        $parent_id       = 37; // <= Targeted main product category
        $shipping_method = 'local_pickup'; // <= Targeted shipping method id
        $percentage      = 50; // <= percentage discount
        $subtotal        = WC()->cart->get_subtotal();
        $taxonomy        = 'product_cat';
        $others_found    = false;
    
        // Loop through cart items for the current package
        foreach( $package['contents'] 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 ) ){
                $others_found  = true;
                break; // stop the loop
            }
        }
    
        // Loop through shipping methods for the current package
        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;
    
        $parent_id       = 37; // <= Targeted main product category
        $shipping_method = 'local_pickup'; // <= Targeted shipping method id
        $taxonomy        = 'product_cat';
        $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 ){
            $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
            }
        }
    }
    
    // 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($){
            $(document.body).on('change', 'input[name^="shipping_method"]', function() {
                setTimeout(function(){
                   $(document.body).trigger('added_to_cart');
                }, 300); // 300 can be increased if necessary (for example to 400 or 500)
            });
        })(jQuery);
        </script>
        <?php
        endif;
    }
    Ответ написан
    Комментировать