option('tenant_id'); $dryRun = $this->option('dry-run'); $this->info('=== 케이스/하단마감재 모델 → SAM 임포트 ==='); $this->info('Mode: '.($dryRun ? 'DRY-RUN' : 'LIVE')); $this->newLine(); // 케이스 (shutterbox) $this->info('--- 케이스 (shutterbox) ---'); $cases = DB::connection('chandj')->table('shutterbox')->whereNull('is_deleted')->get(); $this->info("chandj shutterbox: {$cases->count()}건"); $caseCreated = $this->importItems($cases, 'SHUTTERBOX_MODEL', $tenantId, $dryRun); $this->newLine(); // 하단마감재 (bottombar) $this->info('--- 하단마감재 (bottombar) ---'); $bars = DB::connection('chandj')->table('bottombar')->whereNull('is_deleted')->get(); $this->info("chandj bottombar: {$bars->count()}건"); $barCreated = $this->importItems($bars, 'BOTTOMBAR_MODEL', $tenantId, $dryRun); $this->newLine(); $this->info("결과: 케이스 {$caseCreated}건 + 하단마감재 {$barCreated}건"); if ($dryRun) { $this->info('🔍 DRY-RUN 완료.'); } return self::SUCCESS; } private function importItems($rows, string $category, int $tenantId, bool $dryRun): int { $created = 0; $skipped = 0; foreach ($rows as $row) { $code = $this->buildCode($row, $category); $name = $this->buildName($row, $category); $existing = DB::table('items') ->where('tenant_id', $tenantId) ->where('code', $code) ->whereNull('deleted_at') ->first(); if ($existing) { $skipped++; continue; } $components = $this->convertComponents(json_decode($row->bending_components ?? '[]', true) ?: []); $materialSummary = json_decode($row->material_summary ?? '{}', true) ?: []; $options = $this->buildOptions($row, $category, $components, $materialSummary); if (! $dryRun) { DB::table('items')->insert([ 'tenant_id' => $tenantId, 'code' => $code, 'name' => $name, 'item_type' => 'FG', 'item_category' => $category, 'unit' => 'SET', 'options' => json_encode($options, JSON_UNESCAPED_UNICODE), 'is_active' => true, 'created_at' => now(), 'updated_at' => now(), ]); } $created++; $this->line(" ✅ {$code} ({$name}) — 부품 ".count($components).'개'); } $this->info(" 생성: {$created}건 | 스킵: {$skipped}건"); return $created; } private function buildCode(object $row, string $category): string { if ($category === 'SHUTTERBOX_MODEL') { $size = ($row->box_width ?? ''). '*'.($row->box_height ?? ''); $exit = match ($row->exit_direction ?? '') { '양면 점검구' => '양면', '밑면 점검구' => '밑면', '후면 점검구' => '후면', default => $row->exit_direction ?? '', }; return "SB-{$size}-{$exit}"; } // BOTTOMBAR_MODEL $model = $row->model_name ?? 'UNKNOWN'; $finish = str_contains($row->finishing_type ?? '', 'SUS') ? 'SUS' : 'EGI'; return "BB-{$model}-{$finish}"; } private function buildName(object $row, string $category): string { if ($category === 'SHUTTERBOX_MODEL') { return "케이스 {$row->box_width}*{$row->box_height} {$row->exit_direction}"; } return "하단마감재 {$row->model_name} {$row->firstitem}"; } private function buildOptions(object $row, string $category, array $components, array $materialSummary): array { $base = [ 'author' => $row->author ?? null, 'registration_date' => $row->registration_date ?? null, 'search_keyword' => $row->search_keyword ?? null, 'memo' => $row->remark ?? null, 'components' => $components, 'material_summary' => $materialSummary, 'source' => 'chandj_'.(strtolower($category)), 'legacy_num' => $row->num, ]; if ($category === 'SHUTTERBOX_MODEL') { return array_merge($base, [ 'box_width' => (int) ($row->box_width ?? 0), 'box_height' => (int) ($row->box_height ?? 0), 'exit_direction' => $row->exit_direction ?? null, 'front_bottom_width' => $row->front_bottom_width ?? null, 'rail_width' => $row->rail_width ?? null, ]); } // BOTTOMBAR_MODEL return array_merge($base, [ 'model_name' => $row->model_name ?? null, 'item_sep' => $row->firstitem ?? null, 'model_UA' => $row->model_UA ?? null, 'finishing_type' => $row->finishing_type ?? null, 'bar_width' => $row->bar_width ?? null, 'bar_height' => $row->bar_height ?? null, ]); } private function convertComponents(array $legacyComps): array { return array_map(function ($c, $idx) { $inputs = $c['inputList'] ?? []; $rates = $c['bendingrateList'] ?? []; $sums = $c['sumList'] ?? []; $colors = $c['colorList'] ?? []; $angles = $c['AList'] ?? []; $bendingData = []; for ($i = 0; $i < count($inputs); $i++) { $bendingData[] = [ 'no' => $i + 1, 'input' => (float) ($inputs[$i] ?? 0), 'rate' => (string) ($rates[$i] ?? ''), 'sum' => (float) ($sums[$i] ?? 0), 'color' => (bool) ($colors[$i] ?? false), 'aAngle' => (bool) ($angles[$i] ?? false), ]; } $lastSum = ! empty($sums) ? (float) end($sums) : ($c['widthsum'] ?? 0); return [ 'orderNumber' => $idx + 1, 'itemName' => $c['itemName'] ?? '', 'material' => $c['material'] ?? '', 'quantity' => (int) ($c['quantity'] ?? 1), 'width_sum' => (float) $lastSum, 'bendingData' => $bendingData, 'legacy_bending_num' => $c['source_num'] ?? $c['num'] ?? null, ]; }, $legacyComps, array_keys($legacyComps)); } }