Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ACF repeater based on product quantity generating checkout fields in Woocommerce

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

like image 485
Rinsad Ahmed Avatar asked Oct 10 '18 02:10

Rinsad Ahmed


1 Answers

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.

like image 119
LoicTheAztec Avatar answered Oct 21 '22 07:10

LoicTheAztec