There is no "easy answer" for that. I've been dealing with this kind of problems many times in the last 3 years, because IMHO the sales_rule engine isn't good at all for product promotions.
Facts:
- Magento Sales_Rules (as they name says) are made to be used in the cart "world" without Cart (quote) data you just can't validate them.
- Magento Sales_Rules are extremely "flexible" so that makes almost impossible handle all rules configurations and/or combinations.
- Magento Product View it's slow enough to add more complexity if you just figure out that every time you load a single rule at least - 4 database calls are made - for 100 active rules you will have 400 Db Calls just get the rules.
- Magento Sales Rules are saved serialized so you need to load them all to validate each one (before know if applies or not)
- You must undestand/decode how rules are selized in order to deserialize and validate sufh information.
So at this point we have the worst scenario
We just can't load promotions (sales_rules) directly in the product view
But wait a minute... we can do some stuff before quit...
Possible Solutions:
We can "flat" data for some 'specific/identified' rules every time they are saved (using an event observer), but isn't an easy work.
First we need to identify which rules we'll save in our flat table(s), as an example:
Case 1
All those that have one or more category_id(s) in the condition rule and have: "rule_simple_action" = "by_percent".
So we need to create a table to save the rule data, something like that:
TABLE: flat_rule_category
------------------------------
| id | rule_id | category_id |
------------------------------
| 1 | 123 | 54 |
------------------------------
| 2 | 123 | 56 |
------------------------------
-- You must resolve by your own the logic involve to identify and flat the rule data --
Case 2
All those that have one or more sku(s) in the condition rule and have: "rule_simple_action" = "by_fixed".
Now we need a table for those cases, so lets rock...
TABLE: flat_rule_product
------------------------------
| id | rule_id | product_id |
------------------------------
| 1 | 345 | 224 |
------------------------------
| 2 | 345 | 34 |
------------------------------
| 3 | 345 | 666 |
------------------------------
It's clear that in your sales_rule_after_save
process you must map Sku(s) to Ids... i used product_ids in the table because you can map any other rule like "if product color IS green" to product_id(s) in the flattening process.
So now in the product view we must implement a helper to perform queries to both flat_rule_product
& flat_rule_product
tables for fast rule finding, and obviously get all rule-related data to show.
NOTES:
- You should keep in mind the from/to_date to filter rules properly.
- For the "category" case you could join
category_products
index table with the product_id as filter instead $product->getCategoryIds() because the product could be related to a parent category indirectly (parent anchor category).
- Alternatively (for less joins and fast performance) you could render all products_ids (even those that comes from a category-type rule) to the
flat_rule_product
table. But that involves the addition of few observers to products and categories to maintain these relations.
My 2 cents :)