*/ public function segmentOptions(): array { return [ [ 'key' => 'all_household', 'name' => 'همه کاربران خانگی', 'description' => 'همه مشتریان نوع خانگی (آرشیو نشده)', ], [ 'key' => 'no_login', 'name' => 'هرگز وارد اپ نشده‌اند', 'description' => 'آخرین بازدید خالی است', ], [ 'key' => 'inactive_7d', 'name' => '۷ روز اخیر نیامده‌اند', 'description' => 'آخرین بازدید بیش از ۷ روز پیش یا هرگز', ], [ 'key' => 'inactive_30d', 'name' => '۳۰ روز اخیر نیامده‌اند', 'description' => 'آخرین بازدید بیش از ۳۰ روز پیش یا هرگز', ], [ 'key' => 'no_valid', 'name' => 'احراز هویت نشده', 'description' => 'is_legal = 0', ], [ 'key' => 'active_wallet', 'name' => 'کاربران فعال (دارای کیف)', 'description' => 'حداقل یک ردیف در wallets دارند', ], ]; } public function segmentLabel(string $key): string { foreach ($this->segmentOptions() as $opt) { if ($opt['key'] === $key) { return $opt['name']; } } return $key; } /** * @param array $segmentKeys * @return Collection */ public function resolveSegmentCustomers(array $segmentKeys): Collection { $byId = []; foreach ($segmentKeys as $key) { foreach ($this->customersForSegment((string) $key) as $row) { $id = (int) ($row['id'] ?? 0); if ($id > 0) { $byId[$id] = $row; } } } return collect(array_values($byId)); } /** * @param array $customerIds * @return Collection */ public function resolveCustomersByIds(array $customerIds): Collection { $ids = array_values(array_unique(array_filter(array_map('intval', $customerIds)))); if ($ids === []) { return collect(); } return Customer::query() ->whereIn('id', $ids) ->where('is_archive', false) ->get(['id', 'name', 'mobile']) ->map(fn (Customer $c) => [ 'id' => (int) $c->id, 'name' => $c->name, 'mobile' => $c->mobile, ]); } /** * @param array $segmentKeys */ public function buildAudienceLabel(string $audienceType, array $segmentKeys = [], int $recipientsCount = 0): string { return match ($audienceType) { self::TYPE_ALL => 'همه کاربران', self::TYPE_SEGMENT => collect($segmentKeys) ->map(fn ($k) => $this->segmentLabel((string) $k)) ->filter() ->implode(' + ') ?: 'گروهی', self::TYPE_CUSTOMERS => $recipientsCount <= 1 ? 'تکی' : ('تکی / چندنفره (' . $recipientsCount . ' نفر)'), default => $audienceType, }; } /** * @return array */ private function customersForSegment(string $key): array { $base = Customer::query() ->where('type', 2) ->where('is_archive', false); $query = match ($key) { 'all_household' => $base, 'no_login' => (clone $base)->whereNull('last_seen_at'), 'inactive_7d' => (clone $base)->where(function ($q) { $q->whereNull('last_seen_at') ->orWhere('last_seen_at', '<', now()->subDays(7)); }), 'inactive_30d' => (clone $base)->where(function ($q) { $q->whereNull('last_seen_at') ->orWhere('last_seen_at', '<', now()->subDays(30)); }), 'no_valid' => (clone $base)->where('is_legal', 0), 'active_wallet' => (clone $base)->whereIn('id', function ($q) { $q->select('owner')->from('wallets'); }), default => null, }; if ($query === null) { return []; } return $query->get(['id', 'name', 'mobile'])->map(fn (Customer $c) => [ 'id' => (int) $c->id, 'name' => $c->name, 'mobile' => $c->mobile, ])->all(); } }