- ExportItemMasterDataCommand: tenant_id=287 데이터를 JSON으로 추출 - KyungdongItemMasterSeeder: JSON 기반 DELETE+재삽입 시더 - Phase 1: item_pages/sections/fields + entity_relationships - Phase 2: categories(depth순) + items(배치500건) - Phase 3: item_details + prices - ID 매핑으로 환경별 충돌 없음, 트랜잭션 안전 - 8개 JSON 데이터 파일 포함 (총 약 1.5MB) - .gitignore에 시더 데이터 예외 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
203 lines
6.4 KiB
PHP
203 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
/**
|
|
* 경동기업(tenant_id=287) 품목 기준 데이터를 JSON으로 추출
|
|
*
|
|
* 추출 대상: item_pages, item_sections, item_fields,
|
|
* entity_relationships, categories, items, item_details, prices
|
|
*
|
|
* 사용법: php artisan kyungdong:export-item-master
|
|
*/
|
|
class ExportItemMasterDataCommand extends Command
|
|
{
|
|
protected $signature = 'kyungdong:export-item-master';
|
|
|
|
protected $description = '경동기업(tenant_id=287) 품목 기준 데이터를 JSON 파일로 추출';
|
|
|
|
private const TENANT_ID = 287;
|
|
|
|
private string $outputPath;
|
|
|
|
public function handle(): int
|
|
{
|
|
$this->outputPath = database_path('seeders/data/kyungdong');
|
|
|
|
if (! is_dir($this->outputPath)) {
|
|
mkdir($this->outputPath, 0755, true);
|
|
}
|
|
|
|
$this->info('경동기업 품목 기준 데이터 추출 시작 (tenant_id=' . self::TENANT_ID . ')');
|
|
$this->newLine();
|
|
|
|
$this->exportItemPages();
|
|
$this->exportItemSections();
|
|
$this->exportItemFields();
|
|
$this->exportEntityRelationships();
|
|
$this->exportCategories();
|
|
$this->exportItems();
|
|
$this->exportItemDetails();
|
|
$this->exportPrices();
|
|
|
|
$this->newLine();
|
|
$this->info('추출 완료! 경로: ' . $this->outputPath);
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
private function exportItemPages(): void
|
|
{
|
|
$rows = DB::table('item_pages')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('item_pages.json', $rows);
|
|
$this->info(" item_pages: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportItemSections(): void
|
|
{
|
|
$rows = DB::table('item_sections')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('item_sections.json', $rows);
|
|
$this->info(" item_sections: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportItemFields(): void
|
|
{
|
|
$rows = DB::table('item_fields')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('item_fields.json', $rows);
|
|
$this->info(" item_fields: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportEntityRelationships(): void
|
|
{
|
|
// 참조 대상이 실제 존재하는 것만 추출
|
|
$validPageIds = DB::table('item_pages')->where('tenant_id', self::TENANT_ID)->whereNull('deleted_at')->pluck('id');
|
|
$validSectionIds = DB::table('item_sections')->where('tenant_id', self::TENANT_ID)->whereNull('deleted_at')->pluck('id');
|
|
$validFieldIds = DB::table('item_fields')->where('tenant_id', self::TENANT_ID)->whereNull('deleted_at')->pluck('id');
|
|
$validBomIds = DB::table('item_bom_items')->where('tenant_id', self::TENANT_ID)->whereNull('deleted_at')->pluck('id');
|
|
|
|
$validIds = [
|
|
'page' => $validPageIds->flip(),
|
|
'section' => $validSectionIds->flip(),
|
|
'field' => $validFieldIds->flip(),
|
|
'bom' => $validBomIds->flip(),
|
|
];
|
|
|
|
$rows = DB::table('entity_relationships')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->get()
|
|
->filter(function ($row) use ($validIds) {
|
|
$parentValid = isset($validIds[$row->parent_type][$row->parent_id]);
|
|
$childValid = isset($validIds[$row->child_type][$row->child_id]);
|
|
|
|
return $parentValid && $childValid;
|
|
})
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->values()
|
|
->toArray();
|
|
|
|
$this->writeJson('entity_relationships.json', $rows);
|
|
$this->info(" entity_relationships: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportCategories(): void
|
|
{
|
|
$rows = DB::table('categories')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->orderByRaw('COALESCE(parent_id, 0), sort_order, id')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('categories.json', $rows);
|
|
$this->info(" categories: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportItems(): void
|
|
{
|
|
$rows = DB::table('items')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('items.json', $rows);
|
|
$this->info(" items: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportItemDetails(): void
|
|
{
|
|
$itemIds = DB::table('items')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->pluck('id');
|
|
|
|
$rows = DB::table('item_details')
|
|
->whereIn('item_id', $itemIds)
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('item_details.json', $rows);
|
|
$this->info(" item_details: " . count($rows) . "건");
|
|
}
|
|
|
|
private function exportPrices(): void
|
|
{
|
|
$rows = DB::table('prices')
|
|
->where('tenant_id', self::TENANT_ID)
|
|
->whereNull('deleted_at')
|
|
->orderBy('id')
|
|
->get()
|
|
->map(fn ($row) => $this->addOriginalId($row))
|
|
->toArray();
|
|
|
|
$this->writeJson('prices.json', $rows);
|
|
$this->info(" prices: " . count($rows) . "건");
|
|
}
|
|
|
|
/**
|
|
* _original_id 추가 + id 제거
|
|
*/
|
|
private function addOriginalId(object $row): array
|
|
{
|
|
$data = (array) $row;
|
|
$data['_original_id'] = $data['id'];
|
|
unset($data['id']);
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function writeJson(string $filename, array $data): void
|
|
{
|
|
$path = $this->outputPath . '/' . $filename;
|
|
file_put_contents(
|
|
$path,
|
|
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
|
);
|
|
}
|
|
}
|