settings ?? []; $plan = (string) ($settings['plan'] ?? 'free'); if (in_array($plan, ['pro', 'enterprise'], true) && ! empty($settings['plan_expires_at'])) { if (Carbon::parse($settings['plan_expires_at'])->isPast()) { return 'free'; } } return array_key_exists($plan, config('qms.plans', [])) ? $plan : 'free'; } public function plan(Organization $organization): string { return $this->planKey($organization); } public function isPro(Organization $organization): bool { return $this->planKey($organization) === 'pro'; } public function isEnterprise(Organization $organization): bool { return $this->planKey($organization) === 'enterprise'; } public function hasPaidPlan(Organization $organization): bool { return in_array($this->planKey($organization), ['pro', 'enterprise'], true); } public function activeBranchCount(Organization $organization): int { return Branch::query() ->where('organization_id', $organization->id) ->where('is_active', true) ->count(); } public function maxBranches(Organization $organization): ?int { return config('qms.plans.'.$this->planKey($organization).'.max_branches'); } public function maxQueues(Organization $organization): ?int { return config('qms.plans.'.$this->planKey($organization).'.max_queues'); } public function canAddBranch(Organization $organization, int $currentCount): bool { $max = $this->maxBranches($organization); return $max === null || $currentCount < $max; } public function canAddQueue(Organization $organization, int $currentCount): bool { $max = $this->maxQueues($organization); return $max === null || $currentCount < $max; } public function proPricePerBranchMinor(): int { return (int) config( 'qms.plans.pro.price_minor_per_branch', config('qms.plans.pro.price_minor', 249000) ); } public function proPriceMinor(Organization $organization): int { return $this->priceForBranches('pro', $this->activeBranchCount($organization)); } public function enterprisePricePerBranchMinor(): int { return (int) config('qms.plans.enterprise.price_minor_per_branch', 449000); } public function enterprisePriceMinor(Organization $organization): int { return $this->priceForBranches('enterprise', $this->activeBranchCount($organization)); } /** Fixed branch count × per-branch rate (checkout when the user picks seats). */ public function priceForBranches(string $plan, int $branches): int { $branches = max(1, $branches); $rate = $plan === 'enterprise' ? $this->enterprisePricePerBranchMinor() : $this->proPricePerBranchMinor(); return $branches * $rate; } public function resolveCheckoutBranches(Organization $organization, int $requested): int { $branches = max(1, min(999, $requested)); $active = max(1, $this->activeBranchCount($organization)); return max($branches, $active); } public function canSubscribeEnterprise(Organization $organization): bool { return $this->activeBranchCount($organization) >= (int) config('qms.enterprise.min_branches', 2); } }