2

I am using Drupal Commerce and I would like to know if it is possible to have discounted prices for registered users and much better for roles.

For example, the nomral price is $100 but when a user logs in that belongs to Role1 for example, he will see different prices with the percentage discount that I will have assigned to that role. How can I accomplish such a feature?

3 Answers 3

5

You can set this up with Rules. Using the calculate sell price of a product, you can create different conditions (The users role) and add discount depending on the role the user have.

Note if you do this for several roles, you need to take care about the weight of the Rules and how you set discount, as you otherwise might end up with cumulative discounts or wrong discounts if you have users with multiple roles.

1
  • How would you explain your customer how to add/change the discount for a specific role?
    – Strae
    Sep 18, 2012 at 15:50
2

Steps for Applying Discounts by Role in Drupal Commerce

  1. Create a new role
  2. Go to admin/commerce/config/product-pricing and Add a Pricing Rule
  3. Call this new rule: Apply [role] Discount. Save
  4. Conditions:
    1. Add condition - user has role(s), value [your new role]. Save
    2. Optional condition - Order contains products of particular product types -
      1. Data Selector: commerce-line-item:order
      2. Product Type: whatever ones you want.
  5. Add action - Commerce Line Item: Multiple the unit price by some amount.
  6. Data selector: commerce-line-item (use hyphenated, not the one with underscores)
  7. Amount: Value: 0.85 (for 15% discount, so 85% of the price).
  8. Price Component Type: Value: Discount. Save

Now when logged in as a user that has the role to allow for a discount, the discounted price will show for the item and on checkout it will show that a discount was applied.

1

I got this problem right now, googling around i found Og and Profile2 modules that could be configured to accomplish this need, but my customer need a really easy-to-manage solution, so i took another way:

  1. I created a node content-type called "Discount"
  2. Added a integer field "Discount percentage" to the "Discount" node type
  3. Created a simply module that add a "Discount" node every time a new Role is created
  4. Added 2 fields to the user profile (admin/config/people/accounts/fields), one for manual discount and another that gets calculated with roles.
  5. In the Store Pricing rules, I created a rule for the event Calculating the sell price of a product with action Subtract an amount from the unit price and a custom PHP code.

This is the pricing rule amount code:

global $user;
$user_load = user_load($user->uid);
$discount_value = 0;
// Give precedence to an optional manual discount
if(isset($user_load->field_discount_manual['und'][0]['value']) AND (int)$user_load->field_discount_manual['und'][0]['value'] > 0)
{
    $discount_value = (int)$user_load->field_discount_manual['und'][0]['value'];
}
else if(isset($user_load->field_discount_role['und'][0]['value']))
{
    $discount_value = (int)$user_load->field_discount_role['und'][0]['value'];
}

if($discount_value > 0)
{
    return ($value * $discount_value) / 100;
}
// no discount
return 0;

This way let my customer to assign a discount to every role, managing them easly as other types of nodes (just play with Views to semplify the process).

EDIT

Indeed, was a bit insane all that discount calculations every time a product's price get displayed. So i edited the module to make the calculations only when the user log in, and update the field_discount_role (that you have to add too) on the user profile, so the whole gear should be a bit less haevy.

The new module can be found here, but please note that you will need the Field Permission module too, or your customers can change they're own discount! (what a dream!)

OLD POST

Just in case the log-in behavior doesnt fit your needs, this is the first-approach.

Pricing rule amount code:

global $user;
$user_load = user_load($user->uid);
$discount_value = 0;
// Give precedence to an optional manual discount
if(isset($user_load->field_manual_discount['und'][0]['value']) AND (int)$user_load->field_manual_discount['und'][0]['value'] > 0)
{
    $discount_value = (int)$user_load->field_manual_discount['und'][0]['value'];
}
else
{
    // Get the discount nodes.
    // If user has multiple roles (usually _authenticated user_ and the discount role) i take the one with
    // higher discount. Depending on your customer neds, is up to you to sum, avg or do whatever you want.
    foreach($user->roles AS $role_name)
    {
        // using an IN() clause?
        $query = db_select('node', 'n');
        $record = $query->fields('n', array('nid'))
            ->condition('n.type', 'discount')
            ->condition('n.title', $role_name)
            ->execute()
            ->fetchObject();
        if($record !== false)
        {
            $discount = node_load($record->nid);
            if(isset($discount->nid))
            {
                if(isset($discount->field_discount['und'][0]['value']))
                {
                    $discount_value = (int)$discount->field_discount['und'][0]['value'] > $discount_value ? (int)$discount->field_discount['und'][0]['value'] : $discount_value;
                }
            }
        }
    }
}
if($discount_value > 0)
{
    return ($value * $discount_value) / 100;
}
// no discount
return 0;

Here you can find my module (please note is a quick'n'dirty module, you'll have to edit few settings in the .module file) and here the pricing rule I used (my customer asked to apply discounts only if the user has 3 or more items in the cart, so you'll find this condition in the rule).

Now im looking on how to do that calculation when the user login, put the user discount in the session or somewhere else and use this value instead of recalculate all every time, but this is a (needed) optimization.

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.