2

I EDIT THE QUESTION

What should I do to reorder the new Checkout fields created to my needs?

What should I do so that these fields are only shown to certain users according to their role?

It is important to show this new field only to certain user roles

I have not formulated the question correctly, so I correct it. This new NIF/CIF field should only be shown to a certain user role, in this case the role is: "wholesaler_customer". Only if the user is registered and has this role ("wholesaler_customer") should the field be shown at Checkout. For the rest of the user roles, this field will not be visible in the Checkout

Thanks to the collaboration of another user of this site @MartinMirchev , who provided me with documentation to review, I have managed to isolate the problem a bit.

The new field is not reordered, but duplicated, and is displayed at the bottom, after the email address field, and the "Ship to a different address?" checkbox.

The new field that I have created is shown in the position that I indicate with the Code Priority, but it only shows the entry, the placeholder or the label that I have assigned to it is not shown (NIF/CIF: ) To reorder I use the second code snippet below.

What am I doing wrong in these functions?

I have a new field in the woocommerce checkout for the NIF of the companies. The following function creates the field and displays it on the form.

/* show the new field on the checkout page */

add_action( 'woocommerce_before_order_notes', 'bbloomer_add_custom_checkout_field' );
  
function bbloomer_add_custom_checkout_field( $checkout ) { 
   $current_user = wp_get_current_user();
   $saved_license_no = $current_user->license_no;
   woocommerce_form_field( 'license_no', array(        
      'type' => 'text',        
      'class' => array( 'form-row-wide' ),        
      'label' => 'NIF/CIF',        
      'placeholder' => 'B12345678',        
      'required' => true,        
      'default' => $saved_license_no,        
   ), $checkout->get_value( 'license_no' ) ); 
}


/* make sure the new field is not empty */

add_action( 'woocommerce_checkout_process', 'bbloomer_validate_new_checkout_field' );
  
function bbloomer_validate_new_checkout_field() {    
   if ( ! $_POST['license_no'] ) {
      wc_add_notice( 'Por favor ingrese su número de NIF', 'error' );
   }
}



/* 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 ( $_POST['license_no'] ) update_post_meta( $order_id, '_license_no', esc_attr( $_POST['license_no'] ) );
}
 
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_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>';
}

Below I show the function to reorder the fields of the form. By default, the new field is displayed at the bottom of the form. Of course, these functions work for other users, and are available to anyone, as they show in the "Business Bloomer" tutorials and articles

Here you will find more functions where I found inspiration to reorder the payment form fields With this function, I am changing the priority and it should place the new field (NIF/CIF) , below the "Company Name (optional)" field.

add_filter( 'woocommerce_default_address_fields', 'bbloomer_reorder_checkout_fields' );
 
function bbloomer_reorder_checkout_fields( $fields ) {
 
   // default priorities:
   // 'first_name' - 10
   // 'last_name' - 20
   // 'company' - 30
   // 'country' - 40
   // 'address_1' - 50
   // 'address_2' - 60
   // 'city' - 70
   // 'state' - 80
   // 'postcode' - 90
 
  // e.g. move 'company' above 'first_name':
  // just assign priority less than 10
  $fields['license_no']['priority'] = 35;
 
  return $fields;
}

The position does not change, it is duplicated, but at the top where I need the new field to be, only the input drawer is shown, and the NIF/CIF label is not shown, and the placeholder is not shown either.

What do I need to correct in the function so that everything is displayed perfectly?

What should I do so that this field that I have created is shown only to certain users?

What should I correct in the function so that everything is displayed perfectly?

enter image description here

gemita
  • 2,686
  • 2
  • 10
  • 17
  • 3
    Use for example woocommerce_billing_fields filter to add your field in billing. Check this example - https://stackoverflow.com/questions/37729524/add-new-fields-at-the-billing-address-woocommerce. Here is a nice article how to register fields with notices and all - https://www.businessbloomer.com/woocommerce-add-custom-checkout-field-php/ . How to reorder edit fields - https://www.businessbloomer.com/woocommerce-checkout-customization/ – Snuffy Mar 14 '23 at 11:28
  • 1
    Thank you for this documentation, it is very valuable to me. I have checked, and to add the new field to the form it works, the way to do it is similar to the one I have. The problem is when I want to reorder the fields, I change their place but the label and the placeholder are not shown. Please edit the question to make it easier to identify the error. Sorry for the delay in responding @MartinMirchev, I wanted to do several tests – gemita Mar 14 '23 at 15:40
  • 1
    You can reorder fields in a group such as billing fields. So make your field part of the billing fields since you want to reorder billing fields in your example. – Snuffy Mar 15 '23 at 07:05
  • Thanks for your advice and support. I have a question, how do I do what you suggest? I remind you that the examples I use have not been created by me, I do not have much experience in this matter – gemita Mar 15 '23 at 08:15
  • 1
    Here you have an example of how to get the current user's role: https://usersinsights.com/wordpress-get-current-user-role/ Get the role, check if it's admin and then add the fields. ¡Suerte, gemita! – Eloy Ruiz Mar 16 '23 at 23:36
  • Thank you. I have reviewed the options shown in your link. I don't understand how I can use these functions to get only certain user roles to see the new field – gemita Mar 17 '23 at 15:06

1 Answers1

1

Remove add_action( 'woocommerce_before_order_notes', 'bbloomer_add_custom_checkout_field' ); and add_filter( 'woocommerce_default_address_fields', 'bbloomer_reorder_checkout_fields' ); from your code

You can use this bellow code to do all things that you need (set position of input field & show input field only for certain user role)

<?php
add_filter('woocommerce_checkout_fields', 'add_custom_woocommerce_checkout_field');
/**
 * Add a custom field for NIF/CIF to the WooCommerce checkout form
 *
 * @param array $fields An array of checkout fields
 * @return array An updated array of checkout fields with the NIF/CIF field added
 */
function add_custom_woocommerce_checkout_field( $fields ) {

    // Only add this field when user is administrator
    if ( has_user_role( get_current_user_id(), 'administrator' ) ) {

        $current_user = wp_get_current_user();
        $saved_license_no = $current_user->license_no;
    
        // Add the NIF/CIF field to the billing section of the checkout 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, // Change here to set position
        );
    }

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

/**
 * Check user role
 *
 * @param int $user_id
 * @param string $role
 * @return boolean
 */
function has_user_role( $user_id, $role ) {
    $user = get_userdata( $user_id );
    if ( ! empty( $user ) && in_array( $role, (array) $user->roles ) ) {
        return true;
    }
    return false;
}

Checkout form Image


CHECK THIS IMAGES :

Field is displayed in these :

Thankyou page after checkout

Admin order manage option

View order section in my account page

Admin email for new order

Customer email for invoice

and any other email ( New order, Cancelled order, Failed order, Order on-hold, Processing order, Completed order, Customer invoice / Order details ), in every those field is there like this two email image i've added here


NOTE : use my code with this below code that you already used in your question. I've added one more action hook in it

<?php
/* make sure the new field is not empty */
add_action( 'woocommerce_checkout_process', 'bbloomer_validate_new_checkout_field' );
function bbloomer_validate_new_checkout_field() {    
    if ( ! isset($_POST['license_no']) && has_user_role( get_current_user_id(), 'administrator' ) ) {
        wc_add_notice( 'Por favor ingrese su número de NIF', 'error' );
    }
}

/* 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['license_no']) ) update_post_meta( $order_id, '_license_no', esc_attr( $_POST['license_no'] ) );
}

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>';
}

Yash
  • 1,020
  • 1
  • 15
  • 1
    Hello @gemita, My answer is working just as you explain ..." Actually this field should not be displayed by default, it should only be visible to certain user roles if they are logged in... " in line `if ( has_user_role( get_current_user_id(), 'administrator' ) ) ` change 'administrator' with any role sulg for example : 'editor' or 'author' or 'contributor' or 'subscriber' or any other role you have and you only get this field for that user role only at chackout. This `if` condition uses `has_user_role` function that is in my answer, i've made it to check role of user. – Yash Mar 19 '23 at 18:37
  • 1
    @gemita , i've recheck my code and it working as follows : if user is administrator, in only that condition then and then only field is in checkout page , otherwise it is not there , change in `if` condition as i mention in my earlier comment and you get your desired answer , as far as i understand your problem. Reminder there is no need of those two action/filter `add_action( 'woocommerce_before_order_notes', 'bbloomer_add_custom_checkout_field' );` and `add_filter( 'woocommerce_default_address_fields', 'bbloomer_reorder_checkout_fields' );` as long as you use my answer. – Yash Mar 19 '23 at 19:26
  • 1
    @gemita, check my answer , I've added more explanations and images. I think you remove other functions too from your code and that's why field is not displayed with order detail. Don't worry about anything now just copy and paste all code in answer with your question code. And if anything other you want then I'm happy to help – Yash Mar 20 '23 at 18:26
  • Thanks again, you are amazing. In fact, I think the reward has been short. In my next query I will mention you, so that you can help me and offer a higher reward and compensate the effort you put in here. Of course, everything works perfectly, I will certainly accept your answer. I have a question, how does WooCommerce generate invoices after a customer makes a purchase? This is already a query, since the last screenshot you show is of the order invoices. Where can I read documentation about this? Is it necessary to use other plugins to generate invoices for orders made by users? Thanks again – gemita Mar 20 '23 at 21:46
  • 1
    @gemita, Thank you for your kind words. There is no need for plugin to setup basic invoice mail for customer. Check " www.yoursite.com/wp-admin/admin.php?page=wc-settings&tab=email " for email settings. if you don't need that and want something else then you need to clarify more about your email requirements. – Yash Mar 21 '23 at 17:17
  • 1
    Read these [https://woocommerce.com/posts/woocommerce-email-tools-and-integrations/](https://woocommerce.com/posts/woocommerce-email-tools-and-integrations/) and [https://woocommerce.com/posts/how-to-customize-emails-in-woocommerce/](https://woocommerce.com/posts/how-to-customize-emails-in-woocommerce/) posts , maybe it helps you to get more info about emails – Yash Mar 21 '23 at 19:44
  • 1
    @gemita, thanks for the trust you put in my work. i'll defiantly try to help as much as possible by answer or by guiding you to the reference. Please mark this answer as a right one so i can give green tick validation to my mind . XD :) – Yash Mar 22 '23 at 17:45
  • Hello. I'm sorry to bother you again @Yash . I am carrying out the card payment tests and I have a problem, since users who do not have the role of `'administrator'` are not shown the NIF field, but does not allow me to make the payment, and shows the warning message of the function `bbloomer_validate_new_checkout_field() `: **"Please enter your NIF number"** . The field is not visible to users, but it is really in the backend and does not allow payments. Is there a way to correct this ? Thank you, I beg your pardon, I did not do all the necessary tests before accepting your answer – gemita Mar 24 '23 at 15:03
  • 1
    @gemita, I am working on it. no need to worry. – Yash Mar 24 '23 at 20:42
  • 1
    @gemita, Check now , I've made change in `bbloomer_validate_new_checkout_field()` and `bbloomer_save_new_checkout_field()`. It's my fault in first place to give you code that has bug in it. – Yash Mar 24 '23 at 21:06
  • Hello, sorry to bother you again @Yash . I've created new fields from the results of this question and your answer was the one that helped me, maybe you could check and see if I can get what I'm [looking for in this new question on WooCommerce](https://stackoverflow.com/questions/76089977/how-to-show-the-data-of-the-new-fields-in-the-woocommerce-billing-data) . It is only a comment since you handled yourself very well in this question and if you have a little of your time, I would appreciate your visit to the question. Thanks again – gemita Apr 24 '23 at 08:43