-
Notifications
You must be signed in to change notification settings - Fork 0
Add referrals #75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add referrals #75
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| class Api::V1::ReferralsController < Api::BaseController | ||
| def create | ||
| if referral = Referral.create(referrer_id: current_user.id) | ||
| render json: referral, status: :created | ||
| else | ||
| render_error(:unprocessable_entity, referral.errors.full_messages.to_sentence) | ||
| end | ||
| end | ||
|
|
||
| protected | ||
|
|
||
| def referrals_params | ||
| params.require(:referrals).permit(:) | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,12 @@ def create_params | |
|
|
||
| def create_session_for_user | ||
| ensure_one_active_session | ||
| @session = Session.create!(create_params) | ||
| pending_referral = Referral.pending.for_candidate(current_user).first | ||
| create_params[:rewards] = pending_referral.reward if pending_referral | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we keep "rewards due to referrals" and "rewards due to sessions" as seperate things? |
||
| ActiveRecord::Base.transaction do | ||
| @session = Session.create!(create_params) | ||
| pending_referral.rewarded! | ||
| end | ||
| end | ||
|
|
||
| def ensure_one_active_session | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| class Referral < ApplicationRecord | ||
| CODE_PREFIX = 'STAYHOME'.freeze | ||
| REWARD_VALUE = 1000 | ||
|
|
||
| enum status: { pending: 0, rewarded: 1 } | ||
|
|
||
| scope :for_candidate, ->(user) { where(candidate_id: user.id) } | ||
| scope :for_referrer, ->(user) { where(referrer_id: user.id) } | ||
|
|
||
| before_create :generate_code | ||
|
|
||
| private | ||
|
|
||
| def generate_code | ||
| new_code = "#{CODE_PREFIX}-#{SecureRandom.hex[0, 4].upcase}" | ||
|
|
||
| if Referral.exists?(referrer_id: referrer_id, code: new_code) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought an user will have a single referral code that would be shared among his peers. |
||
| generate_code | ||
| else | ||
| self.code = new_code | ||
| self.reward = REWARD_VALUE | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,8 @@ class User < ApplicationRecord | |
| has_many :wallet_transactions, dependent: :destroy | ||
| has_many :notification_tokens, dependent: :destroy | ||
| has_many :sessions, dependent: :destroy | ||
| has_many :sent_referrals, class_name: 'Referral', foreign_key: :referrer_id | ||
| has_many :received_referrals, class_name: 'Referral', foreign_key: :candidate_id | ||
| before_validation :remove_devise_validations, unless: :email_auth_validations | ||
| after_validation :reverse_geocode | ||
|
|
||
|
|
@@ -48,10 +50,16 @@ def self.onboard_from_mobile(params) | |
| user = User.find_or_initialize_by(mobile: params[:mobile]) | ||
| user.name = params[:name] | ||
| user.identities.find_or_initialize_by(provider: 'mobile', uid: params[:uid]) | ||
| update_referrals(params[:referral_code]) if params[:referral_code] | ||
| user.save_provider_auth_user | ||
| user | ||
| end | ||
|
|
||
| def update_referrals(code) | ||
| referral = Referral.find_by(code: code, candidate_id: nil) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the current logic an user is entitled to refer ONLY one other person, as once that happens next time this method won't find any more entry with |
||
| referral.candidate = self if referral | ||
| end | ||
|
|
||
| def password_complexity | ||
| return if password.blank? || password =~ /^(?=.*?[a-z])(?=.*?[#?!@$%^&*-]).{8,70}$/ | ||
| errors.add :password, :password_complexity_error | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| class ReferralSerializer < ActiveModel::Serializer | ||
| attributes :code | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| class UserSerializer < ActiveModel::Serializer | ||
| attributes :id, :name, :email, :mobile, :profile_picture_url, :wallet_balance, | ||
| :home_duration_in_seconds, :lat, :lng | ||
| :home_duration_in_seconds, :lat, :lng, :total_referral_rewards | ||
|
|
||
| def home_duration_in_seconds | ||
| active_session = object.active_session | ||
|
|
@@ -20,4 +20,8 @@ def wallet_balance | |
| object.wallet_balance | ||
| end | ||
| end | ||
|
|
||
| def total_referral_rewards | ||
| Referral.rewarded.for_referrer(object).sum(&:reward) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using |
||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| class CreateReferrals < ActiveRecord::Migration[5.2] | ||
| def change | ||
| create_table :referrals do |t| | ||
| t.references :referrer, index: true, foreign_key: { to_table: :users } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to index all these columns? |
||
| t.references :candidate, index: true, foreign_key: { to_table: :users }, null: true | ||
| t.integer :status, index: true, default: 0 | ||
| t.string :code, index: true | ||
| t.timestamp :expires_at | ||
| t.integer :reward | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this "reward" column is missed in |
||
| t.timestamps | ||
| end | ||
| end | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this required ?