188 خطوط
14 KiB
PHP
188 خطوط
14 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\CallResult;
|
|
use App\Models\LeadStatus;
|
|
use App\Models\LostReason;
|
|
use App\Models\PipelineStage;
|
|
use App\Models\Setting;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Seeder;
|
|
|
|
class DatabaseSeeder extends Seeder
|
|
{
|
|
public function run(): void
|
|
{
|
|
$this->call(RolePermissionSeeder::class);
|
|
$this->seedLeadStatuses();
|
|
$this->seedPipelineStages();
|
|
$this->seedCallResults();
|
|
$this->seedSettings();
|
|
$this->seedDemoUsers();
|
|
}
|
|
|
|
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::updateOrCreate(['email' => 'admin@crm.com'], [
|
|
'name' => 'مدیر سیستم',
|
|
'email' => 'admin@crm.com',
|
|
'password' => bcrypt('password'),
|
|
'phone' => '09121111111',
|
|
'is_active' => true,
|
|
]);
|
|
$admin->syncRoles(['admin']);
|
|
|
|
$supervisor = User::updateOrCreate(['email' => 'supervisor@crm.com'], [
|
|
'name' => 'سرپرست فروش',
|
|
'email' => 'supervisor@crm.com',
|
|
'password' => bcrypt('password'),
|
|
'phone' => '09122222222',
|
|
'is_active' => true,
|
|
]);
|
|
$supervisor->syncRoles(['supervisor']);
|
|
|
|
$agent = User::updateOrCreate(['email' => 'agent@crm.com'], [
|
|
'name' => 'کارشناس فروش',
|
|
'email' => 'agent@crm.com',
|
|
'password' => bcrypt('password'),
|
|
'phone' => '09123333333',
|
|
'is_active' => true,
|
|
]);
|
|
$agent->syncRoles(['agent']);
|
|
}
|
|
}
|