Different role prices. Do you think is a good solution?

58 replies [Last post]
Joined: 08/09/2007
Juice: 23

Hi everybody!

I need the posibility of havind different prices per role. I've written a few lines, and it seems to work, but I don't know if there's something that I'm forgetting. My hack is done in uc_cart.module.

I've added this simple code in line 1862:

global $user;
if (in_array("Botigues", $user->roles)) {
$item->price = $product->list_price;
}
if (in_array("Empreses", $user->roles)) {
$item->price = $product->cost;
}

and I've made my own template for products, so I display the price similarly as I change it in the code above. Do you think that I can have any problem doing this?

Thank you very much!

Joined: 08/09/2007
Juice: 23

no one? is it terrible?

Joined: 05/28/2008
Juice: 313

Wow. I have been looking for this exact thing! It seems like a workable solution, but its not very Drupal-y (e.g. upgrade friendly).

What function did you make the code change in? Is it possible to override that function in your Template.php?

Have you tested this through checkout and does the price stay consistent?

Thanks for posting this!

Joined: 08/09/2007
Juice: 23

I'm glad I've helped someone. I know this is not a good solution for the upgrades but... I haven't found any other solution.
As far as I'm concerned, I think that the function is not themeable (uc_cart_get_contents).
I've made few tests... If you have any problem with it and post it here, you would give me back the help Eye-wink

Joined: 08/07/2008
Juice: 10

This seems useful, however I'm having problems with this code - I put it in after

$product = node_load($item->nid);
      $item->cost = $product->cost;
      $item->price = $product->sell_price;
      $item->weight = $product->weight;

but just get a white screen - I think it's $global user; causing the problem so I took it out but then I get the error 'warning: in_array(): Wrong datatype for second argument. Did I put it in the wrong place? (sorry don't have line numbers in my text editor).

I'm also looking to do a similar thing for attributes (using attribute cost instead of sell price for certain role), so any help would be appreciated!
Thanks
John

Joined: 08/07/2008
Juice: 10

Ok I think I figured it out - supposed to be global $user, right?

Joined: 08/07/2007
Juice: 15375

Ahh, yeah. I'll fix the code in the first post so it doesn't throw anyone else off.

Joined: 08/07/2008
Juice: 10

Ok I've made some more changes to this:
Line numbers are accumulative, based on lines already inserted. Lines also replace any lines mentioned in the code.

***uc_product.module***
Changes made to display the cost price for certain role (in this case "retailer") on product view (but not on teasers, also disables Ajax Attribute Calculations functionality)

Line 735:

global $user;
if (in_array("retailer", $user->roles)){
  $node->content['display_price'] = array('#value' => theme('uc_product_display_price', $node->cost),
    '#access' => $enabled['display_price'],
    '#weight' => $weight['display_price'],
  );
} else {
  $node->content['display_price'] = array('#value' => theme('uc_product_display_price', $node->sell_price),
    '#access' => $enabled['display_price'],
    '#weight' => $weight['display_price'],
  );
}

Line 766:

if (in_array("retailer", $user->roles)){
  $node->content['sell_price'] = array('#value' => theme('uc_product_sell_price', $node->cost, $teaser),
    '#access' => $enabled['sell_price'],
    '#weight' => $weight['sell_price'],
  );
} else {
  $node->content['sell_price'] = array('#value' => theme('uc_product_sell_price', $node->sell_price, $teaser),
    '#access' => $enabled['sell_price'],
    '#weight' => $weight['sell_price'],
  );
}

***uc_attribute.module***
Applies attribute cost instead of price for user role ("retailer" again). You can set the cost in node>edit>options.

Line 315:

      foreach ($item->options as $option) {
        $op_costs += $option['cost'];
        $op_prices += $option['price'];
        $op_weight += $option['weight'];
      }
      $item->cost += $op_costs;
      global $user;
      if (in_array("retailer", $user->roles)){
         $item->price += $op_costs;
      }else{
         $item->price += $op_prices;
      }
      $item->weight += $op_weight;

Line 1476:

// Build the attribute's options array.
      global $user;
      $options = array();

Line 1481:

case 'total':
if (in_array("retailer", $user->roles)){
   $display_price = in_array($relation->aid, $priced_attributes) ? ', '. uc_currency_format(($node->sell_price + $option->cost) * $qty) : '';
} else {
   $display_price = in_array($relation->aid, $priced_attributes) ? ', '. uc_currency_format(($node->sell_price + $option->price) * $qty) : '';
}

and finally 1490:

case 'adjustment':
if (in_array("retailer", $user->roles)){
   $display_price = ($option->cost != 0 ? ', '. ($option->cost > 0 ? '+' : '') . uc_currency_format($option->cost * $qty) : '');
} else {
   $display_price = ($option->price != 0 ? ', '. ($option->price > 0 ? '+' : '') . uc_currency_format($option->price * $qty) : '');
}

I think that's all. An ugly hack but I hope this helps someone as much as it will me. I'll post any issues I get with this as I test it a bit more. Any questions or issues post here cheers!
John

Joined: 08/27/2008
Juice: 2

i wonder why this is not part of the core!
i used your code and it seemed to work fine!
many thanks

Joined: 09/11/2008
Juice: 11

Hi, I've followed this discussion applying phethean's and mortendk's changes: it is exactly the solution I'm looking for. I've submitted two patches opening this feature request on Drupal.org using an additional function that I hope makes this changes easier centralizing user role control. Any suggestion / modification is welcome: I've not added uc_attribute changes yet and a "discount" role selection by admin GUI is desirable. Please reply to drupal.org issue if interested.

Joined: 08/22/2008
Juice: 39

Would the Discount module not work better?
http://www.ubercart.org/contrib/143

Cheers,

Joined: 04/07/2008
Juice: 32

and to add the price into the cart:

* -- uc_cart.module -- *
around lin1889
global $user;
if (in_array("privatkunde", $user->roles)){
$item->price = $product->cost;
}else{
$item->price = $product->sell_price;
}

but this is still pure evil - this should be put out into a module, so we dont end up with a osCommerce way of doing things, hmm "somebody" should do something
and to make this really good it would be sweet if it was based on an cck field etc

/morten.dk

Joined: 07/16/2008
Juice: 392

Here's a snippet which you can add into one of your modules to avoid having to hack uc_cart.module.

function yourmodule_cart_item($op, &$item) {
   global $user;
   switch($op) {
      case 'load':
         if(in_array('reseller', $user->roles)) {
            // Change the price to what ever in here
            $item->price = $item->cost;
         }
         break;
   }
}

It uses this hook:
http://api.ubercart.org/api/function/hook_cart_item/1.0

If I need a more robust solution, I might go ahead and create a module around this.

Joined: 07/16/2008
Juice: 392

It's snippet day from me today. Again, put this in your module. This snippet will display the "cost" on the product page to the "reseller".

You're going to have to enable the "Cost" product field in the admin as well.

http://yoursite.tld/admin/store/settings/products/edit/fields

function yourmodule_nodeapi($node, $op, $arg1 = NULL, $arg2 = NULL) {
   global $user;
   switch($op) {
      case 'view':
         if(in_array($node->type, uc_product_product_types())) {
            if(in_array('reseller', $user->roles)) {
               //dpm(array("WE GOT A RESELLER, SHOW COST" => $node->content['cost']));
               $enabled = variable_get('uc_product_field_enabled', array('cost' => 0));
               $node->content['cost']['#access'] = $enabled['cost'];
            }
         }
      break;
   }
}

Since 'cost' isn't displayed to anyone except for roles with "administer products", this code essentially enable this functionality for your reseller with out the need of having to give their role that permission.

---
<3 the cart (heart the cart)

Joined: 01/11/2008
Juice: 375

Maybe we should set up a bounty to get this coded as a plugin or if possible a feature that can be implemented into UC.

Joined: 08/07/2007
Juice: 533

There are a couple things to consider here.

1. Last I checked, the catalog module does not use the nodeapi, which makes it difficult to modify the display price based on the users role.
2. There is currently a uc_discounts module on drupal.org. Although the current workflow would make it very time consuming to offer a discount for every one of your products, for one or more roles. It may be worth your while to create an additional discount plugin that merges the work here, with the discount system for the final cost adjustment.

Joined: 05/28/2008
Juice: 78

I am currently weighing the best way to do this. One possibility that may be obvious but is not mentioned here is to set up multiple catalogs (multiple taxonomy terms) and display different catalogs to different people according to roles, perhaps using http://drupal.org/project/taxonomy_role.

This would work better if perhaps the catalogs have some different contents in them. You would of course need to maintain more than one "copy" of your product in order to give it a different price, but on the other hand there may be other aspects of the product besides price that you want to differentiate as well (e.g. different wording in the description, different shipping options, etc.).

On the report end, it would show up as separate products, but on some cases this could be a simplification for reporting--it can get complicated when the same product has different prices.

An advantage of this method is of course that you would not need to implement any custom code, or, *gasp*, hack the modules.

Bob Hinrichs
ISL Consulting
http://www.islco.com

Joined: 01/11/2008
Juice: 375

Seems like I'm gonna have to go both retail and wholesale for the last site I build which sucks as atm dual pricing seems like such a hack in UC.

The dual catalog way seemed like a way to do this but I would also have to create dual blocks that display items and have different ones shown per role which seems like a huge redundant way of doing things.

Any more ideas on this would be appreciated.

Arek

hinrichsislcocom wrote:

I am currently weighing the best way to do this. One possibility that may be obvious but is not mentioned here is to set up multiple catalogs (multiple taxonomy terms) and display different catalogs to different people according to roles, perhaps using http://drupal.org/project/taxonomy_role.

This would work better if perhaps the catalogs have some different contents in them. You would of course need to maintain more than one "copy" of your product in order to give it a different price, but on the other hand there may be other aspects of the product besides price that you want to differentiate as well (e.g. different wording in the description, different shipping options, etc.).

On the report end, it would show up as separate products, but on some cases this could be a simplification for reporting--it can get complicated when the same product has different prices.

An advantage of this method is of course that you would not need to implement any custom code, or, *gasp*, hack the modules.

Joined: 12/14/2007
Juice: 120

this is a feature request
instead of having a cost and sell price,
there should have to be a sell price for each role.

example

List price:
Cost:
Sell price:
Sell price (role-1):
Sell price (role-2):
Sell price (role-3):
...
Sell price (role-xxx):

you don't have to fill all roles prices... if left blank for a role. "Sell price" will be applied.

Joined: 08/22/2008
Juice: 416

Nice idea hedac, after reading all the posts above I came to the same idea! ^^ That would be an interesting addition, indeed.

Try FreeBASIC!
My game Lynn's Legacy

Joined: 07/16/2008
Juice: 392

combine this with the purchasing of roles...and you could have yourself a nice "members" discount Laughing out loud

Joined: 03/02/2009
Juice: 4

Ok. I read all the replyes. I decided to make simple module, not to hack original code. It was very easy to do. This is my code:
"dealer" is user role. I use "cost" field as dealer prive field.

uc_dealer_price.module

<?php
//CART OVERRIDE
function uc_dealer_price_cart_item($op, &$item) {
    switch (
$op) {
    case
'load':
              global
$user;
       
$product = node_load($item->nid);
        if (
in_array("dealer", $user->roles)){
           
$item->price = $product->cost;
        } else {
           
$item->price = $product->sell_price;
        }
    break;
    }
}

//PRODUCT OVERRIDE   
function uc_dealer_price_nodeapi($node, $op, $arg1 = NULL, $arg2 = NULL) {
    global
$user;
    switch(
$op) {
        case
'view':
            if(
in_array($node->type, uc_product_product_types())) {
                if(
in_array('dealer', $user->roles)) {                        
           
$node->content['display_price'] = array('#value' => theme('uc_product_price', $node->cost, 'display-price', TRUE),
               
'#access' => $enabled['display_price'],
           
'#weight' => $weight['display_price'],
            );
           
$node->content['sell_price'] = array('#value' => theme('uc_product_price', $node->sell_price, 'display-price', $teaser),
               
'#access' => $enabled['sell_price'],
               
'#weight' => $weight['sell_price'],
            );
        }                   
        else {
           
$node->content['display_price'] = array('#value' => theme('uc_product_price', $node->sell_price, 'display-price', TRUE),
               
'#access' => $enabled['display_price'],
               
'#weight' => $weight['display_price'],
            );
           
$node->content['sell_price'] = array('#value' => theme('uc_product_price', $node->sell_price, 'sell-price', $teaser),
               
'#access' => $enabled['sell_price'],
               
'#weight' => $weight['sell_price'],
            );
        }
            }               
    break;
    }
}
?>

this is very raw. If anybody can make thi better, please. I'm just a designer, not programmer. I gueas it will be not so hard to make user role configurable throught admin part or smth.

Joined: 03/02/2009
Juice: 4

I add some code to catalog module to display two prices there. This is ugly hack and i hate those. Anybody can help me with writing code to my module to override uc_catalog output???

Joined: 07/16/2008
Juice: 392

I require this feature as well. Subscribing to this to see what happens.

Role based prices is definately a worthy module for ubercart as it allows retailers to have a different price...I assume this is why we're all here Laughing out loud

Joined: 12/28/2007
Juice: 716

Yes, different prices per roles opens a lot of possibilities. I'd love to see that happen in Ubercart!

Joined: 02/03/2009
Juice: 71

I am new to Drupal and Ubercart and frankly, it was shocking to me that Ubercart doesn't support discounts or dealer pricing. These would seem to be basic features of a commerce solution that purports to "Rule Them All". I told my client that it would be no problem to have his dealers log in and get wholesale pricing. Now, I'm stuck because the more I study the situation, the more I become convinced that I have painted myself into a corner by making promises that I can't keep.

Joined: 01/25/2008
Juice: 799

If you are running Drupal 6 and can wait a week I should be able to hook you up.

Joined: 02/03/2009
Juice: 71

I am running Drupal 6, Ubercart 2 and using a TopNotch template. A solution in a week or two would be wonderful. Thanks.

Joined: 01/11/2008
Juice: 375
thill wrote:

If you are running Drupal 6 and can wait a week I should be able to hook you up.

Interesting, let us know as I have a few websites that could use role pricing and I'm sure quite a few people are waiting for this feature.

Joined: 02/03/2009
Juice: 71

My client has three styles for many of his products. Rather than have a separate product listing for each style, we use an attribute to select the style and set the price for the product. Other attributes offer choices that may add to the price.

1) The most efficient way we can imagine would be to have role based attributes, one set of attributes that have customer pricing and another for dealers.

2) Less efficent for us in our particular application would be role based classes. We would establish a dealer class and duplicate each product entry and attribute with dealer pricing instead of customer pricing. OTOH, role based classes would be very useful in many applications.

Looking for "User Role-specific visibilty settings" capability just like what is available for "Blocks".

Joined: 12/14/2007
Juice: 120

look at this new module !

http://drupal.org/project/uc_multiprice

it would be nice to do the same for roles instead of countries

Joined: 01/11/2008
Juice: 375
hedac wrote:

look at this new module !

http://drupal.org/project/uc_multiprice

it would be nice to do the same for roles instead of countries

I talked to the person that created the above module and they are willing to do a per role pricing version for around $180 Euros. My money is tied up into other things right now but if no one comes up with a solution in the next two months I'll pay for it myself unless we can get a bounty going.

Joined: 08/07/2007
Juice: 15375

You can also look into http://drupal.org/project/uc_discount, a Conditional Actions based discount framework.

Joined: 01/11/2008
Juice: 375

^ That would kinda work but I need to show and have smome customers pay MSRP and then have the MSRP change to wholesale price for anyone with a "retail" role. I also then need to give the "retail" role discount for bulks buys.

Even if I don't get enough interest then I'll pay it for myself as I have sevferal potential customers that I could get with role pricing.

Joined: 03/31/2009
Juice: 10
Ryan wrote:

You can also look into http://drupal.org/project/uc_discount, a Conditional Actions based discount framework.

Ryan,

The UC_discount module will allow for a number of overrides - BUT it is not a user friendly module for performing this task - most clients (in my experience) perfer TWO sites over using discounts.

I am looking into a module based on the Value Added Tax module (http://www.ubercart.org/contrib/136)

Joined: 04/09/2009
Juice: 31
Quote:

I talked to the person that created the above module and they are willing to do a per role pricing version for around $180 Euros.

If the module could be completed soon enough, I could contribute half that bounty; but I'd need to know the module could be ready within in the next 3 weeks.

Joined: 04/09/2009
Juice: 31

Scratch that. I've drafted a preliminary module myself, based on the above module. Not rigorously tested yet (or at all through checkout), but working under ideal conditions for both product editing and product display. Please feel free to use and/or modify.

AttachmentSize
uc_role_discount.zip 10.1 KB
Joined: 04/17/2009
Juice: 6

umm.. i'm not sure how much work you put into this 'module' but other than changing the option from 'country' to 'user role' it doesn't do much else. you're missing functions and it doesn't even attempt to retrieve the right information from roles. (in fact, i think it still tries to retrieve country options)

it's a start, but i wouldn't even consider it alpha code.

Fatal error: Call to undefined function uc_role_discount_role_id() in /var/www/default/modules/uc_role_discount/uc_role_discount.module on line 110
Joined: 04/09/2009
Juice: 31

Really? It was working for me. Maybe I uploaded the wrong version. Here it is again.

AttachmentSize
uc_role_discount.zip 10.13 KB
Joined: 04/17/2009
Juice: 6

I didnt try the new one, but it looks like what I did to the file on reply #36.

old code with error: (file from reply #36):

<?php
   
// Checkout form
   
if($form_id=='uc_cart_checkout_form') {
       
$form['panes']['delivery']['delivery_role']['#default_value'] = uc_role_discount_role_id();
       
$form['panes']['delivery']['delivery_role']['#attributes'] = array('disabled' => 'disabled');   
       
drupal_add_js('$(document).ready( function() { $(\'#edit-panes-delivery-delivery-role\').val(\''.$_SESSION['rid'].'\').trigger(\'change\'); });', 'inline');
    }
?>

I commented out line #110 (which made a call to unnecessary uc_role_discount_role_id() function):

<?php
   
// Checkout form
   
if($form_id=='uc_cart_checkout_form') {
//        $form['panes']['delivery']['delivery_role']['#default_value'] = uc_role_discount_role_id();
       
$form['panes']['delivery']['delivery_role']['#attributes'] = array('disabled' => 'disabled');   
       
drupal_add_js('$(document).ready( function() { $(\'#edit-panes-delivery-delivery-role\').val(\''.$_SESSION['rid'].'\').trigger(\'change\'); });', 'inline');
    }
?>

new code from reply #38:

<?php
   
// Checkout form
    /*
    if($form_id=='uc_cart_checkout_form') {
        $form['panes']['delivery']['delivery_role']['#default_value'] = uc_role_discount_role_id();
        $form['panes']['delivery']['delivery_role']['#attributes'] = array('disabled' => 'disabled');   
        drupal_add_js('$(document).ready( function() { $(\'#edit-panes-delivery-delivery-role\').val(\''.$_SESSION['rid'].'\').trigger(\'change\'); });', 'inline');
    }*/
?>

the new file (reply #38) should work. i think now we are in Alpha stage. Eye-wink

Joined: 04/09/2009
Juice: 31

Hurrah for alpha!

I don't suppose anyone on this thread has a CVS account on drupal.org and wants to make this a project?

Joined: 04/17/2009
Juice: 6

nope. but some people were asking about a similiar feature added to UC Discounts Alternative. I posted a cross-link, http://drupal.org/node/418278

Joined: 02/20/2008
Juice: 275

I just came across this today, and it couldn't have come at a better time. It works great for what I need.

I have a CVS account, so I'll put it up and give CVS access to whoever wants to maintain it.

Joined: 06/15/2009
Juice: 2

Hi,
I tried your UC_role_discount module (It's Great!), but not working 100%.
I created 3 different groupt (reseller1, reseller2, reseller3), and + anonymus user + authenticated user.
If I set 3 different price for reseller1,2,3 It's OKAY, but if I don't logged or logged into the site, the price set automatically to 0 (zero) USD. What can I do for fixing this problems?

Thanks for your assistance.
Best regards,
H.A

Joined: 06/03/2009
Juice: 17

Where do I find the UC_role_discount module, I searched Drupal and here.

Rich

Joined: 10/20/2007
Juice: 575

I'm using http://drupal.org/project/issues/uc_discounts_alt on a new site and love it so far, very feature rich and configurable. It does role-based discounts.

Gorgeous original Drupal themes (and Ubercart themes!) ~ Psst: more Ubercart themes on our new site

Joined: 10/16/2008
Juice: 106

Yes! The module posted above by stephthegeek works perfectly for this! Thanks!

Joined: 05/10/2009
Juice: 2

Is there any progress being made in this module?

Joined: 06/03/2009
Juice: 17

I too am looking to implement this.

I am also a Drupal newbee. We have another company seting up our site in DrupL, However it will myself that handles moving old content in.

We are an Association and are currently using xcart. We have 2 different prices, one for members and one for non-members.

Thanks

Richard S Albrecht

Joined: 07/06/2009
Juice: 9

I needed this so I paid Dave at Longwave to do the work and it's complete and working for UC 1.x and in operation on my site.

http://drupal.org/project/uc_price_per_role

Thanks Dave!

Joined: 01/11/2008
Juice: 375

Thanks for the module. I'll test it out next week as my current implementation requires too much theming. This would simplify things by a lot and I have a few possible projects if its works. I'll see I can get some funds to get it ported to D6/UC2

Arek