Our website wants to reward users that make referrals, after the new user makes a purchase through the Commerce module.

Referral's Rules integration doesn't have a way to do that natively- the 'referring_user' variable only exists when the new account is being created. It would be very nice to have a Rules action that could fetch the referring user.

CommentFileSizeAuthor
#1 referral-fetch-1566900-1.patch1.83 KBcoleman.sean.c

Comments

coleman.sean.c’s picture

Assigned: coleman.sean.c » Unassigned
StatusFileSize
new1.83 KB

Here's the patch. The rules action returns a list of uids, just to protect against edge cases where there are 0 or many referrals. Is there a hard limit of at most one referral? Could simplify the code a bit, and return a user object if that were the case...

IWasBornToWin’s picture

I just tried to apply the patch but it wouldn't apply. I did it manually. The last added line of the patch has a ";" which would add two semicolon's at the end of the line. Not sure if that would make a difference or not.

After manually changing everything, the new rules action worked. I did get this notice afterward. Notice: Undefined offset: 1 in DatabaseStatementBase->fetchAllKeyed() (line 2180 of /home4/growtogi/public_html/includes/database/database.inc).

I've created a user field, referred_by, and I assign it the uid of the referring user after a new user account is saved. I did notice the variable of the fetched referring uid offered me [referring-uids:0],[referring-uids:1],[referring-uids:2],etc. I'm not sure there should be more than one uid fetched (iud instead of uids). I didn't even know it was possible to have more than one referring uid when referring a new user.

I see your note above about "many referrals" just didn't realize that was even possible. To eliminate a possible 0 I created aded condition - user was referred by another user.

This patch helps out big time - thank you.

RKS’s picture

Is there any way to fetch this for anon users? I need it to track the referrer for each user making a purchase and not just registered users.

vadim.eremeev’s picture

Thanks for patch, I've a bit modified it to follow way since there is no possibility to have more than one referring user.

Added follow code which creates new action and return only one referring user ID:

@@ -42,6 +42,17 @@ function referral_rules_action_info() {
         'uri' => array('type' => 'text', 'label' => t('URI'), 'description' => t('The URI you want to say the new user came from'), 'optional' => TRUE),
       )
     ),
+  'fetch_referral' => array(
+   'label' => t('Fetch referring users\' ID'),
+   'group' => t('user referral'),
+   'base' => 'rules_action_fetch_user_referred',
+      'parameter' => array(
+      'user' => array('type' => 'user', 'label' => t('The user whose referrers you want to fetch')),
+    ),
+   'provides' => array(
+     'referring_uid' => array('type' => 'user', 'label' => t('Referring User ID')),
+   ),
+  ),
   );

@@ -101,6 +112,12 @@ function rules_condition_user_referred($user) {
   return $result;
 }
 
+function rules_action_fetch_user_referred($user) {
+  $result = db_query_range('SELECT referral_uid FROM {referral} WHERE uid = :uid', 0, 1, array('uid' => $user->uid))->fetchField();
+  return array('referring_uid' => $result);
+}

So with this patch we can create a rule which award referring user with points after his referral did success purchase in ecommerce store. Exported rule looks like:

{ "rules_award_user_with_points_after_referral_bought_something" : {
    "LABEL" : "Award user with points after referral \u0026 bought something",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "referral", "userpoints_rules", "commerce_checkout" ],
    "ON" : [ "commerce_checkout_complete" ],
    "IF" : [ { "user_referred" : { "user" : [ "commerce-order:owner" ] } } ],
    "DO" : [
      { "fetch_referral" : {
          "USING" : { "user" : [ "commerce-order:owner" ] },
          "PROVIDE" : { "referring_uid" : { "referring_uid" : "Referring User ID" } }
        }
      },
      { "userpoints_action_grant_points" : {
          "user" : [ "referring-uid" ],
          "points" : "10",
          "tid" : "76",
          "entity" : [ "commerce-order" ],
          "description" : "Granted Points after completed checkout",
          "operation" : "Insert",
          "display" : 1,
          "moderate" : "default"
        }
      }
    ]
  }
}
dariogcode’s picture

I just applied the patch #1 and it works, but as @vadim.eremeev mentioned there is possible only one referer. An about the last patch I think there isn't neccesary to do db_query_range

$result = db_query_range('SELECT referral_uid FROM {referral} WHERE uid = :uid', 0, 1, array('uid' => $user->uid))->fetchField();

It is sufficient with

$result = db_query('SELECT referral_uid FROM {referral} WHERE uid = :uid', array('uid' => $user->uid))->fetchField();

fetchField only return the first result and also it is supposed to not get more than one row with that query.

vadim.eremeev’s picture

@tilon thanks for comments. Yep, I think we can just use db_query().

Also I've added another custom condition which checks if user did first order on web-site. Seems commerce not provide us with such a condition. I've created custom module for that with follow code in custom_referral.rules.inc file (other files just standart):

<?php

/**
 * Implements hook_rules_conditions_info()
 */
function custom_referral_rules_condition_info() {
  $conditions['custom_referral_user_has_orders'] = array(
    'group' => t('Commerce Order'),
    'label' => t('Check user already has orders in system'),
    'base' => 'deal_referral_user_has_order',
    'parameter' => array(
      'user' => array(
        'type' => 'user',
        'label' => t('The user whose order existing you want to check')),
    ),
  );

  return $conditions;
}


function custom_referral_user_has_order($user) {
  $result = db_query('
    SELECT COUNT(order_id)
    FROM {commerce_order}
    WHERE uid = :uid
    GROUP BY uid
  ', array('uid' => $user->uid))->fetchField();

  return ($result > 1 ? TRUE : FALSE);
}

So my final rule which award referring user after his referral did first purchase on web-site looks like:

{ "rules_award_user_with_points_after_referral_bought_something" : {
    "LABEL" : "Award user with points after referral \u0026 bought something",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "referral", "custom_referral", "userpoints_rules", "commerce_checkout" ],
    "ON" : [ "commerce_checkout_complete" ],
    "IF" : [
      { "user_referred" : { "user" : [ "commerce-order:owner" ] } },
      { "NOT custom_referral_user_has_orders" : { "user" : [ "commerce-order:owner" ] } }
    ],
    "DO" : [
      { "fetch_referral" : {
          "USING" : { "user" : [ "commerce-order:owner" ] },
          "PROVIDE" : { "referring_uid" : { "referring_uid" : "Referring User ID" } }
        }
      },
      { "userpoints_action_grant_points" : {
          "user" : [ "referring-uid" ],
          "points" : "10",
          "tid" : "76",
          "entity" : [ "commerce-order" ],
          "description" : "Granted Points after completed checkout",
          "operation" : "Insert",
          "display" : 1,
          "moderate" : "default"
        }
      }
    ]
  }
}
dariogcode’s picture

Nice, I'm doing something similar but with Payment module, but I pay referral with userpoints for each referer purchase ;). I think you should make a final patch for "Fetch referring User" and this should be added to the last version, this is esentially.

hockey2112’s picture

Issue summary: View changes

I applied the patch in #1, but I get this error message when adding the new action to the rule: "Unknown action fetch_referral." Any idea how to fix that issue?

sachin00700’s picture

Hello vadim.eremeev,

Your code is working for me but in my case i want that only points credit on referred user if the first purchase done from the referral user not in every purchase would you help me out for this i am not getting that.

Thanks in advance wait for you quick response

Sachin

sumit-k’s picture

Hi,

You can try commerce first time customer discount module.It has one rule condition user first order.

hejazee’s picture

Assigned: Unassigned » hejazee
Status: Needs review » Fixed

This issue is fixed in the git repository. Please checkout the latest version
(or nightly built version)

hejazee’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.