namespace App\Traits; use App\Models\Referral; use App\Models\ReferralCommission; trait HasReferral { public function initializeHasReferral() { $this->appends = array_merge($this->appends, [ 'referral_count', 'referral_earnings', ]); } public static function bootHasReferral() { static::created(function ($model) { $model->generateReferralCode(); // Check if user was referred if (request()->has('ref') && request()->ref) { $referrer = static::where('referral_code', request()->ref)->first(); if ($referrer) { $model->referred_by = $referrer->id; $model->save(); $referrer->addReferral($model); } } }); } public function referrals() { return $this->hasMany(Referral::class, 'referrer_id'); } public function referredBy() { return $this->belongsTo(User::class, 'referred_by'); } public function referralCommissions() { return $this->hasMany(ReferralCommission::class, 'referrer_id'); } public function getReferralCountAttribute() { return $this->referrals()->where('status', 'active')->count(); } public function getReferralEarningsAttribute() { return $this->referralCommissions() ->where('status', 'paid') ->sum('commission_amount'); } public function getReferralLinkAttribute() { return route('register', ['ref' => $this->referral_code]); } public function generateReferralCode() { $this->referral_code = strtoupper(substr(md5($this->id . time() . uniqid()), 0, 8)); $this->save(); return $this->referral_code; } public function addReferral($user) { return $this->referrals()->create([ 'referred_id' => $user->id, 'referral_code' => $this->referral_code, 'status' => 'active', 'commission_rate' => config('referral.commission_rate', 10), 'joined_at' => now(), ]); } public function addCommission($order, $amount, $level = 1) { $referral = $this->referrals() ->where('referred_id', $order->user_id) ->first(); if (!$referral) { return null; } return $this->referralCommissions()->create([ 'referral_id' => $referral->id, 'order_id' => $order->id, 'commission_amount' => $amount, 'order_amount' => $order->price, 'commission_rate' => $referral->commission_rate, 'level' => $level, 'status' => 'pending', ]); } public function getReferralTree($depth = 3) { $tree = []; $currentLevel = [$this->id]; for ($i = 0; $i < $depth; $i++) { $nextLevel = []; $users = static::whereIn('referred_by', $currentLevel)->get(); foreach ($users as $user) { $tree[$i + 1][] = [ 'user' => $user, 'earnings' => $user->referralCommissions() ->where('level', $i + 1) ->sum('commission_amount'), ]; $nextLevel[] = $user->id; } $currentLevel = $nextLevel; if (empty($currentLevel)) break; } return $tree; } }