option('connection') ?: config('helpdesk.legacy_connection', config('database.default'))); $source = DB::connection($connectionName); $schema = Schema::connection($connectionName); foreach (['tickets', 'tickets_categories'] as $table) { if (! $schema->hasTable($table)) { $this->error("Source table {$table} was not found on connection [{$connectionName}]."); return self::FAILURE; } } if ($this->option('fresh')) { LegacyComment::query()->delete(); LegacyTicket::query()->delete(); LegacyCategory::query()->delete(); } $this->importCategories($source); $this->importTickets($source, $schema); $this->importComments($source, $schema); $this->refreshCategoryCounts(); $this->info(sprintf('Legacy import complete: %d tickets, %d categories, %d comments.', LegacyTicket::count(), LegacyCategory::count(), LegacyComment::count())); return self::SUCCESS; } private function importCategories(ConnectionInterface $source): void { $source->table('tickets_categories')->orderBy('id')->chunk(500, function ($rows): void { foreach ($rows as $row) { LegacyCategory::updateOrCreate(['legacy_id' => $row->id], ['name' => (string) $row->name, 'color' => $row->color ?? null]); } }); } private function importTickets(ConnectionInterface $source, $schema): void { $columns = collect($schema->getColumnListing('tickets')); $lookups = [ 'category' => $this->lookup($source, $schema, 'tickets_categories'), 'status' => $this->lookup($source, $schema, 'tickets_statuses'), 'priority' => $this->lookup($source, $schema, 'tickets_priorities'), 'project' => $this->lookup($source, $schema, 'projects'), 'user' => $this->lookup($source, $schema, 'users'), ]; $source->table('tickets')->orderBy('id')->chunk(250, function ($rows) use ($columns, $lookups): void { foreach ($rows as $row) { $data = (array) $row; LegacyTicket::updateOrCreate(['legacy_id' => $row->id], [ 'reference' => $data['reference'] ?? null, 'subject' => (string) ($data['subject'] ?? 'Legacy ticket #'.$row->id), 'content' => $data['content'] ?? null, 'html_content' => $data['htmlcontent'] ?? null, 'legacy_category_id' => $data['category_id'] ?? null, 'category_name' => $lookups['category'][$data['category_id'] ?? 0] ?? null, 'status_name' => $lookups['status'][$data['status_id'] ?? 0] ?? null, 'priority_name' => $lookups['priority'][$data['priority_id'] ?? 0] ?? null, 'requester_name' => $lookups['user'][$data['user_id'] ?? 0] ?? null, 'agent_name' => $lookups['user'][$data['agent_id'] ?? 0] ?? null, 'project_name' => $lookups['project'][$data['project_id'] ?? 0] ?? null, 'legacy_created_at' => $data['created_at'] ?? null, 'legacy_updated_at' => $data['updated_at'] ?? null, 'completed_at' => $data['completed_at'] ?? null, 'archived_at' => $data['archived_at'] ?? null, 'legacy_data' => $data, ]); } }); } private function importComments(ConnectionInterface $source, $schema): void { if (! $schema->hasTable('tickets_comments')) return; $users = $this->lookup($source, $schema, 'users'); $source->table('tickets_comments')->orderBy('id')->chunk(500, function ($rows) use ($users): void { foreach ($rows as $row) { $data = (array) $row; LegacyComment::updateOrCreate(['legacy_id' => $row->id], [ 'legacy_ticket_id' => $data['ticket_id'], 'author_name' => $users[$data['user_id'] ?? 0] ?? null, 'content' => $data['content'] ?? null, 'html_content' => $data['htmlcontent'] ?? null, 'legacy_created_at' => $data['created_at'] ?? null, 'legacy_updated_at' => $data['updated_at'] ?? null, ]); } }); } private function lookup(ConnectionInterface $source, $schema, string $table): array { if (! $schema->hasTable($table)) return []; $columns = $schema->getColumnListing($table); $nameColumn = in_array('name', $columns, true) ? 'name' : (in_array('username', $columns, true) ? 'username' : null); if ($nameColumn === null) return []; try { return $source->table($table)->pluck($nameColumn, 'id')->map(fn ($v) => (string) $v)->all(); } catch (Throwable) { return []; } } private function refreshCategoryCounts(): void { LegacyCategory::query()->each(function (LegacyCategory $category): void { $category->update(['ticket_count' => LegacyTicket::query()->where('legacy_category_id', $category->legacy_id)->count()]); }); } }