diff --git a/app/Http/Controllers/api/HomeController.php b/app/Http/Controllers/api/HomeController.php index 6dc20ca..407e25d 100644 --- a/app/Http/Controllers/api/HomeController.php +++ b/app/Http/Controllers/api/HomeController.php @@ -21,117 +21,30 @@ class HomeController extends Controller { } + public function index() + { + return $this->buildHomeResponse(); + } + public function homeV2() { - $user = auth()->user(); - - $this->checkAndGrantFreeSubscription($user); - - $this->refreshMarketSubscriptionAfterResponse($user); - - $recent = RecentArt::query()->where('user_id', $user->id)->get()->map(function ($q) { - return [ - 'id' => $q->law?->id, - 'name' => $q->law?->title, - 'is_locked' => $q->law?->is_locked, - ]; - }); - - $laws = Law::orderBy('created_at')->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'name' => $q->title, - 'is_locked' => $q->is_locked, - ]; - }); - - $categories = ['hagigi', 'kifari']; - $lawsByCategory = []; - - foreach ($categories as $category) { - $lawsByCategory[$category] = Law::whereHas('category', function ($q) use ($category) { - $q->where('type', $category); - })->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'title' => $q->title, - 'is_locked' => $q->is_locked, - 'category_id' => $q->category_id, - 'price' => $q->price, - 'image' => $q->image, - 'type' => 'law', - ]; - }); - } - - $free_law = Law::where('is_locked', false)->orderBy('created_at')->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'name' => $q->title, - 'is_locked' => $q->is_locked, - ]; - }); - - $freeSubscription = $user->userSubscribers() - ->whereHas('subscribe', function ($query) { - $query->where('is_free', true); - }) - ->where('expired_at', '>=', now()) - ->first(); - - $current_plan = null; - - if ($freeSubscription) { - $current_plan = [ - 'id' => $freeSubscription->id, - 'name' => $freeSubscription->subscribe->name, - 'price' => $freeSubscription->subscribe->price, - 'expired_day' => $freeSubscription->expired_at->diffInDays(now()), - 'is_free' => true, - ]; - } - - $latestSubscription = $user->userSubscribers() - ->where('expired_at', '>=', now()) - ->latest('expired_at') - ->first(); - - $expiredDays = UserSubscriber::query()->where('user_id', $user->id)->where('expired_at', '>=', now())->get()->sum(function ($subscriber) { - return $subscriber->expired_at->diffInDays(now()); - }); - - if ($latestSubscription) { - $current_plan = [ - 'id' => $latestSubscription->id, - 'name' => $latestSubscription->subscribe->name ?? 'Subscription', - 'price' => $latestSubscription->subscribe->price ?? 100, - 'expired_day' => $expiredDays, - 'is_free' => (bool)$latestSubscription->is_free, - ]; - } - - $unread_notifications_count = Notification::unreadForUser($user->id)->count(); - - $homeData = [ - 'recent' => $recent, - 'laws' => $lawsByCategory, - 'last_law' => $laws, - 'free' => $free_law, - 'current_plan' => $current_plan, - 'unread_notifications_count' => $unread_notifications_count, - ]; - - return $this->success([ - 'home' => $homeData, - 'hoqoqi_list' => $this->getCategoryList(1), - 'keyfari_list' => $this->getCategoryList(2), - ]); + return $this->buildHomeResponse(); } public function homeV3() + { + return $this->buildHomeResponse(); + } + + /** + * UNIFIED CORE LOGIC: Safely builds the home response for ALL app versions (v1, v2, v3) + * By centralizing this, we ensure no old app version ever suffers from the math bug! + */ + private function buildHomeResponse() { $user = auth()->user(); + // 1. Safely grant free subs (Won't overlap with paid plans) $this->checkAndGrantFreeSubscription($user); $this->refreshMarketSubscriptionAfterResponse($user); @@ -179,7 +92,7 @@ class HomeController extends Controller ]; }); - // --- V3 FIXED LOGIC --- + // --- THE FIXED AUTHORITY LOGIC APPLIED TO ALL VERSIONS --- $activeSubscribers = $user->userSubscribers() ->with('subscribe') ->where('expired_at', '>=', now()) @@ -188,12 +101,21 @@ class HomeController extends Controller $current_plan = null; if ($activeSubscribers->isNotEmpty()) { - $latestSubscription = $activeSubscribers->sortByDesc('expired_at')->first(); + // Separate Paid from Free + $paidSubscriptions = $activeSubscribers->reject(function ($subscriber) { + return $subscriber->is_free || ($subscriber->subscribe && $subscriber->subscribe->is_free); + }); - // FIX 1: Never sum the days. Calculate distance to the furthest expiration date. + // AUTHORITY RULE: Paid plans override Free plans + if ($paidSubscriptions->isNotEmpty()) { + $latestSubscription = $paidSubscriptions->sortByDesc('expired_at')->first(); + } else { + $latestSubscription = $activeSubscribers->sortByDesc('expired_at')->first(); + } + + // Fixed math (No sum) $expiredDays = $latestSubscription->expired_at->diffInDays(now()); - // FIX 2: Accurately check if the active plan is free $isFree = (bool) ( $latestSubscription->is_free || ($latestSubscription->subscribe && $latestSubscription->subscribe->is_free) @@ -254,126 +176,19 @@ class HomeController extends Controller return $data; } - public function index() - { - $user = auth()->user(); - - $this->checkAndGrantFreeSubscription($user); - - $this->refreshMarketSubscriptionAfterResponse($user); - - $recent = RecentArt::query()->where('user_id', $user->id)->get()->map(function ($q) { - return [ - 'id' => $q->law?->id, - 'name' => $q->law?->title, - 'is_locked' => $q->law?->is_locked, - ]; - }); - - $laws = Law::orderBy('created_at')->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'name' => $q->title, - 'is_locked' => $q->is_locked, - ]; - }); - - $categories = ['hagigi', 'kifari']; - $lawsByCategory = []; - - foreach ($categories as $category) { - $lawsByCategory[$category] = Law::whereHas('category', function ($q) use ($category) { - $q->where('type', $category); - })->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'title' => $q->title, - 'is_locked' => $q->is_locked, - 'category_id' => $q->category_id, - 'price' => $q->price, - 'image' => $q->image, - 'type' => 'law', - ]; - }); - } - - $free_law = Law::where('is_locked', false)->orderBy('created_at')->get()->map(function ($q) { - return [ - 'id' => $q->id, - 'name' => $q->title, - 'is_locked' => $q->is_locked, - ]; - }); - - $freeSubscription = $user->userSubscribers() - ->whereHas('subscribe', function ($query) { - $query->where('is_free', true); - }) - ->where('expired_at', '>=', now()) - ->first(); - - $current_plan = null; - - if ($freeSubscription) { - $current_plan = [ - 'id' => $freeSubscription->id, - 'name' => $freeSubscription->subscribe->name, - 'price' => $freeSubscription->subscribe->price, - 'expired_day' => $freeSubscription->expired_at->diffInDays(now()), - 'is_free' => true, - ]; - } - - $latestSubscription = $user->userSubscribers() - ->where('expired_at', '>=', now()) - ->latest('expired_at') - ->first(); - - $expiredDays = UserSubscriber::query()->where('user_id', $user->id)->where('expired_at', '>=', now())->get()->sum(function ($subscriber) { - return $subscriber->expired_at->diffInDays(now()); - }); - - if ($latestSubscription) { - $current_plan = [ - 'id' => $latestSubscription->id, - 'name' => $latestSubscription->subscribe->name ?? 'Subscription', - 'price' => $latestSubscription->subscribe->price ?? 100, - 'expired_day' => $expiredDays, - 'is_free' => (bool)$latestSubscription->is_free, - ]; - } - - $unread_notifications_count = Notification::unreadForUser($user->id)->count(); - - return $this->success([ - 'recent' => $recent, - 'laws' => $lawsByCategory, - 'last_law' => $laws, - 'free' => $free_law, - 'current_plan' => $current_plan, - 'unread_notifications_count' => $unread_notifications_count, - ]); - } - - /** - * Helper to automatically assign a free plan safely. - */ private function checkAndGrantFreeSubscription($user): void { - // 1. Have they ever used a free plan? $hasUsedFreePlan = $user->userSubscribers() ->whereHas('subscribe', function ($query) { $query->where('is_free', true); })->exists(); - // 2. Do they currently have an active PAID plan? $hasActivePaidPlan = $user->userSubscribers() ->where('expired_at', '>', now()) ->whereHas('subscribe', function ($query) { $query->where('is_free', false); })->exists(); - // FIX 3: Only grant the free plan if they have never had one AND they aren't currently paying! if (!$hasUsedFreePlan && !$hasActivePaidPlan) { $freePlan = SubscribePlan::where('is_free', true)->where('is_active', true)->first();