11

I am using woocommerce-advanced-checkout-fields plugin and added a repeater field to the billing section as follows

enter image description here

As you can see in the image above the repeater field "Name/Email" is applicable to the product "Belt"

Now when I go to buy the product from the store and make the quantity 3 as follows the repeater field is shown 3 times and all is good to the point.

enter image description here

Now when I place the order the landing page does not carry the values I entered as follows

enter image description here

Also, the values are not showing in the Order admin section as follows.

enter image description here

I believe that I have clearly elaborated the problem. Need your suggestions to solve this issue

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Rinsad Ahmed
  • 1,877
  • 1
  • 10
  • 28
  • Hope its a premium plugin and why can't you contact the support regarding this issue? – Outsource WordPress Oct 12 '18 at 18:48
  • I can see this code in the plugin where these custom repeater fields are stored WC()->customer->set_meta_data WC()->customer->set_meta_data( array( array( 'id' => $key, 'key' => $key, 'value' => $value ) ) ); But those values are not found in the post_meta table – Rinsad Ahmed Oct 13 '18 at 17:52
  • WC()->customer->set_meta_data store values in **User** meta data but **NOT** in **post** meta data … So this doesn't seem to be related to your issue. – LoicTheAztec Oct 13 '18 at 18:51
  • This could be done without your plugin with only custom code… But what about when there is multiple items in cart (for example item1 (quantity 2) + item2 (quantity 3)? – LoicTheAztec Oct 13 '18 at 19:05
  • Could you check the product detail HTML from your browser debugger? To check if some input with a correspondent name is here? Maybe it's hidden by something. Have you edited the woocommerce template? Is it a bought template? – Mtxz Oct 13 '18 at 21:26
  • My suggestions are: 1) Try with a default theme like Twenty Seventeen. 2) Disable all plugins except WC and the plugin in question, then see if that helps. 3) Ask the author. 4) Switch to another plugin.. 5) Custom-code the fields and the other stuff. – Sally CJ Oct 16 '18 at 12:12

1 Answers1

7

As you didn't answer to any comment since you started the bounty. Nobody can handle to solve your problem without knowing what are the settings you are using, and what are the database related post meta data (the registered meta keys) for this additional fields for an Order…

To get a repeater for specific custom checkout billing fields based on the item quantity of specific product(s) without any plugin:

1) A Product additional setting (a checkbox to activate this feature):

// Display a custom setting option on product edit pages
add_action('woocommerce_product_options_general_product_data', 'add_product_repeater_checkbox_option');
function add_product_repeater_checkbox_option(){
    echo '<div class="product_custom_field">';

    // Custom Product Checkbox Field
    woocommerce_wp_checkbox( array(
        'id'          => '_qty_repeater',
        'label'       => __('Qty repeater', 'woocommerce'),
        'description' => __('Enable quantity repeater for additional "Name" and "Email" billing checkout fields', 'woocommerce'),
        'desc_tip'    => 'true'
    ));

    echo '</div>';
}

// Save the custom setting option value from product edit pages
add_action( 'woocommerce_admin_process_product_object', 'save_product_repeater_checkbox_option', 100, 1 );
function save_product_repeater_checkbox_option( $product ) {
    $qty_repeater = isset( $_POST['_qty_repeater'] ) ? 'yes' : 'no';
    $product->update_meta_data( '_qty_repeater', $qty_repeater );
}

enter image description here

2) Add / Save the repeated additional fields on checkout (and mark the order):

add_filter('woocommerce_billing_fields', 'additional_billing_checkout_fields', 50, 1 );
function additional_billing_checkout_fields( $billing_fields ) {
    foreach(WC()->cart->get_cart() as $cart_item ){
        // Check if the "Quanty repeater option is set for the current item
        if( $cart_item['data']->get_meta('_qty_repeater') === 'yes' && is_checkout() && $cart_item['quantity'] > 1 ) {

            // Quantity repeater
            for( $i = 1, $j = 2; $i < $cart_item['quantity']; $i++, $j++ ){

                // Name fields
                $billing_fields['billing_name_person'.$j] = array(
                    'type'        => 'text',
                    'label'       => __("Name", "woocommerce") . ' ' . $j,
                    'class'       => array('form-row-first'),
                    'required'    => true,
                    'clear'       => false,
                );

                // Email fields
                $billing_fields['billing_email_person'.$j] = array(
                    'type'        => 'email',
                    'label'       => __("Email", "woocommerce") . ' ' . $j,
                    'class'       => array('form-row-last'),
                    'required'    => true,
                    'clear'       => true,
                );
            }
            break; // Only for one item
        }
    }
    return $billing_fields;
}

// Mark Order as having this additional fields data values
add_action('woocommerce_checkout_create_order', 'save_additional_billing_checkout_fields', 20, 2);
function save_additional_billing_checkout_fields( $order, $data ) {
    foreach( $order->get_items() as $item ){
        $product = $item->get_product();
        // Mark the order as containing additional fields
        if( $product->get_meta('_qty_repeater') === 'yes' && $item->get_quantity() > 1 ) {
            $item->update_meta_data( '_qty_repeater', '1' );
            break; // Stop the loop
        }
    }
}

enter image description here

3) Display the additional Billing fields related data everywhere (admin orders, order-views, emails):

// Display additional billing fields values
add_action('woocommerce_order_details_after_order_table', 'display_additional_billing_fields_values' ); // Order received and view
add_action( 'woocommerce_email_after_order_table', 'display_additional_billing_fields_values' ); // Email notifications
add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_additional_billing_fields_values' ); // Admin edit Order
function display_additional_billing_fields_values( $order ) {

    if( $order->get_meta('_qty_repeater') ) {
        // Only for email notifications
        if( ! ( is_wc_endpoint_url() || is_checkout() || is_admin() ) ){
            echo '<style>
            table.customer-details {width: 100%; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif;
                color: #737373; border: 1px solid #e4e4e4; margin-bottom:40px;}
            table.customer-details td{text-align: left; border-top-width: 4px; color: #737373; border: 1px solid #e4e4e4;
                padding: 12px; padding-bottom: 4px;}
            </style>';
        }
        // Others
        else {
            echo '<style> table.customer-details, table.customer-details td { border: none; } </style>';
        }

        echo '<h2>' . __( 'Customer details', 'woocommerce' ) . '</h2>';
        echo '<div><table class="customer-details" cellspacing="0">';

        // Loop through order items
        foreach( $order->get_items() as $item ){
            $product = $item->get_product();
            if( $product->get_meta('_qty_repeater') === 'yes' ) {
                // Loop through item quantity
                for( $i = 1, $j = 2; $i < $item->get_quantity(); $i++, $j++ ){
                    // Name
                    echo '<tr><td><strong>' . __("Name", "woocommerce") . ' ' . $j;
                    echo ': </strong>' . $order->get_meta('_billing_name_person'.$j) . '</td>';
                    // Email
                    echo '<td><strong>' . __("Email", "woocommerce") . ' ' . $j;
                    echo ': </strong>' . $order->get_meta('_billing_email_person'.$j) . '</td></tr>';
                }
                break;
            }
        }
        echo '</table></div>';
    }
}

enter image description here

4) Make The additional billing fields editable (Admin):

add_filter( 'woocommerce_admin_billing_fields' , 'additional_admin_editable_billing_fields' );
function additional_admin_editable_billing_fields( $fields ) {
    global $pagenow, $post;

    if( $pagenow != 'post.php' ) return $fields;

    $order = wc_get_order($post->ID);

    if( $order->get_meta('_qty_repeater') ) {
        // Loop through order items
        foreach( $order->get_items() as $item ){
            $product = $item->get_product();
            if( $product->get_meta('_qty_repeater') === 'yes' ) {
                // Loop through item quantity
                for( $i = 1, $j = 2; $i < $item->get_quantity(); $i++, $j++ ){
                    $fields['name_person'.$j] = array(
                        'label'         => __("Name", "woocommerce") . ' ' . $j,
                        'show'          => false,
                        'wrapper_class' => 'first',
                    );
                    $fields['email_person'.$j] = array(
                        'label'         => __("Email", "woocommerce") . ' ' . $j,
                        'show'          => false,
                        'wrapper_class' => 'last',
                    );
                }
                break;
            }
        }
    }
    return $fields;
}

enter image description here

Code goes in function.php file of your active child theme (or active theme). Tested and works.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • LoicTheAztec, you're a genius! Thanks a lot for this. I only have one newbie question: what can I change to make the repeater show a number of fields minus 1. Because the details of one person are already in the Billing details, so I only need the other persons' details, whose number = total_cart_items - 1. – Alex Oct 24 '18 at 15:19
  • i did a small change: for( $i = 1, $j = 2; -> to have Name 2 and Name 3 only. is what I did correct? – Alex Oct 24 '18 at 15:23
  • 1
    @Alex Your change is correct… I have made some more changes testing if the related item quantity is more than 1 to enable this. So Step 2, 3 and 4 are updated. There was also an oversight in `save_additional_billing_checkout_fields()` function… – LoicTheAztec Oct 24 '18 at 16:54
  • @FrankBailey Yes I know, I hate myself :] – LoicTheAztec Dec 09 '20 at 15:50