If the total cart value is 0 then the billing fields should be un-required.

Should the billing pane just be hidden or are there reasons it may be required by some users? Maybe the option to hide should be configurable?

Comments

Critical Tinkerer’s picture

If the billing pane is hidden, I'm curious how the checkout is handled on this.... otherwise items would stay in the cart, no?

rszrama’s picture

Version: 5.x-1.0 » 6.x-1.0-beta1
Assigned: Unassigned » rszrama

I think it can be hidden as long as we make sure the module alters the #required field for the form elements. I've done this in a custom job for a site in the past, so I'm sure I can manage. Good feature request. I am going to move it to the current branch, though.

md2’s picture

can this be added to the drupal 5 branch also?

budda’s picture

Version: 6.x-1.0-beta1 » 5.x-1.0

The uc_free_order.js needs a function amending:

<?php
/**
 * Checks the current total and updates the available/selected payment methods
 * accordingly.
 */
function free_order_check_total(total) {
  total = parseFloat(total);

  if (total >= .01) {
    // Disable the free order option and select the first available method.
    if (using_free_order == 0) {
      // Show the other payment method radios.
      $("#payment-pane .form-radios input:radio").removeAttr('disabled').parent().show(0);

      // Hide the free order radio.
      $("input:radio[@value=free_order]").attr('disabled', 'disabled').parent().hide(0);

      // Find first available payment option
      var firstmethod = $(':radio[name="panes[payment][payment_method]"]:first');
      uc_free_order_next_method = firstmethod.val();

      // Select the first payment method.
      $("input:radio[@value=" + uc_free_order_next_method + "]").attr('checked', 'checked');

      // Refresh the payment details section.
      get_payment_details('cart/checkout/payment_details/' + uc_free_order_next_method);
    } else {
      using_free_order = 0;
    }
  }
  else {
    // Disable the CC option and select the gift card option.
    if (using_free_order != 1) {
      // Hide the fallback payment method radio.
      $("#payment-pane .form-radios input:radio").attr('disabled', 'disabled').parent().hide(0);
      
      // Show and select the gift card.
      $("input:radio[@value=free_order]").removeAttr('disabled').attr('checked', 'checked').parent().show(0);

      // Refresh the payment details section.
      get_payment_details('cart/checkout/payment_details/free_order');

      using_free_order = 1;
    }
  }
}
?>

Then in the module, replace the hook_form_alter() function with:

<?php
/**
 * Implementation of hook_form_alter().
 */
function uc_free_order_ixis_form_alter($form_id, &$form) {
  global $user;

  // Alter the checkout form to prepare it for our special JS.
  if ($form_id == 'uc_cart_checkout_form' && isset($form['panes']['payment'])) {
    if (user_access('test free order')) {
      drupal_set_message('Test free order: <span style="cursor: pointer;" onclick="alert(\'Discount added.\'); set_line_item(\'fo_discount\', \'Test Discount\', -2000, 0);">Add discount</span> | <span style="cursor: pointer;" onclick="alert(\'Discount removed.\'); remove_line_item(\'fo_discount\');">Remove discount</span>');
    }

    drupal_add_js(drupal_get_path('module', 'uc_free_order') .'/uc_free_order.js');

    $set = FALSE;
    foreach (array_keys($form['panes']['payment']['payment_method']['#options']) as $key) {
      if ($key !== 'free_order' && !$set) {
        drupal_add_js("uc_free_order_ixis_next_method = '". $key ."';", 'inline');
        $set = TRUE;
      }
    }
        
    $cart_value = uc_free_order_calc_cart_total();
    if ($cart_value == 0) {
      unset($form['panes']['billing']);
    }
    
  }
  elseif ($form_id == 'uc_cart_checkout_review_form') {
    $order = uc_order_load($_SESSION['cart_order']);

    if ($order->payment_method == 'free_order') {
      if ($cart_value >= .01) {
        drupal_set_message(t('We cannot process your order without payment.'), 'error');
        drupal_goto('cart/checkout');
      }
    }
  }
}
?>

I've only tested this against 5.x UC 1.x

les lim’s picture

subscribing.

micheleannj’s picture

subscribing...

I've done it in the past to just add $form['panes']['billing']['#access'] = FALSE; to a module, but now I'm using uc_coupons and that solution doesn't work...

j9’s picture

Great feature request.

What is currently the easiest way to hack it so that billing doesnt show and isnt required?

El Bandito’s picture

Yep, I'd like this too i.e. no billing information if the order is free. For 6.x version. Any chance of a new release ?

Thanks for all your efforts,

El B

rastarr’s picture

Subscribing.

Any idea when this feature is likely to be added? Seems like the request has been asked many times in the past but without any action.

Anyone?

john franklin’s picture

StatusFileSize
new521 bytes

The attached patch seems to work for 6.x. I'm not very familiar with Drupal & Ubercart programming, so I'd appreciate it if someone more expert could look it over.

panthar’s picture

@John Franklin

This patch does not work, at least for new versions of ubercart.

Reason is, the $order array is not created (and so $_SESSION['cart_order'] is therefore not set) the first time they goto the check out page.

The $order array seems to be created at the checkout review, and subsequently, $_SESSION['cart_order'] is populated.

So the patch you provided only works if they have gone to the review page and then continue shopping -- Not what I (and probably most of us) need.

Looking into how else to solve this for 6.x so that this does not occur. Will post code as soon as I got it.

Thanks.

panthar’s picture

Well that did not take Long,
JUST BELOW (around line 32)
drupal_add_js(drupal_get_path('module', 'uc_free_order') .'/uc_free_order.js');

INSERT:

$cart_contents = uc_cart_get_contents(uc_cart_get_id());
$item_total=0;
foreach($cart_contents as $item){
$item_total += $item->price;
}
if ($item_total == 0) {
unset($form['panes']['billing']);
}

Since the $order array is not created on the checkout pane I alluded to in the last thread, if you want to disable billing properly (so that it works the first time you goto the check out page), we have no choice but to find the price from the cart items like I did here. Obviously there may be a slight performance slow-down, since we have to load the items and parse them.

Thanks.

john franklin’s picture

So the patch you provided only works if they have gone to the review page and then continue shopping -- Not what I (and probably most of us) need.

Is it sufficient to just review the cart, or does there have to be another page view somewhere? I have this on a site combined with uc_signup, which introduces some intermediate screens between the review and checkout pages to handle the signup pieces. That would explain why it works fine on my site but not elsewhere.

Thanks for looking into this.

john franklin’s picture

StatusFileSize
new822 bytes

This patch attached is the code in #12 with indentation and spacing cleaned up. I've tested it on my site and it works fine, both with zero-dollar and non-zero-dollar orders.

john franklin’s picture

BTW, the patch in #14 is against 6.x-1.0-beta4.

scotwith1t’s picture

Version: 5.x-1.0 » 6.x-1.0-beta4
Status: Active » Reviewed & tested by the community

#14 works perfectly. thanks john. i don't think this will be added permanently, but i set to RTBC just in case ryan looks at this module again some day :) it makes sense to me though...if it's a free order, why show the billing pane at all.

socialnicheguru’s picture

I am using uc_signup with this module. this patch is what I need.
Is there a way to remove the billing page and even the order verification screen for a free order? would I have to use something like cart links?

scotwith1t’s picture

i'm with socialnucheguru, how would you take this a couple steps further and let the checkout process end right there on the checkout screen and not have to go to review the order or at least remove the billing info from the review screen?

john franklin’s picture

There is a pretty massive alteration I would like to see to the process that better handles use cases where UC Restrict Qty, UC Price Per Role, UC Signup and UC Free Order are all active.

  • Member signs up self for free (member rate), single-click, no checkout.
  • Member signs up self for free member rate, adds guest at guest-of-member rate, regular checkout.
  • Guest signs up self for regular rate, regular checkout

Right now, UC Price Per Role gives guests the member's rate, not the regular rate and all of our members have to go through six screens to signup themselves for a free-for-members event.

stvnjhncndy’s picture

I'm with #17 and #18. When I complete a free order after the review page, I still get a required fields error message from the billing information. The order is submitted fine, but could be confusing to an end user. I'd like to be able to skip the review page and have no errors appear.

janton’s picture

yes i also like #17 and #18
but what to do with anonymous users registration?

Perhaps this is off-topic:
I also think the price is strainge $0.00 perhaps change it to text "Free" or "Free-Trail" or a option to put that text in yourself (as admin)

sshhll’s picture

Hi,
Would you point me the right direction on where i should Insert this hack?

Thanks,
Sam

sshhll’s picture

Component: User interface » Code
Assigned: rszrama » Unassigned

Hello,
Now i place this #10 John's hack and my billing panes disappear before the coupon applies.
Can some one point me to the right direction?

$order = uc_order_load($_SESSION['cart_order']);
if ($order->order_total == 0) {
unset($form['panes']['billing']);
}

Jonh's second hack doesn't work for me.

I don't have any recurring billing or anything. Just wanted to skip the billing if the customer use the coupon and if the total order come out to $0.

Also, no tax on my product and not using any uc_signup.

Please advice.

aLearningGuy’s picture

How can we suppress the billing field should a coupon (uc_coupon) bring the price down to 0?

aLearningGuy’s picture

Here's what I did, if anyone has a cleaner way let me know - this basically repopulates the billing fields and then hides them when the coupon is applied - thus getting around the "required field" problem.

modify the uc_free_order.js as follows:

function free_order_check_total(total) {
  total = parseFloat(total);

  // Disable the free order option and select the first available method.
  if (total >= .005 && (using_free_order != false || free_order_initialized == false)) {
    // Show the other payment method radios.
    $("#payment-pane .form-radios input:radio").removeAttr('disabled').parent().show(0);

    // Hide the free order radio.
    $("input:radio[value=free_order]").attr('disabled', 'disabled').parent().hide(0);

    // Find the first available payment method.
    var uc_free_order_next_method = $(':radio[name="panes[payment][payment_method]"]:enabled:first').val();

    // Select the first payment method.
    $("input:radio[value=" + uc_free_order_next_method + "]").attr('checked', 'checked');

    // Refresh the payment details section.
    get_payment_details(Drupal.settings.ucURL.checkoutPaymentDetails + uc_free_order_next_method);
//PATCH - Begin, Hide Billing Pane
    
    $("#edit-panes-billing-billing-first-name").val('');
    $("#edit-panes-billing-billing-last-name").val('');
    $("#edit-panes-billing-billing-company").val('');
    $("#edit-panes-billing-billing-street1").val('');
    $("#edit-panes-billing-billing-city").val('');
    $("#edit-panes-billing-billing-zone").val('');
    $("#edit-panes-billing-billing-postal-code").val('');
    $("#edit-panes-billing-billing-phone").val('');
    $("#billing-pane").attr('disabled', 'disabled').show(0);
    //PATCH - END 
    using_free_order = false;
  }
  else if (total < .005 && using_free_order != true) {
    // Hide the fallback payment method radio.
    $("#payment-pane .form-radios input:radio").attr('disabled', 'disabled').parent().hide(0);

    // Show and select the free order payment method.
    $("input:radio[value=free_order]").removeAttr('disabled').attr('checked', 'checked').parent().show(0);

    // Refresh the payment details section.
    get_payment_details(Drupal.settings.ucURL.checkoutPaymentDetails + 'free_order');

    using_free_order = true;
    
    //PATCH - Begin, Hide Billing Pane
    
    $("#edit-panes-billing-billing-first-name").val('COUPON ORDER');
    $("#edit-panes-billing-billing-last-name").val('COUPON ORDER');
    $("#edit-panes-billing-billing-company").val('COUPON ORDER');
    $("#edit-panes-billing-billing-street1").val('COUPON ORDER');
    $("#edit-panes-billing-billing-city").val('COUPON ORDER');
    $("#edit-panes-billing-billing-zone").val('1');
    $("#edit-panes-billing-billing-postal-code").val('00000');
    $("#edit-panes-billing-billing-phone").val('9999999999');
    $("#billing-pane").attr('disabled', 'disabled').hide(0);
    //PATCH - END 
    
  }

  free_order_initialized = true;
}
hedac’s picture

I'm using #25 solution.. for me it works... thanks

hedac’s picture

although... one problem is that next time the user goes to checkout, not a free order this time... there is the saved address billing COUPON ORDER as a new address.

squarecandy’s picture

I realized I can use the product panes module for this issue in my particular situation: http://drupal.org/project/uc_product_panes
Just add specific product panes to your free product under Edit > Features - eliminate the "billing" pane and you're good to go.
Of course this only works if you have a specific free product - if you're using a discount code or something else to get the $0 amount you'll still need a solution like the ones above...

hedac’s picture

thank you #28 for that suggestion squarecandy
that workaround works for me too.

squarecandy’s picture

You're welcome, hedac.
It surprised me when I realized it worked... kind of scary actually.
need to make sure anyone who can access uc_product_panes options knows about this.

mattcasey’s picture

I extracted the important bit of uc_product_panes, here's the relevant code to remove the billing pane on Checkout Submit when the order is $0.00 and free order's enabled:

/**
 * Implementation of drupal_alter('checkout_pane', $panes).
 */
function uc_free_order_checkout_pane_alter(&$panes) {
  if(variable_get('uc_payment_method_free_order_checkout', 0)) {
    $cart_contents = uc_cart_get_contents(uc_cart_get_id());
    $order_total = 0;
    foreach($cart_contents as $item) {
      $order_total += $item->price;
    }
    if ($order_total < 0.005) {
      foreach ($panes as $pid => $pane) {
        if ($pane['id'] == 'billing') {
          $panes[$pid]['enabled'] = 0;
        }
      }
    }
  }
}