0

How to show the data of the new fields in the WooCommerce billing data?

I have created on the page "My Account" of WooCommerce, in the billing address, two new fields. These are only visible to certain user roles ('administrator'),

The fields are shown at checkout in this screenshot

1 - a checkbox that has a text label: 'label' => __('I have Surcharge' (which is the one I need to show in the emails)

This field is created with the following code and

add_filter( 'woocommerce_billing_fields', 'custom_checkbox_below_billing_company' );

function custom_checkbox_below_billing_company( $fields ) {
    //Show the checkbox only to users with the role "administratorr"
    if ( user_can( wp_get_current_user(), 'administrator' ) ) {
        $fields['billing_custom_checkbox'] = array(
            'type'          => 'checkbox',
            'label'         => __('Tengo Recargo', 'woocommerce'),
            'class'         => array('form-row-wide'),
            'priority'      => 30,
            'required'      => false,
            'clear'         => true,
            'default'       => 0,
        );
    }
    return $fields;
}

// Save the value of the checkbox in the database
add_action( 'woocommerce_customer_save_address', 'save_billing_custom_checkbox', 10, 2 );

function save_billing_custom_checkbox( $customer_id, $load_address ) {
    if ( isset( $_POST['billing_custom_checkbox'] ) ) {
        $checkbox_value = sanitize_text_field( $_POST['billing_custom_checkbox'] );
        update_user_meta( $customer_id, 'billing_custom_checkbox', $checkbox_value );
    } else {
        update_user_meta( $customer_id, 'billing_custom_checkbox', '0' );
    }
}

/* SENDING THE FIELD IN THE POST*/

// Show checkbox label in billing address
add_action( 'woocommerce_admin_billing_fields', 'show_billing_custom_checkbox_label' );
add_action( 'woocommerce_billing_fields', 'show_billing_custom_checkbox_label' );

function show_billing_custom_checkbox_label( $fields ) {
    if ( isset( $fields['billing_custom_checkbox'] ) ) {
        $fields['billing_custom_checkbox']['label'] .= ' ' . __('(Tengo Recargo de Ekivalencia)', 'woocommerce');
    }
    return $fields;
}


add_filter( 'woocommerce_email_customer_details_fields', 'add_custom_checkbox_to_emails', 10, 3 );

function add_custom_checkbox_to_emails( $fields, $sent_to_admin, $order ) {
    $checkbox_value = get_user_meta( $order->get_user_id(), 'billing_custom_checkbox', true ); // Get the value of the checkbox
    $fields['billing_custom_checkbox'] = array(
        'label' => __('Tengo Recargo de Ekivalencia', 'woocommerce') . ' ' . ($checkbox_value ? 'SI' : 'NO'), //Add the value of the checkbox in the label
        'value' => $checkbox_value ? 'SI' : 'NO', // Agrega el valor del checkbox en el valor
    );
    return $fields;
}

2 - A field to enter the tax identification number of the company, NIF/CIF : 'label' => __('NIF/CIF', 'woocommerce'),

The NIF/CIF field has been created as follows, but the way it is displayed in emails to clients and administrators fails

add_filter('woocommerce_checkout_fields', 'add_custom_billing_field');
function add_custom_billing_field($fields)
{
  // Get the role of the current user
  $user = get_userdata( get_current_user_id() );
  if ( ! empty( $user ) && in_array( 'administrator', (array) $user->roles ) ) {

    $current_user = wp_get_current_user();
    $saved_license_no = $current_user->license_no;

    // Add the NIF/CIF field to the billing address editing form
    $fields['billing_license_no'] = array(
      'label'       => __('NIF/CIF', 'woocommerce'),
      'placeholder' => __('B12345678', 'woocommerce'),
      'required'    => true,
      'clear'       => false,
      'type'        => 'text',
      'default'     => $saved_license_no,
      'class'       => array('form-row-wide'),
      'priority'    => 25, 
    );
  }

  //Return the updated array of billing fields
  return $fields;
}

/* save the new field and show it in email, checkout, etc... */
add_action('woocommerce_checkout_update_order_meta', 'bbloomer_save_new_checkout_field');
function bbloomer_save_new_checkout_field($order_id)
{
  if (isset($_POST['billing_license_no'])) { //Check if field value was sent
    update_post_meta($order_id, '_license_no', wc_clean($_POST['billing_license_no'])); //Clear value before saving
  }
}


add_action('woocommerce_thankyou', 'bbloomer_show_new_checkout_field_thankyou');
function bbloomer_show_new_checkout_field_thankyou($order_id)
{
  if (get_post_meta($order_id, '_license_no', true)) echo '<p><strong>NIF/CIF:</strong> ' . get_post_meta($order_id, '_license_no', true) . '</p>';
}

add_filter('woocommerce_order_details_after_order_table', 'bbloomer_show_new_checkout_field_order', 20, 1);
add_action('woocommerce_admin_order_data_after_billing_address', 'bbloomer_show_new_checkout_field_order');
function bbloomer_show_new_checkout_field_order($order)
{
  $order_id = $order->get_id();
  if (get_post_meta($order_id, '_license_no', true)) echo '<p><strong>NIF/CIF:</strong> ' . get_post_meta($order_id, '_license_no', true) . '</p>';
}

add_action('woocommerce_email_after_order_table', 'bbloomer_show_new_checkout_field_emails', 20, 4);

function bbloomer_show_new_checkout_field_emails($order, $sent_to_admin, $plain_text, $email)
{
  if (get_post_meta($order->get_id(), '_license_no', true)) echo '<p><strong>NIF/CIF:</strong> ' . get_post_meta($order->get_id(), '_license_no', true) . '</p>';
}

These fields are edited from the user's account page, my-account/edit-address/billing/ and are also displayed at Checkout when placing an order.

I only need these data to be part of the WooCommerce billing data and to be sent along with the rest of the data: Name, Surname, Company Name, Address, etc.

It can be seen on the screenshot. //// admin-Mail

Now they are sent in the mail but outside the address range, as you can see in the screenshot (administrator-Mail.png)

But this data is not part of the WooCommerce structure, so it is not displayed when I generate an invoice (invoice screenshot - bill.jpg)

What should I do so that these data are part of the WooCommerce Billing address?

Perhaps it could be achieved by editing the WooCommerce structure, but I don't know if this is possible, and if it could be done, how would it be done?

How can this be done in the safest way?

Yash
  • 1,020
  • 1
  • 15
gemita
  • 2,686
  • 2
  • 10
  • 17
  • anyone who want to understand background process that lead the custom checkout field functionality to hear , check answer of https://stackoverflow.com/questions/75730742/how-to-show-and-order-some-fields-in-the-woocommerce-checkout-only-to-certain-us , that answer is now used in question – Yash Apr 25 '23 at 19:11

1 Answers1

1
<?php
/**
 * Add custom WooCommerce checkout fields for administrator users.
 *
 * @param   array   $fields The existing billing fields.
 * @return  array   $fields The updated billing fields.
 */
function custom_woocommerce_checkout_fields( $fields ) {

    // Get the current user
    $current_user = wp_get_current_user();

    // Check if the current user is an administrator
    if ( in_array( 'administrator', (array) $current_user->roles ) ) {

        // Get the saved license number for the current user
        $saved_license_no = $current_user->license_no;

        // Add the custom fields to the billing fields array
        $fields['billing_licenseno'] = array(
            'label'       => __( 'NIF/CIF', 'woocommerce' ),
            'placeholder' => __( 'B12345678', 'woocommerce' ),
            'type'        => 'text',
            'required'    => true,
            'clear'       => false,
            'default'     => $saved_license_no,
            'class'       => array( 'form-row-wide' ),
            'priority'    => 25,
        );

        $fields['billing_customcheckbox'] = array(
            'label'         => __('Tengo Recargo (Tengo Recargo de Ekivalencia)', 'woocommerce'),
            'type'          => 'checkbox',
            'required'      => false,
            'clear'         => true,
            'default'       => 0,
            'class'         => array('form-row-wide'),
            'priority'      => 30,
        );
    }
    
    return $fields;
}
add_filter('woocommerce_billing_fields', 'custom_woocommerce_checkout_fields');


/**
 * Filters the WooCommerce order formatted billing address.
 * @param   array   $address The array of address.
 * @param   object  $order The order object.
 * @return  array   The updated array of address.
 */
function add_custom_woocommerce_order_fields( $address, $order ) {
    
    $user_meta = get_userdata( $order->get_user_id() );
    $user_roles = $user_meta->roles;
    
    if( in_array( "administrator", (array) $user_roles) ) {            
        // Get the license number from the order meta.
        $address['licenseno'] = $order->get_meta( '_billing_licenseno' );

        // Get the custom checkbox value from the order meta.
        $address['customcheckbox'] = $order->get_meta( '_billing_customcheckbox' ) ? __( 'SI', 'text-domain' ) : __( 'NO', 'text-domain' );
    }

    return $address;
}
add_filter( 'woocommerce_order_formatted_billing_address', 'add_custom_woocommerce_order_fields', 10, 2 );


/**
 * Saves the billing custom checkbox value on customer save address.
 * @param   int     $customer_id The customer ID.
 * @param   string  $load_address The address type.
 * @return  void
 */
function save_billing_custom_checkbox( $customer_id, $load_address ) {
    if ( isset( $_POST['billing_customcheckbox'] ) ) {
        // Sanitize the custom checkbox value.
        $checkbox_value = sanitize_text_field( wp_unslash( $_POST['billing_customcheckbox'] ) );

        // Update the user meta with the custom checkbox value.
        update_user_meta( $customer_id, 'billing_customcheckbox', $checkbox_value );
    } else {
        // If the custom checkbox value is not set, update the user meta with 0.
        update_user_meta( $customer_id, 'billing_customcheckbox', '0' );
    }
}
add_action( 'woocommerce_customer_save_address', 'save_billing_custom_checkbox', 10, 2 );


/**
 * Filters the WooCommerce localisation address formats.
 * @param   array   $address_formats The array of address formats.
 * @return  array   The updated array of address formats.
 */
function custom_localisation_address_formats( $address_formats ) {
    
    foreach ( $address_formats as $country_code => $address_format ) {
        $address_formats[ $country_code ] = str_replace(
            "{name}",
            "{name}\n{licenseno}\n{customcheckbox}",
            $address_formats[ $country_code ]
        );
    }
    
    return $address_formats;
}
add_filter( 'woocommerce_localisation_address_formats', 'custom_localisation_address_formats', 50, 1 );


/**
 * Filters the WooCommerce formatted address replacements.
 * @param   array   $replacements The array of address replacements.
 * @param   array   $args The array of arguments.
 * @return  array   The updated array of address replacements.
 */
function formatted_address_custom_replacements( $replacements, $args ) {
    $replacements['{licenseno}'] = ! empty( $args['licenseno'] ) ? $args['licenseno'] : '';
    $replacements['{customcheckbox}'] = ! empty( $args['customcheckbox'] ) ? $args['customcheckbox'] : '';

    return $replacements;
}
add_filter( 'woocommerce_formatted_address_replacements', 'formatted_address_custom_replacements', 10, 2 );

Test it and let me know for any change or if error occure

Yash
  • 1,020
  • 1
  • 15
  • Hello. Thanks for being there. This seems to work, we just have to change the `\n` to `
    ` in the following line `{name}\n{licenseno}\n{customcheckbox}`and perfect. It has some drawback, a space is generated in "the shipping address" that you can see in the two screenshots, but I don't know how to solve this. Otherwise well. Thank you very much for your support https://ibb.co/j5J1vgN --- https://ibb.co/6Z9zpq8. In gratitude I will create a reward when the time comes
    – gemita Apr 25 '23 at 21:35
  • 1
    @gemita , `\n` not work in single quotation `' '` , it work in double quotation `" "` , it's my error , thanks for point it out . i'll update my answer , so use `\n` instead of `
    `. it is more right way
    – Yash Apr 26 '23 at 17:12
  • Hi @Yash. I have a mistake. The new fields are only shown to users with the 'administrator' role. The problem is that, when adding these fields to the WooCommerce billing data, the field of `$address['customcheckbox']= "NO No tengo Recargom de ekibalenciah`, is added to all user role types by default. This `'billing_customcheckbox'` field should only be added to the billing data for the 'administrator' role. I've tried to do it, but I can't find the way, I can't get it to work, can you give me a hint on how to achieve this and only add to the billing data of the 'administrator' role? Thank you – gemita May 03 '23 at 14:28
  • 1
    @gemita , i make some change in `add_filter( 'woocommerce_order_formatted_billing_address', 'add_custom_woocommerce_order_fields', 10, 2 ); ` so check that and let me know – Yash May 03 '23 at 18:17
  • Great, I had a similar solution, but I finally used your example. Thank you thank you very much – gemita May 03 '23 at 18:53