Home > Enterprise >  Calculate fee from cart totals (subtotal shipping) without adding it to order total value in Wooco
Calculate fee from cart totals (subtotal shipping) without adding it to order total value in Wooco

Time:09-16

Based on enter image description here

CodePudding user response:

Since you don't want to add it to the total, you can add a custom table row to the woocommerce-checkout-review-order-table instead of a cart fee. So my answer is not based on the WooCommerce fee and is completely separate from it.

The custom table row will then show/hide the percentage, based on if the checkbox is checked.

Explanation via one-line comments, added to my answer.

So you get:

// Add checkbox field
function action_woocommerce_before_order_notes( $checkout ) {
    // Add field
    woocommerce_form_field( 'my_id', array(
        'type'          => 'checkbox',
        'class'         => array( 'form-row-wide' ),
        'label'         => __( '15% and some other text', 'woocommerce' ),
        'required'      => false,  
    ), $checkout->get_value( 'my_id' ));
}
add_action( 'woocommerce_before_order_notes', 'action_woocommerce_before_order_notes', 10, 1 );

// Save checkbox value
function action_woocommerce_checkout_create_order( $order, $data ) {
    // Set the correct value
    $checkbox_value = isset( $_POST['my_id'] ) ? 'yes' : 'no';
    
    // Update meta data
    $order->update_meta_data( '_my_checkbox_value', $checkbox_value );
}
add_action( 'woocommerce_checkout_create_order', 'action_woocommerce_checkout_create_order', 10, 2 );

// Add table row on the checkout page
function action_woocommerce_before_order_total() {
    // Initialize
    $percent = 15;
    
    // Get subtotal & shipping total
    $subtotal       = WC()->cart->subtotal;
    $shipping_total = WC()->cart->get_shipping_total();
    
    // Total
    $total = $subtotal   $shipping_total;
    
    // Result
    $result = ( $total / 100 ) * $percent;
    
    // The Output
    echo '<tr class="my-class">
        <th>' . __( 'My text', 'woocommerce' ) . '</th>
        <td data-title="My text">' . wc_price( $result ) . '</td>
    </tr>';
}
add_action( 'woocommerce_review_order_before_order_total', 'action_woocommerce_before_order_total', 10, 0 );
    
// Show/hide table row on the checkout page with jQuery
function action_wp_footer() {
    // Only on checkout
    if ( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script type="text/javascript">
    jQuery( function($){
        // Selector
        var my_input = 'input[name=my_id]';
        var my_class = '.my-class';
        
        // Show or hide
        function show_or_hide() {
            if ( $( my_input ).is(':checked') ) {
                return $( my_class ).show();
            } else {
                return $( my_class ).hide();               
            }           
        }
        
        // Default
        $( document ).ajaxComplete(function() {
            show_or_hide();
        });
        
        // On change
        $( 'form.checkout' ).change(function() {
            show_or_hide();
        });
    });
    </script>
    <?php
    endif;
}
add_action( 'wp_footer', 'action_wp_footer', 10, 0 );

// If desired, add new table row to emails, order received (thank you page) & my account -> view order
function filter_woocommerce_get_order_item_totals( $total_rows, $order, $tax_display ) {    
    // Get checkbox value
    $checkbox_value = $order->get_meta( '_my_checkbox_value' );
    
    // NOT equal to yes, return
    if ( $checkbox_value != 'yes' ) return $total_rows;
    
    // Initialize
    $percent = 15;
    
    // Get subtotal & shipping total
    $subtotal       = $order->get_subtotal();
    $shipping_total = $order->get_shipping_total();
    
    // Total
    $total = $subtotal   $shipping_total;
    
    // Result
    $result = ( $total / 100 ) * $percent;
    
    // Save the value to be reordered
    $order_total = $total_rows['order_total'];
    
    // Remove item to be reordered
    unset( $total_rows['order_total'] );
    
    // Add new row
    $total_rows['my_text'] = array(
        'label' =>  __( 'My text:', 'woocommerce' ),
        'value' => wc_price( $result ),
    );
    
    // Reinsert removed in the right order
    $total_rows['order_total'] = $order_total;

    return $total_rows;
}
add_filter( 'woocommerce_get_order_item_totals', 'filter_woocommerce_get_order_item_totals', 10, 3 );
  • Related