Choose role in register form (Woocommerce) - wordpress

I'm building a site using Wordpress and WooCommerce. This site need to have 2 types of clients:
Normal customer (default customer of woocommerce)
B2B customer (this user have different prices and aditional products)
I need a checkbox to appear on the registration form.
When the user marks that checkbox, the b2b role would be assigned and additional fields would appear to complete the registration.
EDIT
I'm triying whit this code:
/*checkbox*/
add_action('woocommerce_after_checkout_billing_form', 'mostrar_campo_nif_profesionales');
function mostrar_campo_nif_profesionales( $checkout ) {
echo '<div id="mostrar_campo_nif_profesionales"><h3>'.__('¿Eres un profesional?').'</h3>';
woocommerce_form_field( 'check_profesional', array(
'type' => 'checkbox',
'class' => array('checkbox-profesionales form-row-wide'),
'label' => __('Profesional?'),
'required' => false,
), $checkout->get_value( 'profesional' ));
echo '</div>';
}
/*the field must appears when the checkbox are checked*/
if ("DON'T KNOW WHAT CONDITION MUST BE WRITE HERE") {
/*** Añadir campo personalizado a página de checkout ***/
add_action('woocommerce_after_checkout_billing_form', 'campo_nif_profesionales');
function campo_nif_profesionales( $checkout ) {
echo '<div id="campo_nif_profesionales"><h3>'.__('NIF/CIF').'</h3>';
woocommerce_form_field( 'NIF', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('NIF/CIF'),
'placeholder' => __('Introduzca su NIF/CIF'),
'required' => true,
), $checkout->get_value( 'NIF' ));
echo '</div>';
}
/*** Validación del campo personalizado ***/
add_action('woocommerce_checkout_process', 'campo_nif_profesionales_process');
function campo_nif_profesionales_process() {
global $woocommerce;
// Comprobar si el campo ha sido completado, en caso contrario agregar un error.
if (!$_POST['NIF'])
$woocommerce->add_error( __('Por favor introduce tu NIF o CIF.') );
}
/*** Incluir campo personalizado a formato de orden ***/
add_action('woocommerce_checkout_update_order_meta', 'campo_nif_profesionales_update_order_meta');
function campo_nif_profesionales_update_order_meta( $order_id ) {
if ($_POST['NIF']) update_post_meta( $order_id, 'NIF/CIF', esc_attr($_POST['NIF']));
}
/*** Incluir campo personalizado a correos electrónicos de órdenes ***/
add_filter('woocommerce_email_order_meta_keys', 'campo_nif_profesionales_order_meta_keys');
function campo_nif_profesionales_order_meta_keys( $keys ) {
$keys[] = 'NIF/CIF';
return $keys;
}
}
But now the problem is only show the text field when the users chek the checkbox

Part 1.
At the start there are two options,
Add fields you need at the Start of the page
Add fields that you need at the End of the Page.
This can be done by woocommerce_register_form_start hook or woocommerce_register_form.
Here , the only way I can think of is to by default include the fields for all but only reveal them by JS / JQ when used click on the check box.
This would fix the part of adding the fields.
Part 2.
Validation of the Submitted form
Use the Hook woocommerce_register_post and then get hold of the registration data that is sent back to the server. And Validate it from server side as well. Say if the box is checked and all the related fields have the necessary data as well and sanitize the fields as well.
Part 3.
Now add the additional Data as well as the additional role to the user.
Now use the user_register hook and get hold of the newly registered user's ID. And then add the new data in there.
A bit of caution is suggested, as this hook is fired on every user register so first add a validation to check that this user is a customer , and then check that this user is registered via the front end form, this is can normally be done by checking the $_POST variable.
Use the wp_update_user and add_role function to achieve this.
Sample Code for part 3
function add_user_additional_details_frontend_reg( $user_id )
{
$registered_user = get_user_by('ID',$user_id);
if($registered_user) {
$user_role = $registered_user->roles;
if((in_array('customer', (array) $user_role))){
/* The field below "front_end_cust_form" is just a hidden field I added to check and make sure that this is coming from the Front end Reg form where I added the additional fields */
if($_POST['front_end_cust_form'] == 'front_end_cust_form')
{
$first_name = $_POST['billing_first_name'];
$last_name = $_POST['billing_last_name'];
update_user_meta($user_id, 'billing_first_name', $first_name);
update_user_meta($user_id, 'billing_last_name', $last_name);
$update_data = array(
'ID' => $user_id,
'first_name' => $first_name,
'last_name' => $last_name
);
$user_id = wp_update_user($update_data);
$registered_user->add_role('custom_role');
}
}
}
}
add_action( 'user_register', 'add_user_additional_details_frontend_reg', 10, 1 );
Hope this helps.

Related

Wordpress: save custom billing field in account Billing address

Using Wordpress/Woocommerce.
I have this code which adds a custom billing field in checkout page called: "NIF/CIF". It works fine but its value it not saved in the customer account "Billing Address" data.
Once the customer makes a first order all billing address values are saved in his account: Address, State, Country, etc. But my custom field is not saved.
I guess that in my function is missing a line of code to save its value in the database, but I don't know how to start with this.
/*******************************
CUSTOM BILLING FIELD
*********************************/
add_filter('woocommerce_billing_fields', 'custom_woocommerce_billing_fields');
function custom_woocommerce_billing_fields($fields)
{
$fields['nif_cif'] = array(
'label' => __('NIF/CIF', 'woocommerce'), // Add custom field label
'placeholder' => _x('NIF/CIF', 'placeholder', 'woocommerce'), // Add custom field placeholder
'required' => true, // if field is required or not
'clear' => false, // add clear or not
'type' => 'text', // add field type
'class' => array('my-css') // add class name
);
return $fields;
}
Here is an example of how to save your custom field:
add_action( 'woocommerce_checkout_order_processed', 'prefix_save_field_on_checkout', 11, 2 );
function checkout_order_processed_add_referral_answer( $order_id, $posted ) {
if ( ! isset( $_POST['nif_cif'] ) ) {
return;
}
$order = wc_get_order( $order_id );
// WC < 3.0
update_post_meta( $order->id, 'order_meta_field_name', wc_clean( $_POST['nif_cif'] ) );
// WC > 3.0
$order->add_meta_data( 'order_meta_field_name', wc_clean( $_POST['nif_cif'] ), true );
$order->save();
}
Adding an extra field through 'woocommerce_billing_fields' hook is not enough. you are missing out two things.
Proper validation of NIF/CIF field using
'woocommerce_after_checkout_validation' hook
Saving data in order
using 'woocommerce_checkout_order_processed' hook

Woocommerce hide payment when is checked checkbox

I need to hide the payment method "Bank transfer" when checkbox is checked in checkout form.
My code for adding checkbox in checkout:
https://gist.github.com/thegdshop/3171026
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
echo '<div id="my-new-field"><h3>'.__('My Checkbox: ').'</h3>';
woocommerce_form_field( 'my_checkbox', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('I have read and agreed.'),
'required' => true,
), $checkout->get_value( 'my_checkbox' ));
echo '</div>';
}
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error.
if (!$_POST['my_checkbox'])
$woocommerce->add_error( __('Please agree to my checkbox.') );
}
add_action('woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta( $order_id ) {
if ($_POST['my_checkbox']) update_post_meta( $order_id, 'My Checkbox', esc_attr($_POST['my_checkbox']));
}
In this situation you can use ajax. The approach is
Prehide the Bank transfer Payment on page load.
Write a code in jQuery to Unhide and hide 'Bank transfer' payment method.
That's it.
Let me know if that solves your problem.

Adding User Profile Fields to Wordpress Buddypress to Include "Favorites"

I'm trying to figure out a way for members on my Wordpress (Buddypress) site to pick their "favorite movies, books, etc."
It would be nice if, instead of members simply typing a list of these things, they could select from books already in the system, and add more as the please in the future.
I'm hoping that there is an easy answer to this, such as a plugin that I can use, or, at least, modify. Does anyone know of anything that I can look into?
Your title asks how to add a user profile field. Here is the code to add as many fields as you like. Once you add the field, you can easily place additional inputs or options on the custom tab page for users to enter their own favorites.
function my_test_setup_nav() {
global $bp;
$parent_slug = ‘test’;
$child_slug = ‘test_sub’;
//name, slug, screen, position, default subnav
bp_core_new_nav_item( array(‘name’ => __( ‘Test’ ),’slug’ => $parent_slug,’screen_function’ => ‘my_profile_page_function_to_show_screen’,'position’ => 40,’default_subnav_slug’ => $child_slug ) );
/* Add the subnav items to the profile */
// name, slug, parent_url, parent slug, screen function
bp_core_new_subnav_item( array( ‘name’ => __( ‘Home’ ), ‘slug’ => $child_slug, ‘parent_url’ => $bp->loggedin_user->domain . $parent_slug.’/', ‘parent_slug’ => $parent_slug, ‘screen_function’ => ‘my_profile_page_function_to_show_screen’ ) );
bp_core_new_subnav_item( array( ‘name’ => __( ‘Random Page’ ), ‘slug’ => ‘random’, ‘parent_url’ => $bp->loggedin_user->domain . $parent_slug.’/', ‘parent_slug’ => $parent_slug, ‘screen_function’ => ‘my_profile_page_function_to_show_screen234′ ) );
}
function my_profile_page_function_to_show_screen() {
//add title and content here – last is to call the members plugin.php template
add_action( ‘bp_template_title’, ‘my_profile_page_function_to_show_screen_title’ );
add_action( ‘bp_template_content’, ‘my_profile_page_function_to_show_screen_content’ );
bp_core_load_template( apply_filters( ‘bp_core_template_plugin’, ‘members/single/plugins’ ) );
}
function my_profile_page_function_to_show_screen_title() {
echo ‘wptaskforce title’;
}
function my_profile_page_function_to_show_screen_content() {
echo ‘wptaskforce content’;
}
//random page content:
function my_profile_page_function_to_show_screen234() {
//add content here – last is to call the members plugin.php template
add_action( ‘bp_template_content’, ‘my_profile_page_function_to_show_screen234_content’ );
bp_core_load_template( apply_filters( ‘bp_core_template_plugin’, ‘members/single/plugins’ ) );
}
function my_profile_page_function_to_show_screen234_content() {
echo ‘This is a random page.’;
}
add_action( ‘bp_setup_nav’, ‘my_test_setup_nav’ );

Add Tax Exempt form on checkout in woocommerce

I am trying to add a form to my checkout page so when a user clicks the 'Tax Exempt' checkbox, a textbox will popup and ask the user what the Tax Exempt Id number is.
I got all of that working great, and I even added the update_totals_on_change class to my form field so it will update the totals.
My next step was to add an action/filter on a method so when the update_totals_on_change executes, I can set the tax to 0 and then it will finish calculating the total.
Does anyone know which functions I can hook on to?
Looking at the checkout.js file in WooCommerce, they set the action to woocommerce_update_order_review for the ajax operation.
I tried following that but soon got lost.
I was thinking I could add some post data by hooking in to woocommerce_checkout_update_order_review
and then hooking in to woocommerce_before_calculate_totals to modify the tax stuff, but I have no idea what I need to modify.
Am I even on the right path?
Alright, I finally figured it out in case anyone is interested.
In my plugin, I made a form after the order notes by hooking in to this function: 'woocommerce_before_order_notes'
add_action('woocommerce_before_order_notes', array(&$this, 'taxexempt_before_order_notes') );
my 'taxexempt_before_order_notes' function contained:
function taxexempt_before_order_notes( $checkout ) {
echo '<div style="clear: both"></div>
<h3>Tax Exempt Details</h3>';
woocommerce_form_field( 'tax_exempt_checkbox', array(
'type' => 'checkbox',
'class' => array('tiri taxexempt'),array( 'form-row-wide', 'address-field' ),
'label' => __('Tax Exempt'),
), $checkout->get_value( 'tax_exempt_checkbox' ));
woocommerce_form_field( 'tax_exempt_name', array(
'type' => 'text',
'class' => array('form-row-first', 'tiri', 'taxexempt', 'textbox', 'hidden'),
'label' => __('Tax Exempt Name'),
), $checkout->get_value( 'tax_exempt_name' ));
woocommerce_form_field( 'tax_exempt_id', array(
'type' => 'text',
'class' => array('form-row-last', 'tiri', 'taxexempt', 'textbox', 'hidden', 'update_totals_on_change'),
'label' => __('Tax Exempt Id'),
), $checkout->get_value( 'tax_exempt_id' ));
}
Then the most important woocommerce function to hook was: 'woocommerce_checkout_update_order_review'
add_action( 'woocommerce_checkout_update_order_review', array(&$this, 'taxexempt_checkout_update_order_review' ));
function taxexempt_checkout_update_order_review( $post_data ) {
global $woocommerce;
$woocommerce->customer->set_is_vat_exempt(FALSE);
parse_str($post_data);
if ( isset($tax_exempt_checkbox) && isset($tax_exempt_id) && $tax_exempt_checkbox == '1' && !empty($tax_exempt_id))
$woocommerce->customer->set_is_vat_exempt(true);
}
I simply parsed out the $post_data that is the serialized form data from the checkout.js file in woocommerce and checked if my part of the form was filled out correctly.
If it was, then I would set the tax exempt for the user.
The accepted solution didn't work for me, but I modified it to use the following:
//=============================================================================
// ADD TAX EXEMPT CHECKMARK
// =============================================================================
add_action( 'woocommerce_after_order_notes', 'qd_tax_exempt');
function qd_tax_exempt( $checkout ) {
echo '<div id="qd-tax-exempt"><h3>'.__('Tax Exempt').'</h3>';
woocommerce_form_field( 'shipping_method_tax_exempt', array(
'type' => 'checkbox',
'class' => array(),
'label' => __('My organization is tax exempt.'),
'required' => false,
), $checkout->get_value( 'shipping_method_tax_exempt' ));
echo '</div>';
}
add_action( 'woocommerce_checkout_update_order_review', 'taxexempt_checkout_update_order_review');
function taxexempt_checkout_update_order_review( $post_data ) {
global $woocommerce;
$woocommerce->customer->set_is_vat_exempt(FALSE);
parse_str($post_data);
if ( isset($shipping_method_tax_exempt) && $shipping_method_tax_exempt == '1')
$woocommerce->customer->set_is_vat_exempt(true);
}
The key here is understanding that any field with a name that starts with shipping_method is going to inherit this updating order functionality (which was the part that didn't work for me). I found this answer at http://www.affectivia.com/blog/have-a-checkbox-on-the-checkout-page-which-updates-the-order-totals/
After a long search I found that there is a method for the cart object called remove_taxes() .
So, after setting a user meta for the tax exempt users, this cancels the tax totals.
function remove_tax_for_exempt( $cart ) {
global $current_user;
$ok_taxexp = get_the_author_meta( 'granted_taxexempt', $current_user->ID );
if ($ok_taxexp){ // now 0 the tax if user is tax exempt
$cart->remove_taxes();
}
return $cart;
}
add_action( 'woocommerce_calculate_totals', 'remove_tax_for_exempt' );
Because $cart->remove_taxes(); is deprecated. This is what I used instead.
I didn't have a form on the frontend, but have a user roll that is tax exempt. This was my solution.
Also worth noting that set_is_vat_exempt(true) also works in the US to set as tax exempt.
/**
* Set customer as tax exempt if user is a wholesale customer
*/
function remove_tax_for_exempt( $cart ) {
global $woocommerce;
if ( is_user_logged_in() && current_user_can( 'wholesale_customer' ) ) {
$woocommerce->customer->set_is_vat_exempt(true);
}
return $cart;
}
add_action( 'woocommerce_calculate_totals', 'remove_tax_for_exempt' );
Since this answer still pops up on google, I thought I'd share that setting the customer as tax exempt only works during checkout, if you need to edit the order on the back-end after it is placed and use the "recalculate" button, the taxes will still appear. Fortunately there is a hook for this as well:
function remove_tax_for_exempt($exempt, $order){
return $exempt || user_can($order->get_user_id(), 'wholesale_customer');
}
add_filter('woocommerce_order_is_vat_exempt', 'remove_tax_for_exempt', 10, 2);

Show custom field on order in woocommerce

Im working on a webshop and follwoing this tutorial http://wcdocs.woothemes.com/snippets/tutorial-customising-checkout-fields-using-hooks-and-filters/ to add some customes fields to my billing.
// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields['billing']['billing_gls_name'] = array(
'label' => __('Name for pickup person', 'woocommerce'),
'placeholder' => _x('Name', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
This adds my field. So far so good. So my problem is:
How can I view this new field in the orders view? Details for billing only show the usual billing fields.
The first answer (Cesar) was CLOSE to being correct. In case anyone ever comes across this old post trying to find out the same thing, below is the code needed to insert into your functions.php file after the code given by the original poster, tailored to his/her variables as provided. Note that they use the field name "billing_gls_name" and that this is referenced in our new function as "_billing_gls_name". The extra "_" at the beginning is necessary. This works on Wordpress 3.5.1 running WooCommerce 2.0.3.
function your_custom_field_function_name($order){
echo "<p><strong>Name of pickup person:</strong> " . $order->order_custom_fields['_billing_gls_name'][0] . "</p>";
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'your_custom_field_function_name', 10, 1 );
After defining your custom field (that you did in your code mentioned above), add the code mentioned below to:
Process your field
Save it in the database as Order meta data
Display it in the 'Order details' in the Woocommerce->Orders section
Process your field:
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
if (!$_POST['billing']['billing_gls_name']) {
wc_add_notice(__('Please tell us the Location Type that we are billing to.'), 'error');
}
}
Save Field in the DB as Order Meta Data:
add_action('woocommerce_checkout_update_order_meta','my_custom_checkout_field_update_order_meta');
function my_custom_checkout_field_update_order_meta($order_id) {
if (!empty($_POST['billing']['billing_gls_name'])) {
update_post_meta($order_id, 'Billing Gls Name', esc_attr($_POST['billing']['billing_gls_name_type']));
}
}
And finally display it in the Order details screen:
add_action('woocommerce_admin_order_data_after_billing_address', 'my_custom_billing_fields_display_admin_order_meta', 10, 1);
function my_custom_billing_fields_display_admin_order_meta($order) {
echo '<p><strong>' . __('Billing Gls Name') . ':</strong><br> ' . get_post_meta($order->id, '_billing_gls_name', true) . '</p>';
}
Adding the action woocommerce_admin_order_data_after_billing_address you can insert some data after billing info. Custom fields are under $order->order_custom_fields array.
function display_rfc_in_order_metabox($order){
echo "<p><strong>RFC:</strong> {$order->order_custom_fields['_billing_rfc'][0]}</p>";
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'rxm_details_to_order', 10, 1 );

Resources