Userpoints module

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

Hello,

I am starting to work on a user points module. If someone has something started or finished and is willing to share that would be greatly appreciated. If not let me know and i'll keep working on this...

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

This is what i have so far

this is the updated checkout function for ubercart

function uc_cart_checkout_complete() {
  if (!$_SESSION['do_complete']) {
    drupal_goto('cart');
  }

  $order = uc_order_load(intval($_SESSION['cart_order']));

  // Clear our the session variables used to force the cart workflow.
  unset($_SESSION['cart_order'], $_SESSION['do_complete']);

  $output = uc_cart_complete_sale($order);

  // Add a comment to let sales team know this came in through the site.
  uc_order_comment_save($order->order_id, 0, t('Order created through website.'), 'admin');


  // Give user points
  if (module_exists('userpoints') && module_exists('userpoints_ubercart')) {
  userpoints_ubercart_cartcompleteapi($order->order_id,'give_pts');
  }
 
  // Empty that cart...
  uc_cart_empty(uc_cart_get_id());

  $page = variable_get('uc_cart_checkout_complete_page', '');
  if (!empty($page)) {
    drupal_goto(variable_get('uc_cart_checkout_complete_page', ''));
  }

  return $output;
}

to use this replace the above function in uc_cart.module, download the userpoints module for drupal and then unzip the attached folder into the contrib (simply because I like keeping things together) From what I have seen so far it adds the point just like the ecommerce module but you cannot buy anything or do anything with the points yet.

comments regarding this are also being posted on drupal and can be seen here
http://drupal.org/node/164176

AttachmentSize
userpoints_ubercart.zip1.61 KB
Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

Success, I have a working userpoints module. I am going to keep doing some testing and make a few more changes before i release it as alpha. If anyone wants to test it out please let me know. I would be glad to post it as is if you are interested...

Currently:
-adds points based on purchases but does not add if paying with points
-completes sale and subtracts points with the chosen method to move the order along
-conversion rates for points to dollars and back

ToDo:
-add points back to user if order is canceled?
-bug test and verify it is working as intended...

Wish list:
-nothing at present... feed back would be appreciated greatly

Posts: 1315
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Something I would like to help you test Smiling Subscribing to the post. Keep us updated! Nice work!

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 5379
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Exciting news! Congrats on getting this so far, and let us know if you need any pointers for the remaining tasks. Smiling

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

i am stuck, i want a method that can be used to refund points when an order is canceled and am not sure on that one. I am going to keep digging.

edit: i think i found my answer with hook_order and the variable &arg2, i guess i overlooked it....i still need to test it but i think that will work...

if you want to try it the same change still applies as mentioned above to enable accumulating points.

AttachmentSize
userpoints_ubercart.zip3.21 KB
Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

Its done, and I got everything in my to do list along with adding a check to make sure the user has more than 0 points. I would like someone to look the code over once, but I think I got everything. There probably should be more logging like to watchdog...

enjoy

AttachmentSize
userpoints_ubercart.zip3.32 KB
Jredding (not verified)

I took at a look at the code (just a visual review) and I noticed inconsistencies in the use of some of the userpoints API calls.

Specifically
userpoints_get_current_points($uid = $curUserId, $tid = NULL);
is called in uc_points_payment.inc
This is a 3.x API call incompatible with 2.x

and
userpoints_userpointsapi('points',$points, $uid, 'uc_earn','Ubercart Transaction ID ' . $txnid)
is called in userpoints_ubercart.module.
This is a 2.x API call incompatible with 3.x

Which version are you coding for? I'd suggest coding for version 3.x even though its currently in BETA as it will be stabilizing soon.

Posts: 1315
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

I have installed your module and I'm excited by it - but .... I can't seem to find your settings area for it? I looked in the module and there isn't a path to the admin side either. I'm wondering how to change settings such as userpoints_ubercart_payment... I would love for people to be able to buy some products using points but right now, can't figure out how to set it up! Please point me in the right direction Smiling

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

one thing before i get there, i was just informed that there will be some major api changes to userpoints with the version 3.x release so I will be making those changes tonight (the modules function should not change but will not be compatible with 2.x).

To administer it:
--The settings that control how many points a user gets on payment and how many points equal a dollar are under the user points setttings (admin/settings/userpoints)
--To enable the use of points (I might need to review this...) but you go to the ubercart store settings and choose payment settings, then click edit, click payment methods. It should be listed there as points. This part i need to look at reviewing because i use an if statement to check if you are user_id = 1 or if you have points to control if the payment method even shows up. I think i need to see if there is an admin flag that can be used as well so that it is always shown on the payment settings page but not always shown durring checkout if the user doesn't have any points.

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

I got some bugs in my logic in a couple places. they will be fixed but in the process i am also converting this to be a userpoints 3.x module.

Posts: 1315
Joined: 08/14/2007
Bug FinderEarly adopter... addicted to alphas.Getting busy with the Ubercode.

Awesome! Let us know when we can update. I'll be first in line Smiling

--

"Pain don't hurt." - Dalton

Mike Nelson's RiffTrax! www.rifftrax.com

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

I think I got it all fixed. I guess its easier when to fix when I'm not incredibly tried. It will require userpoints version 3.0, it has also been fixed so that it does not need to have any modifications made to the ubercart files through the use of hooks. I am still trying to find a better solution to showing/hiding the payment option if they don't have anypoints. I also realized i left out several checks and functions that were needed. they have been added in as well.

there are no db items attached to this module just copy it in.

AttachmentSize
userpoints_ubercart-alpha1.zip3.51 KB
Posts: 5379
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Haven't had a chance to check this out yet, but if you're looking for a way to disable the payment method for a user that has no userpoints, try this... I think it's a little bit of a hack, but simply modify your hook_payment_method() function to check if the current page is cart/checkout and if so then check if a user has userpoints... and if not, then don't return the method array.

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

I was thinking about something like that. Its what I have implemented now. Version Alpha2

AttachmentSize
userpoints_ubercart-alpha2.zip3.51 KB
Posts: 96
Joined: 10/29/2007
Bug Finder

I was going to try this last night. I installed the 3.x version of userpoints, and I could not get the retro points to work (calc for all my content) so I uninstalled 3x beta and installed 2x and I got all my point stuff working well.

2 Questions.
1. I assume I need to upgrade to 3.x to use your module, correct?
2. Does the upgrade go from 2.x to 3.x pretty easily?

Thanks for this update, it will add a cool feature to our website.

Jim

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

the big thing there is the api calls my module makes to add/subtract points. if i looked up the 2x api calls i could make a 2x version. i didn't have any issues upgrading to userpoints 3x though. the module itself should not be affected at all. Lemme know if you find any bugs, I think its all good.

EDIT:
I just updated my copy of userpoints to the latest dev version and i need to do some debugging as it is not working right. give me a day or two to get it sorted out.

EDIT 2:
Alpha 3 Has been uploaded. I am running userpoints 3 from the latest dev and ubercart alpha 8. If someone wants to try it on other versions it should work but no guarantees. If upgrading to alpha 8 is a show stopper let me know and i think we can work through the issues with prior versions

Posts: 96
Joined: 10/29/2007
Bug Finder

Can you just write a wrapper function so that a 2.x formatted api call will pass the parameters to 3.x?

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

Im not sure, its something I can look at though.

i would like some input from you guys about reporting and some of the discussion taking place in the last several posts here (http://drupal.org/node/164176). Thanks for the input

edit:
is it possible to get the version of a module that is in use? if possible i could just duplicate that part and use an if statement to switch between the two but will need someone to test that

Posts: 2273
Joined: 08/07/2007
AdministratoreLiTe!

Detecting module versions is tricky, but it's been done before. Usually, the code will use function_exists() to detect API changes. Actual version numbers can't be detected without opening up the .info file. As long as you know what's different between the versions, you ought to be able to deal with the differences.

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

thanks for the tip. I've decided that I will not be releasing a version compatible with the alpha 7 series and userpoints 2x due to the changes in each, I do not want to be maintaining several variations of it at this time. at present it is compatible with alpha 8 and userpoints 3x-dev. perhaps down the road I will release something that is compatible with the older versions. if someone is in need of this module working with prior versions please let me know and i'll see what i can do.

Posts: 33
Joined: 08/25/2007

Hey all, very useful addition. Where is it being maintained? I've added a couple of modifications for my own purposes and need to add a few more, but when I read the thread on Drupal it looked like this was still actively being maintained and I didn't want to walk on anything anyone is doing.

So far what I've added is the ability to assign points to a referrer or "salesman" instead of or in addition to the customer. This was necessary because on our site we don't give points to individual purchasers, however, when anyone is referred to the site and becomes a member, the person that referred them gets a percentage of everything they purchase as long as they're a member. I also wanted the ability to give a different percentage to the purchaser and referrer in the event we eventually do decided to give points to the purchaser. This was done in userpoints_ubercart.module via:

define('USERPOINTS_AWARD_TO',     'userpoints_award_to');
define('USERPOINTS_REF_MULT',     'userpoints_ref_mult');

and

        if(module_exists('referral')){
          $form[$group][USERPOINTS_AWARD_TO] = array(
            '#type' => 'radios',
            '#title' => t('User to whom !points are awarded on purchase', userpoints_translation()),
            '#default_value' =>  variable_get(USERPOINTS_AWARD_TO,0),
            '#options' => array(t('Referrer only'), t('Purchaser only'), t('Referrer and Purchaser')),
          );
          $form[$group][USERPOINTS_REF_MULT] = array(
            '#type' => 'textfield',
            '#title' => t('!points multiplier for referrer', userpoints_translation()),
            '#default_value' =>  variable_get(USERPOINTS_REF_MULT,1),
            '#size' => 5,
            '#maxlength' => 5,
            '#description' => t('Add a multiplier here if you wish to have your referrer and purchaser get different point val
ues based on their role.  If for instance you want your referrer to get 50% of the points awarded to the purchaser, enter 0.5
here.  The default value, 1, awards equal points.  <b>This field is only valid when "Referrer and Purchaser" is selected above
.  Otherwise the standard multiplier is used.</b>'),
          );
        }

and then a couple of additions to the Alpha2 zip on this post in the inc file.

Now I want to be able to assign points based on certain other criteria (like no points on tax and shipping). If that's already been implemented, I'd rather not re-write it.

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

That was not the original intention of this module, it was to give points to the user making the purchase. I can understand why you might want to give the person who referred you to the site. There is an existing module to give a referrer points too. I would rather not incorporate that into this module with an existing one out there.

http://drupal.org/project/userpoints

If you look under the contrib section you will see the module I am talking about.

Posts: 33
Joined: 08/25/2007

I looked at those modules and they are just as far if not farther from what I need to do. I want to award points on purchase. Just like userpoints_ubercart. The only difference between the original module and what I want to do is the person I give the points to.

The referral_points module does this:

referral_points:
Allows referrers to get bonus points percentage points for all user points awarded to their referrees.

But, if you look at the code, this module doesn't even trigger until AFTER a user has already been given points. In the primary case I'm worried about/coding for, the user would never get points, but their referrer always will. If I set the amount of points to award to zero, then this module would never even trigger.

I'm not sure why this is a problem but I will try the approach you suggest.

Posts: 33
Joined: 08/25/2007

Sorry to follow up on my own post, but as I suspected that approach is not workable. The scenario is this: User B was referred to the site by user A. When user B makes a purchase, user A gets points and user B gets none (think "sales commission" where A is the salesman and B is the client).

When using ubercart with userpoints, points are awarded via your module through the userpoints_ubercart_award call. If I were using the Drupal ecommerce module, points would be awarded via the userpoints_ecommerce module through the userpoints_ecommerce_ecommerceapi call. In both of those calls, a point multiplier is grabbed, points are calculated, and then awarded to the uid of the purchaser. The only way to prevent the purchaser from being awarded any points at all is to set that multiplier to zero, however doing so loses the original value of the purchase after calculation, and no value is saved for the amount of points that would be awarded to the referrer.

The next option would be to intercept the call to userpoints_userpointsapi on the 'points before' operation. However, since the $points variable is not passed by reference, any intercepting call can not change its value and the API awards the points to the purchaser.

The only other option I can think of without touching either of the "cart" modules would be to catch the 'points after' operation and call userpoints_userpointsapi again, subtracting the initial amount back out of the purchasers account while adding them to the referrer's account. I haven't thought about how this would be done without causing an infinite loop, but this is a bad idea for many reasons - mostly because it's non-atomic and we don't have any method of validating success of previous internal API calls so we could end up removing points that we never added.

I don't know how common a "commission" like scenario like this would be, but it's functionality I need to have. At the very least, the hooks for it would have to be in the "cart" module itself so points are assigned to the correct UIDs before calling userpoints_userpointsapi. So yes, my future need to have points assigned to a purchaser and referrer are handled neatly by the referral_points module. However my current need for a "commission" referral points where the referrer gets points but the purchaser doesn't must reside within the "cart" module and can't be accomplished with any existing module or module combination.

I'm not sure what the best resolution to this is without polluting your feature space. It seems silly for me to write a mutually exclusive userpoints_ubercart_commission module that would just duplicate 95% of your functionality to add these few lines. It also doesn't seem right for me to just keep my mods to myself in case someone else finds them useful, but that seems like the least odious of my choices.

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

for discussions sake at this point (i have finals this week) how are you determining the person who is to receive the commission? I don't remember what was in your code. I may just incorporate it to make it easier on both you and others. (on a side note, i finally got my laptop back from the repair place and it is going back as they broke something else but i will try and look at it next week when things slow down)

Posts: 33
Joined: 08/25/2007

bmagistro wrote:
for discussions sake at this point (i have finals this week) how are you determining the person who is to receive the commission? I don't remember what was in your code.

I use the referral module. If a referrer is listed, I set curUserId to the referrer instead of the current user:

  // We may reassign this if we're using a referral
  if(module_exists('referral')){
    // award_to: 0 = award points to referral
    // award_to: 1 = award points to purchaser
    // award_to: 2 = award points to referral and purchaser
    if($award_to == 0 || $award_to == 2){
      // Look up our referrer if we have one
      $result = db_query("select referral_uid FROM {referral} WHERE uid = %d", $curUserId);
      if(db_num_rows($result)>0){
        $ref = db_fetch_object($result);
        $referrer = $ref->referral_uid;
        if($award_to == 0){
          $curUserId = $ref->referral_uid;
        }
        else{
          $ref_mult =  variable_get(USERPOINTS_REF_MULT,1);
        }
      }
    }
  }

Posts: 95
Joined: 09/24/2007
Getting busy with the Ubercode.

should points be given for all purchases or just purchases where points were not used as a payment? I am also going to need you to test this since I do not have the referral module installed/referrers on my site. i also modified the form and made it so that you do not need to use the radio group to do the who gets points, its done by setting the multiplier and each "person" is calculated out separately.