365 lines
14 KiB
PHP
365 lines
14 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Currency;
|
|
use App\Models\PayoutRequest;
|
|
use App\Models\Referral;
|
|
use App\Models\ReferralSetting;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Inertia\Inertia;
|
|
|
|
class ReferralController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
$user = Auth::user();
|
|
$settings = ReferralSetting::current();
|
|
|
|
if ($user->isSuperAdmin()) {
|
|
return $this->superAdminView($settings);
|
|
} else {
|
|
return $this->companyView($user, $settings);
|
|
}
|
|
}
|
|
|
|
private function superAdminView($settings)
|
|
{
|
|
$totalReferralUsers = User::whereNotNull('used_referral_code')
|
|
->where('used_referral_code', '!=', 0)
|
|
->count();
|
|
|
|
$pendingPayouts = PayoutRequest::where('status', 'pending')->count();
|
|
$totalCommissionPaid = PayoutRequest::where('status', 'approved')->sum('amount');
|
|
|
|
if (isDemo()) {
|
|
// For demo mode, get total counts without month filtering
|
|
$monthlyReferrals = User::whereNotNull('used_referral_code')
|
|
->where('used_referral_code', '!=', 0)
|
|
->count();
|
|
|
|
$monthlyPayouts = PayoutRequest::where('status', 'approved')
|
|
->sum('amount') ?: 0;
|
|
} else {
|
|
// For normal mode, get monthly data and sum it
|
|
$monthlyReferralsData = User::whereNotNull('used_referral_code')
|
|
->selectRaw('MONTH(created_at) as month, COUNT(*) as count')
|
|
->whereYear('created_at', date('Y'))
|
|
->groupBy('month')
|
|
->pluck('count', 'month')
|
|
->toArray();
|
|
|
|
$monthlyReferrals = array_sum($monthlyReferralsData);
|
|
|
|
$monthlyPayoutsData = PayoutRequest::where('status', 'approved')
|
|
->selectRaw('MONTH(created_at) as month, SUM(amount) as total')
|
|
->whereYear('created_at', date('Y'))
|
|
->groupBy('month')
|
|
->pluck('total', 'month')
|
|
->toArray();
|
|
|
|
$monthlyPayouts = array_sum($monthlyPayoutsData);
|
|
}
|
|
|
|
$topCompanies = User::select('users.id', 'users.name', 'users.email', 'users.referral_code')
|
|
->selectRaw('COUNT(referrals.id) as referral_count, SUM(referrals.amount) as total_earned')
|
|
->leftJoin('referrals', 'users.id', '=', 'referrals.company_id')
|
|
->where('users.type', 'company')
|
|
->whereNotNull('users.referral_code')
|
|
->groupBy('users.id', 'users.name', 'users.email', 'users.referral_code')
|
|
->orderByDesc('referral_count')
|
|
->limit(10)
|
|
->get();
|
|
|
|
$payoutRequests = PayoutRequest::with('company')
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(10);
|
|
|
|
// Get all referred users for superadmin with pagination
|
|
$referredUsers = User::whereNotNull('used_referral_code')
|
|
->with(['plan', 'referrals', 'planOrders' => function ($query) {
|
|
$query->where('status', 'approved')->orderBy('created_at', 'desc')->limit(1);
|
|
}])
|
|
->where('used_referral_code', '!=', 0)
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(5)
|
|
->withQueryString();
|
|
|
|
// Always use super admin currency for plan pricing
|
|
$superAdmin = User::where('type', 'superadmin')->first();
|
|
$superAdminSettings = settings($superAdmin->id);
|
|
$currency = $superAdminSettings ? ($superAdminSettings['defaultCurrency'] ?? 'USD') : 'USD';
|
|
$currencySymbol = '$';
|
|
if (! empty($currency)) {
|
|
$currencyData = Currency::where('code', $currency)->first();
|
|
$currencySymbol = $currencyData ? $currencyData->symbol : '$';
|
|
}
|
|
|
|
return Inertia::render('referral/index', [
|
|
'userType' => 'superadmin',
|
|
'settings' => $settings,
|
|
'stats' => [
|
|
'totalReferralUsers' => $totalReferralUsers,
|
|
'pendingPayouts' => $pendingPayouts,
|
|
'totalCommissionPaid' => $totalCommissionPaid,
|
|
'monthlyReferrals' => $monthlyReferrals,
|
|
'monthlyPayouts' => $monthlyPayouts,
|
|
'topCompanies' => $topCompanies,
|
|
],
|
|
'payoutRequests' => $payoutRequests,
|
|
'referredUsers' => $referredUsers,
|
|
'currency' => $currency,
|
|
'currencySymbol' => $currencySymbol,
|
|
]);
|
|
}
|
|
|
|
private function companyView($user, $settings)
|
|
{
|
|
$totalReferrals = Referral::where('company_id', $user->id)->count();
|
|
|
|
$totalEarned = Referral::where('company_id', $user->id)->sum('amount');
|
|
$totalPayoutRequests = PayoutRequest::where('company_id', $user->id)->count();
|
|
$pendingAmount = PayoutRequest::where('company_id', $user->id)
|
|
->where('status', 'pending')
|
|
->sum('amount');
|
|
$availableBalance = $totalEarned - PayoutRequest::where('company_id', $user->id)
|
|
->whereIn('status', ['pending', 'approved'])
|
|
->sum('amount');
|
|
|
|
$payoutRequests = PayoutRequest::where('company_id', $user->id)
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(10);
|
|
|
|
// Get referred users count (users who used this company's referral code)
|
|
$referredUsersCount = User::where('used_referral_code', $user->referral_code)->count();
|
|
|
|
// Get recent referred users
|
|
$recentReferredUsers = User::where('used_referral_code', $user->referral_code)
|
|
->with(['plan', 'planOrders' => function ($query) {
|
|
$query->where('status', 'approved')->orderBy('created_at', 'desc')->limit(1);
|
|
}])
|
|
->orderBy('created_at', 'desc')
|
|
->limit(5)
|
|
->get()
|
|
->map(function ($referredUser) {
|
|
return [
|
|
'id' => $referredUser->id,
|
|
'name' => $referredUser->name,
|
|
'email' => $referredUser->email,
|
|
'avatar' => check_file($referredUser->avatar) ? get_file($referredUser->avatar) : get_file('avatars/avatar.png'),
|
|
'plan' => $referredUser->plan,
|
|
'plan_orders' => $referredUser->planOrders,
|
|
];
|
|
});
|
|
|
|
// Get all referred users for the company with pagination
|
|
$referredUsers = User::where('used_referral_code', $user->referral_code)
|
|
->with(['plan', 'referrals', 'planOrders' => function ($query) {
|
|
$query->where('status', 'approved')->orderBy('created_at', 'desc')->limit(1);
|
|
}])
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(5)
|
|
->withQueryString();
|
|
|
|
// Generate referral code if not exists
|
|
if (! $user->referral_code) {
|
|
$user->referral_code = 'REF'.str_pad($user->id, 6, '0', STR_PAD_LEFT);
|
|
$user->save();
|
|
}
|
|
|
|
$referralLink = url('/register?ref='.$user->referral_code);
|
|
|
|
// Always use super admin currency for plan pricing
|
|
$superAdmin = User::where('type', 'superadmin')->first();
|
|
$superAdminSettings = settings($superAdmin->id);
|
|
$currency = $superAdminSettings ? ($superAdminSettings['defaultCurrency'] ?? 'USD') : 'USD';
|
|
$currencySymbol = '$';
|
|
if (! empty($currency)) {
|
|
$currencyData = Currency::where('code', $currency)->first();
|
|
$currencySymbol = $currencyData ? $currencyData->symbol : '$';
|
|
}
|
|
|
|
return Inertia::render('referral/index', [
|
|
'userType' => 'company',
|
|
'settings' => $settings,
|
|
'stats' => [
|
|
'totalReferrals' => $totalReferrals,
|
|
'totalEarned' => $totalEarned,
|
|
'totalPayoutRequests' => $totalPayoutRequests,
|
|
'availableBalance' => $availableBalance,
|
|
'referredUsersCount' => $referredUsersCount,
|
|
],
|
|
'payoutRequests' => $payoutRequests,
|
|
'referralLink' => $referralLink,
|
|
'recentReferredUsers' => $recentReferredUsers,
|
|
'referredUsers' => $referredUsers,
|
|
'currency' => $currency,
|
|
'currencySymbol' => $currencySymbol,
|
|
]);
|
|
}
|
|
|
|
public function updateSettings(Request $request)
|
|
{
|
|
$request->validate([
|
|
'commission_percentage' => 'required|numeric|min:0|max:100',
|
|
'threshold_amount' => 'required|numeric|min:0',
|
|
'guidelines' => 'nullable|string',
|
|
'is_enabled' => 'boolean',
|
|
]);
|
|
|
|
$settings = ReferralSetting::current();
|
|
$settings->update($request->all());
|
|
|
|
return back()->with('success', __('Referral settings updated successfully'));
|
|
}
|
|
|
|
public function createPayoutRequest(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
$settings = ReferralSetting::current();
|
|
|
|
$request->validate([
|
|
'amount' => 'required|numeric|min:1',
|
|
]);
|
|
|
|
$totalEarned = Referral::where('company_id', $user->id)->sum('amount');
|
|
$totalRequested = PayoutRequest::where('company_id', $user->id)
|
|
->whereIn('status', ['pending', 'approved'])
|
|
->sum('amount');
|
|
$availableBalance = $totalEarned - $totalRequested;
|
|
|
|
if ($request->amount > $availableBalance) {
|
|
return back()->withErrors(['amount' => __('Insufficient balance')]);
|
|
}
|
|
|
|
if ($request->amount < $settings->threshold_amount) {
|
|
return back()->withErrors(['amount' => __('Amount must be at least $ :amount', ['amount' => $settings->threshold_amount])]);
|
|
}
|
|
|
|
PayoutRequest::create([
|
|
'company_id' => $user->id,
|
|
'amount' => $request->amount,
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
return back()->with('success', __('Payout request submitted successfully'));
|
|
}
|
|
|
|
public function approvePayoutRequest(PayoutRequest $payoutRequest)
|
|
{
|
|
$payoutRequest->update(['status' => 'approved']);
|
|
|
|
return back()->with('success', __('Payout request approved'));
|
|
}
|
|
|
|
public function rejectPayoutRequest(PayoutRequest $payoutRequest, Request $request)
|
|
{
|
|
$payoutRequest->update([
|
|
'status' => 'rejected',
|
|
'notes' => $request->notes,
|
|
]);
|
|
|
|
return back()->with('success', __('Payout request rejected'));
|
|
}
|
|
|
|
public function getReferredUsers(Request $request)
|
|
{
|
|
$user = Auth::user();
|
|
// Always use super admin currency for plan pricing
|
|
$superAdmin = User::where('type', 'superadmin')->first();
|
|
$superAdminSettings = settings($superAdmin->id);
|
|
$currency = $superAdminSettings ? ($superAdminSettings['defaultCurrency'] ?? 'USD') : 'USD';
|
|
$currencySymbol = '$';
|
|
if (! empty($currency)) {
|
|
$currencyData = Currency::where('code', $currency)->first();
|
|
$currencySymbol = $currencyData ? $currencyData->symbol : '$';
|
|
}
|
|
if ($user->isSuperAdmin()) {
|
|
// Super admin can see all referred users
|
|
$referredUsers = User::whereNotNull('used_referral_code')
|
|
->with(['plan', 'referrals', 'planOrders' => function ($query) {
|
|
$query->where('status', 'approved')->orderBy('created_at', 'desc')->limit(1);
|
|
}])
|
|
->where('used_referral_code', '!=', 0)
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(15)
|
|
->withQueryString();
|
|
|
|
} else {
|
|
// Company can see users who used their referral code
|
|
$referredUsers = User::where('used_referral_code', $user->referral_code)
|
|
->with(['plan', 'referrals', 'planOrders' => function ($query) {
|
|
$query->where('status', 'approved')->orderBy('created_at', 'desc')->limit(1);
|
|
}])
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(15)
|
|
->withQueryString();
|
|
}
|
|
|
|
return Inertia::render('referral/referred-users', [
|
|
'referredUsers' => $referredUsers,
|
|
'userType' => $user->isSuperAdmin() ? 'superadmin' : 'company',
|
|
'currency' => $currency,
|
|
'currencySymbol' => $currencySymbol,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create referral record when user purchases a plan
|
|
*/
|
|
public static function createReferralRecord(User $user, $billingCycle = null)
|
|
{
|
|
$settings = ReferralSetting::current();
|
|
|
|
if (! $settings->is_enabled || ! $user->used_referral_code || ! $user->plan) {
|
|
return;
|
|
}
|
|
|
|
// Check if referral record already exists
|
|
$existingReferral = Referral::where('user_id', $user->id)
|
|
->where('plan_id', $user->plan_id)
|
|
->first();
|
|
|
|
if ($existingReferral) {
|
|
return; // Already created
|
|
}
|
|
|
|
$referrer = User::where('referral_code', $user->used_referral_code)
|
|
->where('type', 'company')
|
|
->first();
|
|
|
|
if (! $referrer) {
|
|
return;
|
|
}
|
|
|
|
// Get the actual paid amount from the most recent plan order
|
|
$planOrder = \App\Models\PlanOrder::where('user_id', $user->id)
|
|
->where('plan_id', $user->plan_id)
|
|
->where('status', 'approved')
|
|
->orderBy('created_at', 'desc')
|
|
->first();
|
|
|
|
// Use the actual paid amount if available, otherwise use plan price based on billing cycle
|
|
if ($planOrder && $planOrder->final_price > 0) {
|
|
$planPrice = $planOrder->final_price;
|
|
} elseif ($planOrder && $planOrder->billing_cycle === 'yearly' && $user->plan->yearly_price) {
|
|
$planPrice = $user->plan->yearly_price;
|
|
} else {
|
|
$planPrice = $user->plan->price ?? 0;
|
|
}
|
|
$commissionAmount = ($planPrice * $settings->commission_percentage) / 100;
|
|
|
|
if ($commissionAmount > 0) {
|
|
Referral::create([
|
|
'user_id' => $user->id,
|
|
'company_id' => $referrer->id,
|
|
'commission_percentage' => $settings->commission_percentage,
|
|
'amount' => $commissionAmount,
|
|
'plan_id' => $user->plan_id,
|
|
]);
|
|
}
|
|
}
|
|
}
|