9

I would like to grant User Point to product owner in amount of product price after a product is sold.

For this I defined a rule as below:

  • Events: Completing the checkout process

  • Actions: Loop (commerce-order:commerce-line-items)

And I defined a Rules Component as below:

  • Conditions: Entity has field (Entity: commerce-line-item, Field: commerce_product)

  • Actions: Grant points to a user: (User: commerce-line-item:commerce-product:creator, Points: commerce-line-item:commerce-product:commerce-price:amount)

But when I save component it generates this Error message:

Data selector commerce-line-item:commerce-product:commerce-price:amount for parameter points is invalid.

How I can do that?

8
  • Why do you need this condition? Commented Jan 28, 2013 at 14:42
  • Probably the reason is that commerce-product is already out of scope as the checkout is completed(I am not sure). Try to print the value and check it once.
    – Gokul N K
    Commented Jan 28, 2013 at 15:29
  • @Daniele are you sure that you want to grant points to the user who has created the product? Commented Jan 29, 2013 at 17:03
  • @subhojit777 Yes, for example to manager userpoints as user credit. I create a virtual product that, once bought, give me userpoint needed to buy real products. Sadly commerce_credits don't have flexibility and currency replacing like commerce_userpoints. Commented Jan 30, 2013 at 15:51
  • @DanieleNapolitano why do you need that condition? I see the question has condition in rule component. Commented Jan 30, 2013 at 16:09

2 Answers 2

5
+25

At first I tried to answer your question using rules and userpoints module, but I saw that while adding Grant points to a user as action there is no such data selector for selecting the user who has created the product. I found the data selector for selecting the user who is the owner of order, but that is not your requirement. (That is why I clarified this in comments).

I found a module solution to your question. The module uses hook_commerce_checkout_complete(). From the hook page:

Allows modules to perform business logic when an order completes checkout.

This hook coincides with the "Customer completes checkout" event. Only business logic should be performed when this is invoked, such as updating the order status, assigning the order to a user account, or sending notification e-mails. Interaction with the user should instead occur through checkout panes on the checkout completion page.

This is the coding of the module I designed:

YOURMODULE.info file:

name = YOURMODULE
description = Module description
dependencies[] = commerce
dependencies[] = commerce_cart
dependencies[] = commerce_checkout
dependencies[] = userpoints
core = 7.x

UPDATE As suggested by Clive, I have changed the module file so that this custom module will also work with multilingual sites.

YOURMODULE.module file:

/**                                                                             
 * Implements hook_commerce_checkout_complete().                                
 */                                                                             
function YOURMODULE_commerce_checkout_complete($order) {
  // Iterate through every commerce line item added in product.
  foreach (field_get_items('commerce_order', $order, 'commerce_line_items') as $line_item_id) {

    // Load commerce line item by line item id.
    $line_item = commerce_line_item_load($line_item_id['line_item_id']);

    // We do not want to include shipping cost in userpoints.
    if ($line_item->type != 'shipping') {
      // Load commerce product by product id.
      $product = commerce_product_load(field_get_items('commerce_line_item', $line_item, 'commerce_product')[0]['product_id']);

      // Create parameters.
      $params = array(
        'uid' => $product->uid,
        'points' => commerce_currency_amount_to_decimal(field_get_items('commerce_line_item', $line_item, 'commerce_total')[0]['amount'], field_get_items('commerce_line_item', $line_item, 'commerce_total')[0]['currency_code']),
      );

      // Grant userpoints programmatically.
      userpoints_userpointsapi($params);
    }
  }
}

Reference links:

userpoints_userpointsapi($params)

commerce_checkout API

commerce_line_item_load($line_item_id)

commerce_product_load($product_id)

Userpoints: deduct points programmatically

commerce_currency_amount_to_decimal()

2
  • Great solution, that's going to come in handy. Might I suggest one small change? It would be better to use field_get_items() to retrieve $order->commerce_line_items, that way this will work with multilingual sites too
    – Clive
    Commented Jan 30, 2013 at 18:27
  • @Clive thanks for the suggestion.. but I have never used field_get_item() before.. I have to learn its usage and apply that in this answer. Need some time :) Commented Jan 31, 2013 at 4:12
0

As an alternative to the previous answer, which requires custom code, you may want to try the alternative described below to get around that error message ...

Your question seems to be a variation (not a duplicate) of the question "How to grant user User Points equal to certain field's value / calculated value?". Similar to the accepted answer to that question, try to adapt your Rules Component like so:

  1. Add these extra Rules Actions before the Rules Action in your Rules Component that causes the error:

    • Set a variable that corresponds to "amount of product price" (as in your question), which appears to be commerce-line-item:commerce-product:commerce-price:amount. Let's assume you name that variable price_amount.
    • Convert data type of that price_amount variable to integer. Let's assume you name that conversion result amount_of_points.
  2. Adapt your existing Rules Action (in that Rules Component) so that the number of user points to be granted uses this (calculated + converted) amount_of_points.

PS 1: Such "Convert data type" is simply a matter of how Rules works (by design), so it's not to be considered as a bug either ...

PS 2: I assume your question is about D7.

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.