1

I want to create a pricing rule based on discount entered in a field in the product display node? Is it possible? I have been trying to do it but i can't see the discount field in the dataselector. I tried entity has field but there only line-item entity appears and no node entity?

2 Answers 2

5

You can do this, I have done so myself. It's been a lot easier to do this than when I needed to do this.

The thing is that in rules, in order to get the fields of an entity, to use it in Rules, you need to either add a condition that the field exists or add a condition that the entity is of type X.

I've attached the base setup that does this for the commerce kickstart install profile. You might be using a different product type, but it should be easy to change.

{ "rules_example_discount" : {
    "LABEL" : "Example discount",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules", "commerce_product_reference" ],
    "ON" : [ "commerce_product_calculate_sell_price" ],
    "IF" : [
      { "data_is" : { "data" : [ "commerce-line-item:type" ], "value" : "product" } },
      { "data_is" : {
          "data" : [ "commerce-line-item:commerce-product:type" ],
          "value" : "product"
        }
      }
    ],
    "DO" : []
  }
}

Update:

Since you are saving the discount on the product display, you are making it more difficult for you. What you need to do, is from the line_item/product context to be able to figure out which product display the product comes from. The easiest way to do that would be to add a node reference field on the line item and then populate that with the product display node when adding the product to the cart. This should be doable with a custom submit handler added to the add to cart form with hook_form_alter. Then you need to tweak the rule accordingly and use the field from the node referenced on the line item instead of the product reference on the line item.

4
  • Thanks Googletrop for your answer...i tried it...and it works fine for if the discount field lies inside the Product Entity..but actually my discount field lies inside the product display and i have tried many ways but just cant make the fields available to the calculation data selectors...Field will show inside Entity has field Fields section but i cant select Entity node from Entity has Field section in its first Text field....Because it would make sense if i select Entity has field and select node entity and then the field rather than selecting only the line item entity and then selecting t
    – Azmat
    Commented Mar 7, 2012 at 16:59
  • @Azmat It's a good idea to structure it like that, doing it like that is making it more difficult than need be, as there is no direct relationship between a product and it's product display. Why don't you put the discount field on the product itself. Usually you want to specify the discount on the product and not the display, otherwise all products displayed would get the same price, and the same product on a different display would get a different price.
    – googletorp
    Commented Mar 7, 2012 at 22:51
  • Thanks again for your reply...Actually i want to create a Groupon like Deals website...there is Opendeals installation profile but it is a bit too heavy for my liking...so the benefit i will get in placing discount field inside displays is that there can be different deals associated with a single product and thus different prices altogether based on the particular deal or in other words product display...In the Open Deals website drupal installation,the developer calculates discounts right in the node--deal.tpl.php which is not a good idea at all..i thought i would be able to do it with rules
    – Azmat
    Commented Mar 8, 2012 at 4:41
  • @Azmat See my update.
    – googletorp
    Commented Mar 8, 2012 at 9:10
4

As I said on IRC, a line item doesn't store the id of the product display in a way that Rules can understand. This is because product displays are not required for Commerce to work.

However, line items have a "commerce_display_path" field that stores the url from which the product was added, so in your case it would probably look like "node/1", or whatever the node id is.

What you need to do is: Write a custom Rules action that takes the line item, initializes the wrapper, gets the value of commerce_display_path, explodes the string, takes the nid, loads the node, returns it.

Example code:
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $commerce_line_item);
$url = $line_item_wrapper->commerce_display_path->value();
$url_parts = explode('/', $url);
$nid = $url_parts[1];
return array('node_fetched' => $node);

Place this in a custom rules action, and you're good to go.

You can then use your action in a component to get the product display whose fields you can then access.

3
  • Yep, work with one slight change. You need to return the loaded node in an array, keys as per your rules action definition: return array('node_fetched' => $node); Commented Mar 23, 2012 at 9:22
  • Love that example code! It works! Commented Nov 14, 2012 at 15:16
  • I have the same issue,could someone write analytically the steps to solve this either with a rule or code?thanks
    – Dion
    Commented Mar 25, 2015 at 10:59

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