seedRoles(); $this->seedLeadStatuses(); $this->seedPipelineStages(); $this->seedCallResults(); $this->seedSettings(); $this->seedDemoUsers(); } private function seedRoles(): void { $admin = Role::firstOrCreate(['name' => 'admin', 'guard_name' => 'web']); Role::firstOrCreate(['name' => 'supervisor', 'guard_name' => 'web']); Role::firstOrCreate(['name' => 'agent', 'guard_name' => 'web']); $permissions = [ 'view_leads', 'create_leads', 'edit_leads', 'delete_leads', 'import_leads', 'export_leads', 'view_full_phone', 'view_reports', 'export_reports', 'manage_users', 'manage_roles', 'manage_campaigns', 'manage_settings', 'view_activity_logs', 'manage_scripts', 'view_quality_reviews', 'create_quality_reviews', 'listen_recordings', 'view_all_calls', 'view_team_calls', 'view_own_calls', 'assign_leads', 'reassign_leads', ]; foreach ($permissions as $p) { Permission::firstOrCreate(['name' => $p, 'guard_name' => 'web']); } $admin->syncPermissions(Permission::all()); } private function seedLeadStatuses(): void { $statuses = [ ['slug' => 'open', 'name' => 'در جریان', 'color' => '#2563EB', 'sort_order' => 0, 'is_default' => true, 'is_won' => false, 'is_lost' => false], ['slug' => 'won', 'name' => 'موفق', 'color' => '#16A34A', 'sort_order' => 1, 'is_default' => false, 'is_won' => true, 'is_lost' => false], ['slug' => 'lost', 'name' => 'ناموفق', 'color' => '#DC2626', 'sort_order' => 2, 'is_default' => false, 'is_won' => false, 'is_lost' => true], ]; foreach ($statuses as $s) { LeadStatus::updateOrCreate(['slug' => $s['slug']], $s); } } private function seedPipelineStages(): void { $stages = [ ['slug' => 'new', 'name' => 'لید جدید', 'color' => '#3B82F6', 'sort_order' => 0, 'is_default' => true, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => false], ['slug' => 'waiting_call', 'name' => 'در انتظار تماس', 'color' => '#6366F1', 'sort_order' => 1, 'is_default' => false, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => false], ['slug' => 'contacted', 'name' => 'تماس برقرار شد', 'color' => '#06B6D4', 'sort_order' => 2, 'is_default' => false, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => false], ['slug' => 'qualified', 'name' => 'واجد شرایط / علاقه‌مند', 'color' => '#22C55E', 'sort_order' => 3, 'is_default' => false, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => false], ['slug' => 'follow_up', 'name' => 'پیگیری', 'color' => '#F59E0B', 'sort_order' => 4, 'is_default' => false, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => true], ['slug' => 'proposal_sent', 'name' => 'پیشنهاد ارسال شد', 'color' => '#8B5CF6', 'sort_order' => 5, 'is_default' => false, 'is_won' => false, 'is_lost' => false, 'requires_follow_up' => false], ['slug' => 'closed', 'name' => 'موفق / ناموفق', 'color' => '#334155', 'sort_order' => 6, 'is_default' => false, 'is_won' => true, 'is_lost' => true, 'requires_follow_up' => false], ]; foreach ($stages as $s) { PipelineStage::updateOrCreate(['slug' => $s['slug']], $s); } } private function seedCallResults(): void { $results = [ ['slug' => 'no_answer', 'name' => 'پاسخ نداد', 'color' => '#F59E0B', 'requires_follow_up' => true, 'phone_status' => 'no_answer', 'sort_order' => 0], ['slug' => 'busy', 'name' => 'اشغال بود', 'color' => '#F97316', 'requires_follow_up' => true, 'phone_status' => 'no_answer', 'sort_order' => 1], ['slug' => 'off', 'name' => 'خاموش بود', 'color' => '#64748B', 'requires_follow_up' => true, 'phone_status' => 'inactive', 'sort_order' => 2], ['slug' => 'wrong_number', 'name' => 'شماره اشتباه', 'color' => '#EF4444', 'is_negative' => true, 'is_final' => true, 'phone_status' => 'wrong', 'sort_order' => 3], ['slug' => 'call_later', 'name' => 'بعداً تماس بگیرید', 'color' => '#3B82F6', 'requires_follow_up' => true, 'sort_order' => 4], ['slug' => 'not_decision_maker', 'name' => 'تصمیم‌گیرنده نبود', 'color' => '#8B5CF6', 'requires_follow_up' => true, 'sort_order' => 5], ['slug' => 'not_interested', 'name' => 'علاقه‌مند نبود', 'color' => '#EF4444', 'is_negative' => true, 'sort_order' => 6], ['slug' => 'interested', 'name' => 'علاقه‌مند بود', 'color' => '#22C55E', 'is_positive' => true, 'sort_order' => 7], ['slug' => 'needs_follow_up', 'name' => 'نیازمند پیگیری', 'color' => '#0EA5E9', 'requires_follow_up' => true, 'sort_order' => 8], ['slug' => 'no_budget', 'name' => 'بودجه ندارد', 'color' => '#DC2626', 'is_negative' => true, 'sort_order' => 9], ['slug' => 'already_purchased', 'name' => 'قبلاً خرید کرده', 'color' => '#14B8A6', 'is_positive' => true, 'is_final' => true, 'sort_order' => 10], ['slug' => 'do_not_call', 'name' => 'عدم تماس مجدد', 'color' => '#475569', 'is_negative' => true, 'is_final' => true, 'sort_order' => 11], ['slug' => 'invalid_lead', 'name' => 'لید نامعتبر', 'color' => '#991B1B', 'is_negative' => true, 'is_final' => true, 'sort_order' => 12], ['slug' => 'answered', 'name' => 'پاسخ داد', 'color' => '#06B6D4', 'is_positive' => true, 'sort_order' => 13], ['slug' => 'proposal_sent', 'name' => 'پیشنهاد ارسال شد', 'color' => '#8B5CF6', 'is_positive' => true, 'sort_order' => 14], ['slug' => 'referral', 'name' => 'معرفی شماره جدید', 'color' => '#0EA5E9', 'is_positive' => true, 'requires_follow_up' => true, 'sort_order' => 15], ]; foreach ($results as $r) { CallResult::updateOrCreate(['slug' => $r['slug']], $r); } $stageIds = PipelineStage::pluck('id', 'slug'); $statusIds = LeadStatus::pluck('id', 'slug'); $transitions = [ 'answered' => ['stage' => 'contacted', 'phone' => 'active', 'next' => 'ثبت تماس انجام شد'], 'interested' => ['stage' => 'qualified', 'phone' => 'active', 'next' => 'ادامه مذاکره'], 'proposal_sent' => ['stage' => 'proposal_sent', 'phone' => 'active', 'next' => 'پیگیری پیشنهاد'], 'call_later' => ['stage' => 'follow_up', 'phone' => 'active', 'next' => 'پیگیری در زمان مشخص‌شده'], 'needs_follow_up' => ['stage' => 'follow_up', 'phone' => 'active', 'next' => 'پیگیری در زمان مشخص‌شده'], 'wrong_number' => ['phone' => 'wrong', 'next' => 'بررسی شماره جایگزین'], 'off' => ['phone' => 'inactive'], 'no_answer' => ['phone' => 'no_answer', 'next' => 'تماس مجدد در صف'], 'busy' => ['phone' => 'no_answer', 'next' => 'تماس مجدد در صف'], 'not_interested' => ['stage' => 'closed', 'status' => 'lost', 'phone' => 'inactive', 'next' => 'لید بسته شد'], 'do_not_call' => ['stage' => 'closed', 'status' => 'lost', 'phone' => 'inactive'], 'invalid_lead' => ['stage' => 'closed', 'status' => 'lost'], 'already_purchased' => ['stage' => 'closed', 'status' => 'won', 'phone' => 'active'], 'referral' => ['stage' => 'follow_up', 'phone' => 'active', 'next' => 'تماس با مخاطب معرفی‌شده'], ]; foreach ($transitions as $slug => $transition) { CallResult::where('slug', $slug)->update([ 'next_pipeline_stage_id' => isset($transition['stage']) ? ($stageIds[$transition['stage']] ?? null) : null, 'lead_status_id' => isset($transition['status']) ? ($statusIds[$transition['status']] ?? null) : null, 'phone_status' => $transition['phone'] ?? null, 'next_action' => $transition['next'] ?? null, ]); } foreach ([ ['slug' => 'no_budget', 'name' => 'بودجه ندارد', 'sort_order' => 0], ['slug' => 'no_need', 'name' => 'عدم نیاز', 'sort_order' => 1], ['slug' => 'competitor', 'name' => 'رقیب انتخاب شد', 'sort_order' => 2], ['slug' => 'no_response', 'name' => 'عدم پاسخگویی', 'sort_order' => 3], ['slug' => 'invalid_lead', 'name' => 'لید نامعتبر', 'sort_order' => 4], ] as $reason) { LostReason::updateOrCreate(['slug' => $reason['slug']], $reason + ['color' => '#DC2626', 'is_active' => true]); } } private function seedSettings(): void { $settings = [ ['key' => 'company_name', 'value' => 'CRM فروش', 'default_value' => 'CRM فروش', 'group' => 'general', 'type' => 'string', 'validation_rules' => ['string', 'max:255'], 'is_public' => true, 'is_runtime_enforced' => true, 'description' => 'نام نمایشی سامانه'], ['key' => 'phone_mask_enabled', 'value' => 'true', 'default_value' => 'true', 'group' => 'security', 'type' => 'boolean', 'validation_rules' => ['in:true,false,1,0'], 'is_public' => true, 'is_runtime_enforced' => true, 'description' => 'مخفی‌سازی شماره برای کاربران بدون مجوز'], ['key' => 'call_recording_enabled', 'value' => 'false', 'default_value' => 'false', 'group' => 'voip', 'type' => 'boolean', 'validation_rules' => ['in:true,false,1,0'], 'is_public' => true, 'is_runtime_enforced' => true, 'description' => 'فعال‌سازی ضبط تماس'], ['key' => 'voip_provider', 'value' => 'mock', 'default_value' => 'mock', 'group' => 'voip', 'type' => 'string', 'allowed_values' => ['mock', 'ami', 'api', 'socket'], 'is_runtime_enforced' => true], ['key' => 'voip_ami_host', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_ami_port', 'value' => '5038', 'group' => 'voip', 'type' => 'integer'], ['key' => 'voip_ami_username', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_ami_secret', 'value' => '', 'group' => 'voip', 'type' => 'string', 'is_secret' => true, 'is_runtime_enforced' => true], ['key' => 'voip_ami_channel_technology', 'value' => 'SIP', 'group' => 'voip', 'type' => 'string', 'allowed_values' => ['SIP', 'PJSIP']], ['key' => 'voip_ami_context', 'value' => 'from-internal', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_ami_caller_id_template', 'value' => 'CRM <{extension}>', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_ami_timeout', 'value' => '5', 'group' => 'voip', 'type' => 'integer'], ['key' => 'voip_ami_originate_timeout', 'value' => '30', 'group' => 'voip', 'type' => 'integer'], ['key' => 'voip_ami_recording_url', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_api_base_url', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_api_token', 'value' => '', 'group' => 'voip', 'type' => 'string', 'is_secret' => true, 'is_runtime_enforced' => true], ['key' => 'voip_api_call_path', 'value' => '/calls', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_api_status_path', 'value' => '/calls/{id}', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_api_recording_url', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_socket_host', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'voip_socket_port', 'value' => '', 'group' => 'voip', 'type' => 'integer'], ['key' => 'voip_socket_token', 'value' => '', 'group' => 'voip', 'type' => 'string', 'is_secret' => true, 'is_runtime_enforced' => true], ['key' => 'voip_socket_timeout', 'value' => '5', 'group' => 'voip', 'type' => 'integer'], ['key' => 'voip_socket_recording_url', 'value' => '', 'group' => 'voip', 'type' => 'string'], ['key' => 'session_timeout_minutes', 'value' => '120', 'default_value' => '120', 'group' => 'security', 'type' => 'integer', 'validation_rules' => ['integer', 'min:5'], 'is_runtime_enforced' => false], ['key' => 'strong_passwords_enabled', 'value' => 'false', 'default_value' => 'false', 'group' => 'security', 'type' => 'boolean', 'validation_rules' => ['in:true,false,1,0'], 'is_runtime_enforced' => false], ['key' => 'two_factor_enabled', 'value' => 'false', 'default_value' => 'false', 'group' => 'security', 'type' => 'boolean', 'validation_rules' => ['in:true,false,1,0'], 'is_runtime_enforced' => false], ['key' => 'login_attempt_limit', 'value' => '5', 'default_value' => '5', 'group' => 'security', 'type' => 'integer', 'validation_rules' => ['integer', 'min:1'], 'is_runtime_enforced' => false], ['key' => 'default_follow_up_hours', 'value' => '24', 'default_value' => '24', 'group' => 'follow_up', 'type' => 'integer', 'validation_rules' => ['integer', 'min:1'], 'is_runtime_enforced' => true], ['key' => 'duplicate_phone_policy', 'value' => 'warn', 'default_value' => 'warn', 'group' => 'duplicate', 'type' => 'string', 'validation_rules' => ['string'], 'allowed_values' => ['allow', 'warn', 'block', 'merge_suggestion'], 'is_runtime_enforced' => true], ]; foreach ($settings as $s) { Setting::updateOrCreate(['key' => $s['key']], $s); } } private function seedDemoUsers(): void { $admin = User::create([ 'name' => 'مدیر سیستم', 'email' => 'admin@crm.com', 'password' => bcrypt('password'), 'phone' => '09121111111', 'is_active' => true, ]); $admin->assignRole('admin'); $supervisor = User::create([ 'name' => 'سرپرست فروش', 'email' => 'supervisor@crm.com', 'password' => bcrypt('password'), 'phone' => '09122222222', 'is_active' => true, ]); $supervisor->assignRole('supervisor'); $agent = User::create([ 'name' => 'کارشناس فروش', 'email' => 'agent@crm.com', 'password' => bcrypt('password'), 'phone' => '09123333333', 'is_active' => true, ]); $agent->assignRole('agent'); } }