16 replies [Last post]
tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Was this information Helpful?

Hi Guys,

I'm working on a site that has two types of products, shippable and not shippable. I want to use the shippable checkbox to designate between the two. For the sake of our product catalog we would like to make the non-shippable items phone call required. So they won't be able to purchase online. I would like to replace the add to cart button with some text to contact the store to purchase. Does anyone have any ideas? The non shippable items are usually really large items (furniture). The shipping provider doesn't provide a good way to estimate shipping on items.(yet)

Thanks,

Matt

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Products that can't be purchased

It appears that, at least in Views integration with UC products, you can't use the "is shippable" field but you can send the Weight of the product to the Views template. However with your node-product.tpl.php template file, you should be able to access anything from the $node object, including the field that designates the product as being shippable.

You could easily look for the value of that field, and if it's > 0, decide to show text instead of the add to cart button.

--
Help directly fund development: Donate via PayPal!

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Re: Re: Products that can't be purchased

I've been trying to remove the add to cart button all together and I'm not having any success. Here is the code I have been using.

function trcb_preprocess_node(&$vars, $hook) {
  if ($vars->shippable == 0) {
    $vars['node']->content['add_to_cart'] = 'test';
  }
}

I can see 'test' when I print_r the $vars but it doesn't seem to effect the add to cart. Is there another place I should be overwriting this? Ideally I could disable this product from being purchased. Should I attempt this with the stock module?

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Found a possible solution

Here's what I came up with.

function trcb_uc_product_add_to_cart($node, $teaser = 0, $page = 0) {
  $output = '<div class="add-to-cart">';
  if ($node->nid) {
    if ($node->shippable == 1) {
      $output .= drupal_get_form('uc_product_add_to_cart_form_'. $node->nid, $node);
  } else {
          $output .= '<div class="non-shipping">';
          $output .= '<p>Please contact for shipping rates on this item</p>';
          $output .= '</div>';
  }
  }
  else {
    $output .= drupal_get_form('uc_product_add_to_cart_form', $node);
  }
  $output .= '</div>';
  return $output;
}

How else can a product be added to the cart, since this doesn't technically "disable" a product from being checked out.

splash112@drupal.org's picture
Offline
Joined: 04/01/2008
Juice: 413
Re: Products that can't be purchased

I think you should make a CCK-field with "call for shipping" with yes/no option.

Then you would change the conditional action which provides shipping quotes and add a check if there are products with "yes" in the cart. If so, it shouldn't give a quote and the default "call for shipping" shows.

Don't try to get this functionality with the core "shippable" setting because then it will not show shipping altogether.

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Re: Re: Products that can't be purchased

I am trying to make it so that if a product is not shippable, it can't be added to the cart or purchased.

splash112@drupal.org's picture
Offline
Joined: 04/01/2008
Juice: 413
Re: Re: Re: Products that can't be purchased

The not-shippable option in Drupal is ment for downloads, registrations, roles and the like.

these products can still be bought, but they will normally skip shipping.... So now you have to make sure they cannot be sold...

Which shipping do you use?

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Re: Re: Re: Re: Products that can't be purchased

The smaller items (shippable) are going to go through UPS, but the larger items(furniture) we use a pack and ship company. They don't have an api for shipping charges/quotes unfortunately.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: Re: Products that can't be purchased

EDIT: Nevermind, I didn't see your code from the earlier post. You're almost there. You need to return a $result. So like this.

<?php
function example_add_to_cart($nid, $qty, $data) {
 
$node = node_load($nid);
  if (
$node->shippable == FALSE) {
   
$result[] = array(
     
'success' => FALSE,
     
'message' => t('Sorry, %title is not available to purchase yet.', array('%title' => $node->title)),
    );
    return
$result;
  }
}
?>

This will prevent the item from being purchased. Hook_add_to_cart intercepts pressing the "add to cart" button. It looks like your code you are trying to intercept the add to cart form, which would require a hook_form_alter.

Edited again to add the node_load.

--
Help directly fund development: Donate via PayPal!

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Re: Re: Re: Re: Re: Re: Products that can't be purchased

Thank you for pointing out Hook_add_to_cart, I think that's the other half I'm missing.

The function I'm using above removes the add to cart form from the product page completely. Is there a way I can check if the item is shippable and then only remove the add to cart button, allowing me to show any product attributes and options? This way we could use the ubercart system for keeping attributes and options beacuse there is a possibility that in the future we change to allowing the products to be purchased online. This would help us avoid putting attributes and options in the descriptions.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Re: Re: Re: Re: Re: Re: Products that can't be purchased

Easiest way to do that is just in the node-product.tpl.php file. You can look for that variable in the $node object, and if it is FALSE, then just not display the form. Like this:

<?php
if ($node->shippable == TRUE) {
  print
$node->content['add_to_cart']['#value'];
}
?>

That's it.

--
Help directly fund development: Donate via PayPal!

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Solution

Ok, with your help I've got this code in my module:

function countrybarn_add_to_cart($nid, $qty, $data) {
  $node = node_load($nid);
  if ($node->shippable == FALSE) {
   $result[] = array(
     'success' => FALSE,
     'message' => t('Sorry, %title is not available to purchase yet.', array('%title' => $node->title)),
   );
   return $result;
}
}

This prevents anyone from adding a product that has "this product and it's derivitives are shippable" unchecked to their cart.

The next function then removes the add to cart button from the product page and displays a drupal message telling the customer to call to purchase.

function countrybarn_form_alter(&$form, $form_state, $form_id) {
  if (strpos($form_id, 'uc_product_add_to_cart_form') !== false) {
  $nid = end(explode('_', $form_id));
  $node = node_load($nid);
  $title = $node->title;
    if ($node->shippable == FALSE) {
      unset($form['submit']);
      drupal_set_message("<span class='shipping'>To purchase a $title please <a href='/contact-us'>contact</a> The Rustic Country Barn</span>");
    }
  }
}

This method allows us to keep the same layout for products and keeps the default product page (for the most part) of the ubercart install.

Thanks again guys for your help!

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: Solution

You can tighten up that second function a bit. You're doing some text comparisons that are unnecessary.

<?php
function countrybarn_form_alter(&$form, $form_state, $form_id) {
  if (
$form_id == 'uc_product_add_to_cart_form') {
   
$nid = $form_state['values']['nid'];
   
$node = node_load($nid);
   
$title = $node->title;
   
    if (
$node->shippable == FALSE) {
      unset(
$form['submit']);
     
drupal_set_message("<span class='shipping'>To purchase a $title please <a href='/contact-us'>contact</a> The Rustic Country Barn</span>");
    }
  }
}
?>

You can use $form_id and $form_state['values'] more freely than looking for a strpos() or exploding string variables.

--
Help directly fund development: Donate via PayPal!

benny's picture
Offline
Joined: 01/20/2010
Juice: 2
tightening up some more

I have found this thread extremely helpful. However, the revised countrybarn_form_alter did not work for me. The if statement never fired because 'uc_product_add_to_cart_form' in my case was always appended with the node id ('uc_product_add_to_cart_form_88') and the node_load did not return a node. With some changes the function looks like so:

<?php
function countrybarn_form_alter(&$form, $form_state, $form_id) {
 
//if ($form_id == 'uc_product_add_to_cart_form') {
 
if (preg_match("/^uc_product_add_to_cart_form.*/",$form_id)) {
   
//$nid = $form_state['values']['nid'];
   
$nid = $form['nid']['#value'];
   
$node = node_load($nid);
   
$title = $node->title;
    if(
$node->shippable==FALSE) {
      unset(
$form['submit']);
     
drupal_set_message("<span class='shipping'>To purchase a $title please <a href='/contact-us'>contact</a> The Rustic Country Barn</span>");
    } 
//is not shippable
 
} //is uc_add to cart form
} //countrybarn_form_alter
?>

Once again, thanks alot for these two functions. I've thrown both of them in a module and solved the problem of products I'd like in the catalogue but would prefer the customer call for a quote and to arrange delivery.

torgosPizza's picture
Offline
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.
Joined: 08/14/2007
Juice: 4110
Re: tightening up some more

Ah, you're right - I forgot that the nid exists at the end of the form_id. Thanks for posting that! If I could go back and edit my post I would. :/

--
Help directly fund development: Donate via PayPal!

tars16's picture
Offline
Joined: 01/18/2010
Juice: 23
Re: Re: tightening up some more

Yes, that's what we were accounting for in the second function. I'm glad this was of use to someone else.

joeebel's picture
Offline
Joined: 09/27/2009
Juice: 66
Thanks for the tips!

Thanks for posting the question and the answers! I found another way to override the Add-to-Cart button when a product is not shippable and you want customers to call in the order. Using Devel I located function theme_uc_product_add_to_cart() in uc_product.module. I copied it to my custom theme template.php and modified with an if...then wrapper:

function mytheme_uc_product_add_to_cart($node, $teaser = 0, $page = 0) {
  if ($node->shippable == TRUE) {
  $output = '<div class="add-to-cart">';
  if ($node->nid) {
    $output .= drupal_get_form('uc_product_add_to_cart_form_'. $node->nid, $node);
  }
  else {
    $output .= drupal_get_form('uc_product_add_to_cart_form', $node);
  }
  $output .= '</div>';
  } else {
    $output = '<div class="call-us">';
    $output .= 'Call us at 1-xxx-xxx-xxxx to arrange delivery!';
    $output .= '</div>';
  }
 
  return $output;
}

Thanks for pointing me in the right direction!

Also, if ya see anything wrong with my approach, (after all, I am a noob) please correct me!!

Joe