plugins – Custom field for shipping method in Woocommerce

Question

I need to add custom (and required) text field for specific shipping method in Woocommerce, that will be validated and will be visible in admin order pages and emails. It needs to be visible in cart AND in checkout page.

I have made my own little customization based on answer from: https://stackoverflow.com/a/63195406/2375074 – it’s basically what i want, but the solution is for select input field and i need simple text field.

The problem is that the validation from my code doesn’t work properly(it always shows empty error) and i have no information about that field in admin pages or emails.

I would really appreciate if someone could point me to right direction with my code.

// Custom function that handle your settings
function carrier_settings(){
    return array(
        'targeted_methods' => array('flat_rate:34'), // Your targeted shipping method(s) in this array
        'field_id'         => 'torder', // Field Id
        'field_type'       => 'text', // Field type
        'field_label'      => '', // Leave empty value if the first option has a text (see below).
        'label_name'       => __("Dołączyć do zamówienia","woocommerce"), // for validation and as meta key for orders
    );
}

// Display the custom checkout field
function carrier_company_custom_select_field( $method, $index ) {
    extract( carrier_settings() ); // Load settings and convert them in variables

    $chosen  = WC()->session->get('chosen_shipping_methods'); // The chosen methods
    $value   = WC()->session->get($field_id);
    $value   = WC()->session->__isset($field_id) ? $value : WC()->checkout->get_value('_'.$field_id);
    $options = array(); // Initializing

    if( ! empty($chosen) && $method->id === $chosen[$index] && in_array($method->id, $targeted_methods)  ) {
        echo '<div class="custom-carrier">';

        woocommerce_form_field( $field_id, array(
            'type'     => $field_type,
            'label'    => 'Do zamówienia', // Not required if the first option has a text.
            'class'    => array('form-row-wide ' . $field_id . '-' . $field_type ),
            'required' => true,
            'placeholder' => 'Podaj numer zamówienia',
        ), $value );

        echo '</div>';
    }
}
add_action( 'woocommerce_after_shipping_rate', 'carrier_company_custom_select_field', 20, 2 );

// jQuery code (client side) - Ajax sender
function carrier_company_script_js() {

    if( is_cart() || ( is_checkout() && ! is_wc_endpoint_url() ) ):
        
    extract( carrier_settings() );
    $js_variable = is_cart() ? 'wc_cart_params' : 'wc_checkout_params';

    ?>

    <script type="text/javascript">
    jQuery( function($){
        if (typeof <?php echo $js_variable; ?> === 'undefined')
            return false;

        $(document.body).on( 'input', '#<?php echo $field_id; ?>', function(){
            var value = $(this).val();
            $.ajax({
                type: 'POST',
                url: <?php echo $js_variable; ?>.ajax_url,
                data: {
                    'action': 'toorderid',
                    'value': value
                },
            });
        });
    });
    </script>

    <?php
    endif;
}
add_action( 'wp_footer', 'carrier_company_script_js' );

// The WordPress Ajax PHP receiver
function set_carrier_company_name() {
    if ( !empty($_POST['value']) ){

        extract( carrier_settings() );

        if( empty($_POST['value']) ) {
            $value = 0;
            $label="Brak";
        } else {
            $value = $label = esc_attr( $_POST['value'] );
        }

        WC()->session->set( $field_id, $value );
        echo $label;
        die();
    }
}
add_action( 'wp_ajax_torder', 'set_carrier_company_name' );
add_action( 'wp_ajax_nopriv_torder', 'set_carrier_company_name' );

// Conditional function for validation
function has_carrier_field(){
    $settings = carrier_settings();
    return array_intersect(WC()->session->get( 'chosen_shipping_methods' ), $settings['targeted_methods']);
}

// Validate the custom selection field
function carrier_company_checkout_validation() {

    extract( carrier_settings() );

    if( has_carrier_field() && empty( $_POST[$field_id] ) )
        wc_add_notice(
            sprintf( __("Proszę wpisać odpowiedni numer zamówienia","woocommerce"),
            '<strong>' . $label_name . '</strong>'
        ), "error" );
}
add_action('woocommerce_checkout_process', 'carrier_company_checkout_validation');

// Save custom field as order meta data
function save_carrier_company_as_order_meta( $order ) {

    extract( carrier_settings() );

    if( has_carrier_field() && ! empty( $_POST[$field_id] ) ) {
        $order->update_meta_data( '_'.$field_id );
        WC()->session->__unset( $field_id ); // remove session variable
    }
}
add_action( 'woocommerce_checkout_create_order', 'save_carrier_company_as_order_meta', 30, 1 );

// Display custom field in admin order pages
function admin_order_display_carrier_company( $order ) {

    extract( carrier_settings() );
    $carrier = $order->get_meta( '_'.$field_id );

    if( ! empty($carrier) ) {
        echo '<p><strong>' . $label_name . '</strong>: ' . $carrier . '</p>';
    }
}
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'admin_order_display_carrier_company', 30, 1 );

// Display carrier company after shipping line everywhere (orders and emails)
function display_carrier_company_on_order_item_totals( $total_rows, $order, $tax_display ){

    extract( carrier_settings() );
    $carrier = $order->get_meta( '_'.$field_id ); // Get carrier company

    if( ! empty($carrier) ) {
        $new_total_rows = [];

        // Loop through order total rows
        foreach( $total_rows as $key => $values ) {
            $new_total_rows[$key] = $values;
            
            // Inserting the carrier company under shipping method
            if( $key === 'shipping' ) {
                $new_total_rows[$field_id] = array(
                    'label' => $label_name,
                    'value' => $carrier,
                );
            }
        }
        return $new_total_rows;
    }
    return $total_rows;
}
add_filter( 'woocommerce_get_order_item_totals', 'display_carrier_company_on_order_item_totals', 1000, 3 );

0
Nikson 5 months 2022-06-19T11:05:01-05:00 0 Answers 0 views 0

Leave an answer

Browse
Browse