Product Pricing Rules (with screencasts)
Discounts in Drupal Commerce
Overview
- Create a discount using a rule
- Create a weekend (date-based) sale discount using a rule
- Create a tag-based weekend sale discount using a rule
Simple Discount
An example of a simple discount: You want to take 10% off everything in your store until further notice.
- Go to Store -> Configuration -> Product Pricing Rules
- Click "Add a pricing rule"
- Give your rule a name
- Under "Actions" click "Add Action"
- Under "Commmerce Line Item" choose "Multiply the Unit Price by Some Amount"
- The data selector should be "line_item"
- The amount should be .9 (in other words, multiply the price by .9).
- Now all products have 10% taken off of them.
Simple Discount using the VAT Hack
The problem with simple product pricing rules is that there's currently no way to actually show why the prices are what they are. We'll eventually have more options here. But right now, you can accomplish what we just did using negative VAT. VAT is, of course, a tax which is included in a product price normally, but there's not much difference between that and a discount... but a discount is a negative tax.
- Go to Store -> Configuration -> Taxes -> Tax Types
- Create a new tax type of "Discount".
- Give it a title
- Check "Display taxes of this type inclusive in product prices".
- Go to Store -> Configuration -> Taxes -> Tax Rates
- Add a tax rate - give it a name and a tax rate of -0.10
- Under type, choose the type that you created above.
- Visit "Cart" and you'll see that the discount is being taken.
- Visit the checkout page and you'll see that the discount is explained and accounted for in the subtotal.
Drupal Commerce Basic Discount from Randy Fay on Vimeo.
Adding a Date Window to the Discount
Now we need to take our simple discount and make it effective for just one period of time. We'll use the "Simple Discount" approach above, but now we'll make it only applicable during this upcoming weekend.
- Create a discount as in the "Simple Discount" above.
- This time we'll add two conditions to the product pricing rule:
- System Date is Greater than Midnight April 23
- System Date is Less than Midnight April 25.
That's it. To test in a Linux environment you can temporarily change the server date using
sudo date MMDDHHMM
for example
sudo date 04231237
Don't forget to change the time back. Changing it like this makes a big mess of things.sudo ntpdate pool.ntp.org
Drupal Commerce Date-Based Discounts from Randy Fay on Vimeo.
Adding a Taxonomy Term To Drive Discounts
Now we're going to go much farther. We'll add a taxonomy term to our product entity to determine which sale events it should be subject to, and also add a date range.
There is a rather major complexity in this one. Rules does not have the ability currently to follow references (like product references and term references) very well, so we have to jump through some hoops to get access to them. It is do-able, but a bit mind-bending. We hope to see the rules issue relating to this land soon, but for now we have to use the tools we have.
- Add a taxonomy vocabulary called "Sales Events"
- Add a term to the vocabulary called "April Weekend Madness Sale"
- Add a term reference field to the "Product" product type referencing "Sales Events"
- Set the "Sales Events" value in one or more products to "April Weekend Madness Sale". We're essentially marking them for this sale.
- Create a rules component that determines whether the weekend is here:
- Administer -> Configuration -> Workflow -> Rules -> Components -> Add new component.
- Component plugin is "Condition set (AND)"
- Name is "Weekend of April 23"
- Continue
- Add two conditions which do data comparison against system date to select the weekend timeframe just as we did in the earlier, simpler example.
- Create another rules component that accepts a product as a variable which will determine whether the product is marked to be part of the sale. Note that the first three conditions we're adding here are just to force Rules to understand how to traverse the data. They seem quite complex at first, but it's actually just cookbook stuff.
- Administer -> Configuration -> Workflow -> Rules -> Components -> Add new component.
- Condition set (AND)
- Name: "Product is on sale"
- Variables: Data type "Entity - Product", Label "Product", Machine name "product"
- Add a condition
- Entity has field
- Data selector: product
- Field: field_sales_event
- Add another condition
- Data value is empty
- Data selector: product:field-sales-event
- Click negate.
- Add another condition
- Data value is empty
- Data selector: product:field-sales-event:tid
- Click negate.
- Add a final condition
- Data comparison
- Data Selector: product:field-sales-event:tid
- Value equals (the tid of the taxonomy term we created)
-
Now we'll create a product pricing rule at Store -> Configuration -> Product Pricing Rules.
- Add a pricing rule with the name "April weekend sale"
- Under actions, add an action to multiply the price by 0.8 (we'll give them an even bigger discount than we did last time!)
- Under conditions:
- Add condition "Component: April Weekend Sale", which will add the date-based conditions to our rule.
- Add condition "Entity has field" (This is just to bring the product into scope due to the Rules issue mentioned above.)
- Data selector: line-item
- Field: commerce_product
- Add condition "Component: Product is on sale."
- Data selector: line-item:commerce-product
Now we have a product pricing rule that does two things. First it checks the conditions in the "Weekend of April 23" to see if the date is correct, and then it uses the "Product is on sale" component (to which we pass the line item's product) to determine whether the item is on this sale.
We can change the server date to experiment, and should see that the products we marked now have their sale prices.
Drupal Commerce Complex Pricing Rules from Randy Fay on Vimeo.


Comments
Hi! I need a rule to add a
Hi! I need a rule to add a product to the cart every time i click on "add another item" button generated by the "field collection module" that i add to the inline product fields.
I thought it wold be just a matter of rules and I've tried to add this one:
event: after udpating existing field collection item action: add product to the cart Parameter: User: [site:current-user], Product SKU: [field-collection-item:item-id] Provides variables: Added product line item (product_add_line_item)
but actually i'm not good with rules... Can someone help me please?
Pricing Rules for Custom fields in products
Hi,
I have a client that wants to set up a store where there are discounts for certain users.
I'm using profile2 to add custom profile fields to each users profile.
I'd like to use Product Pricing Rule to apply discounts to certain customers, eg. is the customer a member of a discount scheme?
So far so good, but the problem is, that the client doesn't offer a percentage discount but a fixed amount e.g. if the customer is a member of the discount scheme they get £X off product Y.
I've added a custom field to products called discount where I enter the amount of discount a member of the discount scheme gets off that product.
I'm trying to create a rule that checks if they are a member of the discount scheme and if they are, subtract the amount that is stored as a custom field in the product from the product price. The first part works ok, but I can't get the rules to reference the custom field in the product. I've tried using Entity has field in the conditions, but still can't get access to the custom field.
Any ideas?
regards
Simon
Solved
Hi,
I've worked it out.
I was trying to use commerce-line-item to refence the entity rather than commerce-line-item:commerce-product
Simon
Display both prices
thanks for the tip. It works fine.
How could I display both prices ?
I would be useful to display the list price (may be striked through) on top the price with the discount.
By displaying the reference term, I can show the sales action and the discount. but the visitor doesn't know if the discount is already applied or not...
Thanks,
Benoit
Cart block and pricing rules
I have setup a pricing rule with "extra rules conditions" to rule the pricing of the total item amount of digital products.
Works fine so far.
Except the sidebar cart block doesn't show any discounts. Is this a bug or did I something wrong?
THX
Kirk
How to calculate sell price with coefficients for providers
As a distributor, I purchase products from different providers. For each provider, I want to calculate price with 2 coefficients (for example: 1.5 and 2). The providers are defined with taxonomy terms, that contents the field : field_price_coeffient (real with 2 values).
In product, I've defined a new product type with fields to identify the provider (field_provider as referenced term to the vocabulary 'providers') and coefficient code (field_coefficient_code). This last field contents integer that identify the coefficient to take for a specific provider (for ex.: value 0 -> 1.5, value 1 -> 2).
Could you help to create a "Product pricing rule" ?
I've tried to bring the fields into scoop with conditions
Entity is of type
Parameter: Entity: [commerce-line-item], Entity type: Commerce Product
Entity has field
Parameter: Entity: [commerce-line-item], Field: commerce_line_items
Parameter: Entity: [commerce-line-item], Field: field_provider
Parameter: Entity: [commerce-line-item], Field: field_coefficient_code
Parameter: Entity: [commerce-line-item], Field: commerce_price
and component :
Commercer Line Item/Line Item/line_item/parameter
Taxonomy term/Provider/field_provider/parameter
Text/Coefficient code/coefficient_code/parameter
Decimal number/Provider coefficient value depending on coefficient_code/parameter
Price/Calculated price/calculated_price/provided
But finaly I can't define any actions as I don't see the fields into scoop.
Could you help to create this rule ?
Thanks.
Not too sure what you mean
Hey,
I'm not sure exactly what you are doing, it seems like you have a lot going on here. But you're rule should be: "Calculating the sell price of a product".
Conditions: Entity has field:
P: [commerce-line-item] F: commerce-product
Entity has field
P: [commerce-line-item] F: field_coefficient_code
Here I would do a data comparison:
field_coefficient_code = (something)
Action:
set the unit price to a specific amount.
Does that help?
Field not available for data comparison
Thanks.
When I try to add the data comparison, I don't see the field_coefficient_code in the data selectors.
And if I try something like :
Data selector
commerce-line-item:commerce-product:field_coefficient_code
The data is invalid.
hmmm... there could be
hmmm... there could be multiple reasons for this:
Try this:
Make a component: condition set (and).
Set
Data type=> commerce Product
Label => Product
machine name => product
Entity has field:
P: product
F:field_coefficient_code
Data Value is Empty:
F: field_coefficient_code
Negate
Data Value is Empty:
f:field_coefficient_code:value
Negate
Data Comparison:
You choose
Then insert this component into the rule
Data Comparison before Entity has field
I've finally found a rule that does part of job. For some reason, it works if I do the 'data comparison' before 'Entity has field'. And also I can check for only one Entity field. Hopefully the other fields appear into scoop.
So the nice thing is that I can modify price with a data stores as field ('field-price-coefficient') in my taxonomy 'provider'. Here is the rule :
{ "rules_price_calculation_with_coefficient_in_taxonomy_term_field" : {
"LABEL" : "price calculation",
"PLUGIN" : "reaction rule",
"REQUIRES" : [ "rules", "entity" ],
"ON" : [ "commerce_product_presave" ],
"IF" : [
{ "entity_is_of_type" : { "entity" : [ "commerce-product" ], "type" : "commerce_product" } },
{ "data_is" : { "data" : [ "commerce-product:type" ], "value" : "my_special_product_type" } },
{ "entity_has_field" : { "entity" : [ "commerce-product" ], "field" : "field_provider_price" } },
{ "NOT data_is_empty" : { "data" : [ "commerce-product:field-provider-price" ] } }
],
"DO" : [
{ "variable_add" : {
"USING" : {
"type" : "integer",
"value" : [ "commerce-product:field-coefficient-code" ]
},
"PROVIDE" : { "variable_added" : { "variable_coefficient_code" : "Variable Coefficient Code" } }
}
},
{ "data_calc" : {
"USING" : {
"input_1" : [ "commerce-product:field-provider-price:amount" ],
"op" : "*",
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:0" ]
},
"PROVIDE" : { "result" : { "result" : "Calculation result" } }
}
},
{ "data_set" : {
"data" : [ "commerce-product:commerce-price:amount" ],
"value" : [ "result" ]
}
}
]
}
}
For the moment, the price calculation only works with one price coefficient:
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:0" ]
I'm still looking for a way to select one coefficient between up to 4 coefficients, based on the field 'commerce-product:field-coefficient-code' (an integer that refers to the coefficient number. '0' gives the first coefficient,... ).
Something like
"input_2" : [ "commerce-product:field-provider:field-price-coefficient:" & "commerce-product:field-coefficient-code" ]
I don't have found that right synthax (all the arguments are available to write the action of the rule).
Showing original price aswell
Hi Randy, thanks for this page..it helped me a lot :)
How can I give discount but still show the original price with a line through as so many websites has?
Freezing the prices once in my Cart
Not sure if this is the right place to post this...
I'm just wondering if I can do the following with rules (rather than having to write a module):
The trouble I'm having is setting the variable. It would seem the best place would be to set the variable upon adding an item to the cart. But I need another rule for calculating the sell price for the user. The variable isn't carried from one rule to another.
Any suggestions or advice would be greatly appreciated.
Zap
watchdog flood and performance
I used the simple discount example and I have two questions.
rules 02.02.2012 - 14:22 Rules debug information: " Reacting on event....How can I get rid of them?
Turn off rules debugging
Turn off rules debugging in the rules settings.
Rules and custom fields once again
Thanks Randy for all your help here and everywhere!
I have read this FAQ and a lot of other posts, but I still have questions concerning using custom fields with pricing rules. Probably it is something I miss...
Rules traversal of entities works fine.
Good luck!
Rules for applying discounts to one SKU with different atributes
First of all: Great tutorial!
I'm facing a slightly different problem/use case. Maybe I'm doing it wrong on the architectural side but I'll try to explain it as clear as I can.
I'm preparing a small commerce site intended to sell training courses. Each course has 3 "standard" formats:
- one day "live" on class room
- two month web-based with training materials and online support
- one month web-based with training materials and online support
As the contents and purpose of all the three variants are the same, my idea was to have a single product (SKU) with a base price (let's say 100$) and expose three different "product displays" each one with their own discount. As an example, the one day would get the base price (100), the two month online would get a 25% off (75) and the one month online edition a 50% off (50).
As an attempt to get this going I added on each of the "product displays" a new field called field_discount. This field is a list with the above mentioned variants.
My problem is that I don't seem to get to the field_discount on the price calculation rule. I've tried every "data comparison" and "entity has field" I could remember of, but it still only exposes fields that are part of the "product" and not of the "product displays". So, I'm unable to apply a separate discount to a "product display".
I know that maybe the solution is to create one distinct SKU for each variant, but it seems a lost of time to make a complete copy of an SKU only to modify the price.
Is there any solution to this particular use case?
Thanks in advance,
Cláudia
Yes, it works
It works fine! Thanks for the references and the clarifications. I had missed the "Data Comparison -> Type" condition and also that you sometimes may need two (or more?) "scope-conditions".
Thanks for the detailed
Thanks for the detailed description. Usually I only have one or two discounted products for promotion purposes.
Is there a way to just rule one Product for discount? Like
If SKU = 12345 then multiply .5
I haven't found the Producct ID/SKU in the conditions.
Sure. Create a product
Sure. Create a product pricing rule. Add conditions:
Condition: Entity has field, Commerce Line Item, Commerce product
Condition: Data Comparison, commerce-line-item:commerce-product:sku, Comparison =, Data "SOMESKU"
Action: Set the unit price to a certain amount, commerce_line_item, value (in minor units, like cents), component (probably discount)
Hey Randy, Thanks for the
Hey Randy,
Thanks for the description above: would you be able to do something similar if you knew the sku structure? This is just a thought question, of no real importance.
Lets say the sku = xx_xx_xx
The first two designate type of item. The second two designate size of item. The third two designate color
Would it be possible to use the data comparison to select the item based simply on the specific digit of a sku?
Thanks,
Tim
Sure. You should experiment
Sure. You should experiment with this. But you can match the beginning of the sku. If you use php snippets you could do far more significant things with processing the sku based on meaningful components.
Pricing based on Multiple Selections of Taxonomy Terms
Great Screen Casts.
My question goes a step further on these: I imagine this is fairly common need, but haven't seen it addressed.
I'm filling popcorn tins and the larger tins need to be fillable with three flavors. The pricing however changes dependent on what flavors are selected.
For example:
Caramel, Cheese, Movie = 40;
Caramel, Cheese = 45
Caramel = 45
Movie = 30
Caramel, Movie, Kettle = 35
Using taxonomy terms as a line item makes the product very easy to create and I was able to limit it to three selections.
The problem I am facing is setting up the rules: I get to the second "NOT Data Value is empty" and I'm presented 4 choices. "product:field-flava:0", "product:field-flava:1", "product:field-flava:2"; "product:field-flava:3".
After selecting one and negating it: I add a third step "NOT Data Value is empty" and I choose "product:field-flava:item 0:tid" and then choose the appropriate term ID in the "Compare Data" condition.
The problem I am facing is that I don't know what "product:field-flava:0", "product:field-flava:1", "product:field-flava:2", "product:field-flava:3"; are equal to. I would try to trouble shoot this, but the possibility for error in steps I wouldn't know where I went wrong.
Is "product:field-flava:0" when no choices are selected, is "product:field-flava:1" the first selection, and so on?
If you could clarify, I would greatly appreciate and once my product rules are set up and working, I wouldn't mind writing a FAQ page for this because the rules procedure is fairly complex. Thank you!
Solved
Figured this out. rfay recommends using the process
• Data selector: product:field-sales-event
• Click negate.
• Add another condition
• Data value is empty
• Data selector: product:field-sales-event:tid
• Click negate.
• Add a final condition
• Data comparison
• Data Selector: product:field-sales-event:tid... etc.
I changed the procedure slightly and came up with a pretty decent pricing scheme. I exported the rules that I used to achieve the results I needed here. http://drupal.org/node/1338172
It is a pretty ugly rule that I am sure can be cleaned up. But the quick and dirty of it work.
Thanks for the original screencast.
Perhaps the guide for term
Perhaps the guide for term based discounts could be updated. The issue with rules seems to be fixed now.
VAT or sales tax?
Hi, Randy -- great video. I really appreciate that you've made these.
I went through the VAT process, but it showed prices with the discount already in place -- e.g. a $10 item with a 20% discount simply appears as $8 throughout the site. Then on the checkout page it looks odd, even in your screencast. (Look at 5:48: The three items are $9 each, and it adds up to $30?).
But I found that it works just fine if I create a negative sales tax. I don't have to create a new Tax type, either -- just use the existing sales tax type. Then the price shows up as $10 in the product display node, $10 on the checkout page, and the discount is finally taken as a line item in the checkout.
Or am I missing something?
Showing the discount
It sounds like you've found a technique that works fine...
A lot of people want to show the actual discount in the cart and with pricing rules, and are working on ways to do that just with formatters. I'll pay attention and try to post links to those issues when I see them.
I can accept that. :)
That's fair -- it seems to just be a matter of taste. I'll mention that in the lynda.com video about discounts, and will acknowledge you for this trick. :)
Lynda training on Commerce still in the works?
Oh Wow! This means you're still going to finish the Lynda.com training on Commerce! The world rejoices! If there's anything I can do to help I'll be happy to.
Yup, it's still happening!
Hi, Randy! Yes, I'm still working on it, and will record in early November. (I can't say when it'll come out: There's a long post-production process.)
I actually sent a note to Greg with some questions a few days ago, but it might have been to an old address. I'll send you the same note through your d.o account. (Your timing is perfect: I'm running into a bit of a wall.)
Cheers,
--tgeller
Workaround with php evaluation rules feature
An workaround is to use rules actions with php evaluation. Don't forget to enable the core module PHP filter.
Here is a sample code, for the use case Adding a Taxonomy Term To Drive Discounts, see also http://drupal.org/node/1053850
The rule is: event Calculating the sell price of a product, Conditions Order is a shopping cart,Parameter: Order: [line-item:order], Actions Multiply the unit price by some amount,Parameter: line-item:line-item-id
At amount , click switch to data selection
This code works only with Conditions Order is a shopping cart,Parameter: Order: [line-item:order], because before adding to cart line item object doesn't exists.
In php evaluation input the following code:
<?php
$van_line_item_id['0'] = $value; #$value from rules with data selector line-item:line-item-id
$van_line_item_ent=entity_load('commerce_line_item',$van_line_item_id);
$van_product_id[0]=$van_line_item_ent[$value]->commerce_product['und'][0]['product_id'];
$van_product_ent=entity_load('commerce_product', $van_product_id);
$van_product_price=$van_product_ent[$van_product_id[0]]->commerce_price['und'][0]['amount'];
$van_tags = $van_product_ent[$van_product_id[0]]->field_tag_subdomenii['und'];
foreach ($van_tags as $van_tag ) {
$van_tag_objects[] = taxonomy_term_load($van_tag['tid']);
}
#....
#Return whatever values depending on the taxonomy found...
?>
Accessing additional product fields from rules actions
I came to the conclusion that bringing user created commerce product fields into scope using Rules 2 (as described above) only makes them available to conditions. If you need to use them in actions you will need to use the hook_entity_property_info_alter() to add metadata to the commerce_product to let rules know of their existence.
You bring them into scope in conditions
You bring them into scope in conditions, but then can use them in actions.
Two degrees of separation
Looks to me like it only works if the field is a direct property of the entity the event is on.
So if the event is “After updating an existing commerce product” and you bring the stock field into scope using Entity has field, then you get access to it in actions
However if you are on a pricing rule event “Calculating the sell price of a product” (line item) end you bring the product and then the stock field using two “Entity has field” conditions, then you don’t get access ):
in the second case i am still convinced that the only way is to use hook_entity_property_info_alter().