I would like to add also a field to enter the VAT number when doing a checkout.
What is the most appropriate method and is this even possible ?

I tried to add it to an order, but it's not shown in checkout. Under the checkout settings I don't find a place where I can add extra information. The VAT number would actually be a billing information property to be good. If not possible, I would just like to add it separately on the checkout field.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

rszrama’s picture

Status: Active » Fixed

The easiest thing to do is add a VAT field to your Billing information customer profile type. Then it will show up on the checkout form, on the order view / edit pages, and in Rules data selectors and such.

JGO’s picture

Thanks a lot, this is perfect!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

applynx’s picture

This solution seems to work because the VAT field is tied to the customer. Is there an easy way to include a field that will vary from order to order? My particular case involves a shopping cart where the customer can assign his own internal PO# to every order.

Thanks in advance!

applynx’s picture

Status: Closed (fixed) » Needs review

Just an update for anybody who needs a custom field that does not really belong in the customer billing profile (in my example, a PO# that the customer can enter for the order).

I installed Commerce Fieldgroup Panes (http://drupal.org/project/commerce_fieldgroup_panes) and added a field to the order entity (store -> configuration -> order settings). In manage fields, create a field group, then create a field and add it to the field group by dragging it under the field group and to the right (you will see a slight indent before releasing).

Then, in store -> configuration -> checkout settings you will see an unassigned pane with the name of the fieldgroup you just created. You can drag this pane into any step of the checkout, and the user-entered value of your field will be automatically added to the order object.

I hope this helps and that I am not violating board protocol by replying to a closed article. Like everything in drupal, this solution was awesome once I figured out what to do, but getting to that point was an adventure.

rszrama’s picture

Status: Needs review » Fixed

Ahh, awesome! I didn't know there was already a module for this out there - I'd been wanting to author one similar for some time. Glad to see hunziker beat me to it. : )

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

pardalman’s picture

Almost what I need...
I would need this functionality but I need a diferent field to every line product in the order. I'm trying to add a date field to every product (selling tours).

Any ideas?

Thanks in advance.

P.S.: I guess in the worst case I could use this solution to add two different fields "start date" and "end date" since usually the customer will enjoy all the services bought in the order within this date range but would be a poor solution and it would need extra efforts contacting the customer to know the date for every service bought.

P.S.(2): Hope I explained my problem properly...

pardalman’s picture

SOLVED

"You can add a date field to your product line item type and expose that to the Add to Cart form. It's fairly new functionality, so it may not be documented."
Answered in: How to add a selectable date to a product without replicating SKU product

Fonkel’s picture

This looks almost as what I need:
I want to handle registrations for courses through commerce.
But some courses require extra information like 'name of children attending' while other courses (products) require the name of the partner / spouse.
How can I do this?

svouthi’s picture

Issue summary: View changes

@applynx, thank you so much for posting your solution. Your step by step account of how you set up your field groups is also appreciated, as it took me a moment to understand what was necessary.

@StudioFonkel, if you didn't already solve your problem years ago, you might try Commerce Extra Panes and Commerce Rules Extra modules to show your fields in a conditional checkout pane.

wesleymusgrove’s picture

I needed to accept an optional phone number during checkout, but I didn't think the phone number field really belonged in the Billing Information pane. As you can see in the attached image, I wanted the phone number field to show up below the email address in the Account Information pane, which I renamed "Contact Information". Commerce User Profile Pane, Commerce Fieldgroup Panes, and Address Field Phone were all too feature-rich for my needs. I just wanted to simply add one field to the Account Information pane, validate and save it to the order, thereby persisting it through the checkout.

In my case, the simplest solution was to save the phone number in the $order->data array by adding a form field to the checkout form using hook_form_alter. Before saving it into the $order->data array, I do some validation stripping and formatting on future display.

<?php

/**
 * Implements hook_form_alter
 * Alter the checkout and review forms
 */
function example_form_alter(&$form, &$form_state, $form_id) {
  
  if ($form_id == 'commerce_checkout_form_checkout') {
    //Changing some titles and adding Bootstrap wrapper classes
    $form['account']['#title'] = t('Contact Information');
    $form['account']['login']['mail']['#title'] = t('Email Address');
    $form['account']['login']['mail']['#prefix'] = '<div class="row"><div class="col-xs-12 col-sm-5">';
    $form['account']['login']['mail']['#suffix'] = '</div></div>';
    $form['account']['login']['mail_confirm']['#title'] = t('Confirm Email Address');
    $form['account']['login']['mail_confirm']['#description'] = t('<small>Please re-enter your email address.</small>');
    $form['account']['login']['mail_confirm']['#prefix'] = '<div class="row"><div class="col-xs-12 col-sm-5">';
    $form['account']['login']['mail_confirm']['#suffix'] = '</div></div>';

    //add a phone number textfield to the account login array
    $form['account']['login']['phone_number'] = array(
      '#type' => 'textfield',
      '#title' => t('Phone Number (Optional)'),
      '#size' => 15,
      '#attributes' => array('class' => array('phone-number')),
      '#prefix' => '<div class="row"><div class="col-xs-12 col-sm-5">',
      '#suffix' => '</div></div>',
    );

    //load the order from the form state
    if ($form_state['order']->order_id) {
      $form_state['order'] = commerce_order_load($form_state['order']->order_id);

      $order = $form_state['order'];

      //prefill the phone number field if it's already been set in the data array
      if (!empty($order->data['phone_number'])) {
        $form['account']['login']['phone_number']['#default_value'] = _format_phone_number($order->data['phone_number']);
      }
    }

    //add a custom submit callback function to save the phone number to the order data array
    array_unshift($form['buttons']['continue']['#submit'], "_example_commerce_order_account_pane_checkout_form_alter_submit");
  }

  //show the phone number in the account info section of the review screen
  if ($form_id == 'commerce_checkout_form_review') {
    //load the order from the form state
    if ($form_state['order']->order_id) {
      $form_state['order'] = commerce_order_load($form_state['order']->order_id);

      $order = $form_state['order'];

      //append the phone number to the account info html. there's probably a better way to do this...
      if (!empty($order->data['phone_number'])) {
        $form['checkout_review']['review']['#data']['account']['data'] .= '<div class="form-item form-type-item"><label>Phone Number: </label> '._format_phone_number($order->data['phone_number']).'</div>';
      }
    }
  }
}

/**
 * Custom Account pane: checkout form submission callback.
 */
function _example_commerce_order_account_pane_checkout_form_alter_submit($form, &$form_state) {
  if (!empty($form_state['values']['account'])) {
    $pane_values = $form_state['values']['account'];

    // If the user is editing an order, load a fresh copy to merge changes into.
    if ($form_state['order']->order_id) {
      $form_state['order'] = commerce_order_load($form_state['order']->order_id);
    }

    $order = $form_state['order'];

    if (!empty($pane_values['login']['phone_number'])) {
      $order->data['phone_number'] = _strip_chars_in_phone_number($pane_values['login']['phone_number']);
    }
    else {
      $order->data['phone_number'] = '';
    }

    //don't cut a new revision, just save phone number
    $order->revision = FALSE;
    commerce_order_save($order);
  }
}

/**
 * Custom utility function to strip invalid characters from phone number input
 * leaving only digits
 * stripping a leading 1
 * substring first 10 digits
 */
function _strip_chars_in_phone_number($phone) {
  $strPhoneDigits = '';

  if (isset($phone) && !empty($phone)) {
    $strPhoneDigits = preg_replace("/[\D]/", "", $phone);
    $strPhoneDigits = preg_replace("/^1/", "", $strPhoneDigits);
    $strPhoneDigits = substr($strPhoneDigits, 0, 10);
  }

  return $strPhoneDigits;
}

/**
 * Custom utility function to format a phone number for display
 */
function _format_phone_number($phone) {
  $strFormattedPhone = '';

  if (isset($phone) && !empty($phone)) {
    if (strlen($phone) == 7) {
      $strFormattedPhone = preg_replace("/([0-9]{3})([0-9]{4})/", "$1-$2", $phone);
    }
    elseif (strlen($phone) == 10) {
      $strFormattedPhone = preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "($1) $2-$3", $phone);
    }
    else {
      $strFormattedPhone = $phone;
    }
  }

  return $strFormattedPhone;
}

?>
drupalevangelist’s picture

Hi,

I am trying to add an custom input field for TIP Amount on a checkout page. Any suggestions?

Thanks.