Files
sam-manage/database/seeders/SampleItemsSeeder.php
kent 301f2da23e feat(MNG): Design 자동 견적 샘플 품목 Seeder 추가
- SampleItemsSeeder: Design sampleQuoteData_Complete.ts와 동일한 데이터 구조
- 원자재 (RM) 20종, 부자재 (SM) 25종
- 스크린 반제품 (SF-SCR) 20종
- 철재/절곡 반제품 (SF-STL/BND) 20종
- 완제품 (FG) 14종 (스크린 5 + 철재 5 + 절곡 4)
- 총 99개 샘플 품목 생성

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 22:58:51 +09:00

485 lines
28 KiB
PHP

<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
/**
* Design 자동 견적 산출 샘플 데이터 Seeder
*
* Design의 sampleQuoteData_Complete.ts와 동일한 데이터 구조
* - 원자재 (RM): 20종
* - 부자재 (SM): 25종
* - 스크린 반제품 (SF): 20종
* - 철재/절곡 반제품 (SF): 20종
* - 완제품 (FG): 14종 (스크린 5 + 철재 5 + 절곡 4)
* 총 99개 품목
*/
class SampleItemsSeeder extends Seeder
{
public function run(): void
{
$tenantId = $this->command->ask('테넌트 ID를 입력하세요', 1);
// 기존 샘플 데이터 삭제 (코드 패턴으로 식별)
$this->cleanExistingSampleData($tenantId);
$this->command->info('샘플 데이터 생성 시작...');
// 1단계: 원자재 (RM)
$this->seedRawMaterials($tenantId);
$this->command->info(' ✅ 원자재 (RM) 20종 생성');
// 2단계: 부자재 (SM)
$this->seedSubMaterials($tenantId);
$this->command->info(' ✅ 부자재 (SM) 25종 생성');
// 3단계: 스크린 반제품 (SF-SCR)
$this->seedScreenSemiProducts($tenantId);
$this->command->info(' ✅ 스크린 반제품 (SF-SCR) 20종 생성');
// 4단계: 철재/절곡 반제품 (SF-STL/BND)
$this->seedSteelSemiProducts($tenantId);
$this->command->info(' ✅ 철재/절곡 반제품 (SF-STL/BND) 20종 생성');
// 5단계: 완제품 (FG)
$this->seedFinishedGoods($tenantId);
$this->command->info(' ✅ 완제품 (FG) 14종 생성');
$this->command->info('');
$this->command->info('🎉 총 99개 샘플 품목 생성 완료!');
}
private function cleanExistingSampleData(int $tenantId): void
{
$patterns = ['RM-%', 'SM-%', 'SF-SCR-%', 'SF-STL-%', 'SF-BND-%', 'FG-SCR-%', 'FG-STL-%', 'FG-BND-%'];
foreach ($patterns as $pattern) {
DB::table('items')
->where('tenant_id', $tenantId)
->where('code', 'like', $pattern)
->delete();
}
}
private function seedRawMaterials(int $tenantId): void
{
$materials = [
['code' => 'RM-S001', 'name' => '강판 1.2T', 'unit' => 'KG', 'price' => 3500],
['code' => 'RM-S002', 'name' => '강판 1.6T', 'unit' => 'KG', 'price' => 3800],
['code' => 'RM-S003', 'name' => '강판 2.0T', 'unit' => 'KG', 'price' => 4200],
['code' => 'RM-S004', 'name' => '강판 2.3T', 'unit' => 'KG', 'price' => 4500],
['code' => 'RM-A001', 'name' => '알루미늄 프로파일', 'unit' => 'M', 'price' => 15000],
['code' => 'RM-A002', 'name' => '알루미늄 판재 2.0T', 'unit' => 'KG', 'price' => 8500],
['code' => 'RM-P001', 'name' => '파우더 도료 (흰색)', 'unit' => 'KG', 'price' => 12000],
['code' => 'RM-P002', 'name' => '파우더 도료 (검정)', 'unit' => 'KG', 'price' => 12000],
['code' => 'RM-P003', 'name' => '파우더 도료 (회색)', 'unit' => 'KG', 'price' => 12000],
['code' => 'RM-F001', 'name' => '방화원단 A급', 'unit' => 'M2', 'price' => 28000],
['code' => 'RM-F002', 'name' => '방화원단 B급', 'unit' => 'M2', 'price' => 22000],
['code' => 'RM-R001', 'name' => '고무 패킹 3mm', 'unit' => 'M', 'price' => 3500],
['code' => 'RM-R002', 'name' => '고무 패킹 5mm', 'unit' => 'M', 'price' => 4200],
['code' => 'RM-W001', 'name' => '목재 (집성목)', 'unit' => 'M', 'price' => 25000],
['code' => 'RM-G001', 'name' => '유리섬유', 'unit' => 'KG', 'price' => 15000],
['code' => 'RM-I001', 'name' => '단열재 50mm', 'unit' => 'M2', 'price' => 12000],
['code' => 'RM-I002', 'name' => '단열재 100mm', 'unit' => 'M2', 'price' => 18000],
['code' => 'RM-C001', 'name' => '케이블 피복재', 'unit' => 'M', 'price' => 2800],
['code' => 'RM-ST001', 'name' => 'STS304 판재', 'unit' => 'KG', 'price' => 9500],
['code' => 'RM-Z001', 'name' => '아연도금강판', 'unit' => 'KG', 'price' => 4800],
];
foreach ($materials as $mat) {
$this->insertItem($tenantId, 'RM', $mat, '원자재');
}
}
private function seedSubMaterials(int $tenantId): void
{
$materials = [
['code' => 'SM-B001', 'name' => '볼트 M8x30', 'unit' => 'EA', 'price' => 150],
['code' => 'SM-B002', 'name' => '볼트 M10x40', 'unit' => 'EA', 'price' => 200],
['code' => 'SM-B003', 'name' => '볼트 M12x50', 'unit' => 'EA', 'price' => 280],
['code' => 'SM-N001', 'name' => '너트 M8', 'unit' => 'EA', 'price' => 80],
['code' => 'SM-N002', 'name' => '너트 M10', 'unit' => 'EA', 'price' => 100],
['code' => 'SM-N003', 'name' => '너트 M12', 'unit' => 'EA', 'price' => 120],
['code' => 'SM-W001', 'name' => '와셔 M8', 'unit' => 'EA', 'price' => 50],
['code' => 'SM-W002', 'name' => '와셔 M10', 'unit' => 'EA', 'price' => 60],
['code' => 'SM-W003', 'name' => '와셔 M12', 'unit' => 'EA', 'price' => 70],
['code' => 'SM-R001', 'name' => '리벳 4x10', 'unit' => 'EA', 'price' => 40],
['code' => 'SM-R002', 'name' => '리벳 5x12', 'unit' => 'EA', 'price' => 50],
['code' => 'SM-A001', 'name' => '앵커볼트 M10', 'unit' => 'EA', 'price' => 350],
['code' => 'SM-A002', 'name' => '앵커볼트 M12', 'unit' => 'EA', 'price' => 450],
['code' => 'SM-S001', 'name' => '실리콘 (투명)', 'unit' => 'EA', 'price' => 8500],
['code' => 'SM-S002', 'name' => '실리콘 (백색)', 'unit' => 'EA', 'price' => 8500],
['code' => 'SM-T001', 'name' => '양면테이프 20mm', 'unit' => 'M', 'price' => 1200],
['code' => 'SM-C001', 'name' => '케이블타이 200mm', 'unit' => 'EA', 'price' => 100],
['code' => 'SM-P001', 'name' => '보호필름', 'unit' => 'M2', 'price' => 2500],
['code' => 'SM-G001', 'name' => '그리스', 'unit' => 'EA', 'price' => 12000],
['code' => 'SM-O001', 'name' => '윤활유', 'unit' => 'L', 'price' => 15000],
['code' => 'SM-E001', 'name' => '전선 2.5SQ', 'unit' => 'M', 'price' => 1800],
['code' => 'SM-E002', 'name' => '전선 4.0SQ', 'unit' => 'M', 'price' => 2500],
['code' => 'SM-L001', 'name' => 'LED 표시등', 'unit' => 'EA', 'price' => 5500],
['code' => 'SM-WD001', 'name' => '용접봉 3.2mm', 'unit' => 'KG', 'price' => 8500],
['code' => 'SM-SP001', 'name' => '스프링와셔 M10', 'unit' => 'EA', 'price' => 90],
];
foreach ($materials as $mat) {
$this->insertItem($tenantId, 'SM', $mat, '공용 부자재');
}
}
private function seedScreenSemiProducts(int $tenantId): void
{
$products = [
['code' => 'SF-SCR-F01', 'name' => '스크린 원단', 'unit' => 'M2', 'price' => 35000, 'bom' => [
['code' => 'RM-F001', 'qty' => 1.1, 'note' => 'LOSS 10%'],
['code' => 'SM-T001', 'qty' => 2, 'note' => '가공용'],
]],
['code' => 'SF-SCR-F02', 'name' => '가이드레일 (좌)', 'unit' => 'M', 'price' => 42000, 'bom' => [
['code' => 'RM-A001', 'qty' => 1.05, 'note' => 'LOSS 5%'],
['code' => 'RM-P001', 'qty' => 0.15, 'note' => '표면처리'],
['code' => 'RM-R001', 'qty' => 1, 'note' => ''],
]],
['code' => 'SF-SCR-F03', 'name' => '가이드레일 (우)', 'unit' => 'M', 'price' => 42000, 'bom' => [
['code' => 'RM-A001', 'qty' => 1.05, 'note' => 'LOSS 5%'],
['code' => 'RM-P001', 'qty' => 0.15, 'note' => '표면처리'],
['code' => 'RM-R001', 'qty' => 1, 'note' => ''],
]],
['code' => 'SF-SCR-F04', 'name' => '상부 케이스', 'unit' => 'EA', 'price' => 145000, 'bom' => [
['code' => 'RM-S002', 'qty' => 12, 'note' => ''],
['code' => 'RM-P002', 'qty' => 0.8, 'note' => '표면처리'],
['code' => 'SM-B002', 'qty' => 8, 'note' => '조립용'],
['code' => 'SM-N002', 'qty' => 8, 'note' => ''],
]],
['code' => 'SF-SCR-F05', 'name' => '하부 바텀바', 'unit' => 'EA', 'price' => 55000, 'bom' => [
['code' => 'RM-A002', 'qty' => 3, 'note' => ''],
['code' => 'RM-R002', 'qty' => 1, 'note' => '하부 실링'],
['code' => 'SM-WD001', 'qty' => 0.2, 'note' => '용접'],
]],
['code' => 'SF-SCR-M01', 'name' => '모터 (0.75KW)', 'unit' => 'EA', 'price' => 350000],
['code' => 'SF-SCR-M02', 'name' => '모터 (1.5KW)', 'unit' => 'EA', 'price' => 480000],
['code' => 'SF-SCR-M03', 'name' => '모터 (2.2KW)', 'unit' => 'EA', 'price' => 620000],
['code' => 'SF-SCR-M04', 'name' => '모터 (3.7KW)', 'unit' => 'EA', 'price' => 850000],
['code' => 'SF-SCR-C01', 'name' => '제어반 (표준)', 'unit' => 'EA', 'price' => 280000],
['code' => 'SF-SCR-C02', 'name' => '제어반 (고급)', 'unit' => 'EA', 'price' => 450000],
['code' => 'SF-SCR-S01', 'name' => '감지기 세트', 'unit' => 'SET', 'price' => 180000],
['code' => 'SF-SCR-W01', 'name' => '권취축', 'unit' => 'EA', 'price' => 125000, 'bom' => [
['code' => 'RM-S003', 'qty' => 15, 'note' => '롤 제작'],
['code' => 'SM-G001', 'qty' => 0.3, 'note' => '윤활'],
]],
['code' => 'SF-SCR-B01', 'name' => '브라켓 세트', 'unit' => 'SET', 'price' => 78000, 'bom' => [
['code' => 'RM-S002', 'qty' => 5, 'note' => ''],
['code' => 'SM-B002', 'qty' => 6, 'note' => ''],
['code' => 'SM-N002', 'qty' => 6, 'note' => ''],
]],
['code' => 'SF-SCR-E01', 'name' => '엣지윙 (좌)', 'unit' => 'M', 'price' => 15000, 'bom' => [
['code' => 'RM-A001', 'qty' => 1.03, 'note' => 'LOSS 3%'],
]],
['code' => 'SF-SCR-E02', 'name' => '엣지윙 (우)', 'unit' => 'M', 'price' => 15000, 'bom' => [
['code' => 'RM-A001', 'qty' => 1.03, 'note' => 'LOSS 3%'],
]],
['code' => 'SF-SCR-SP01', 'name' => '스프링 세트', 'unit' => 'SET', 'price' => 45000],
['code' => 'SF-SCR-CH01', 'name' => '체인 세트', 'unit' => 'SET', 'price' => 65000],
['code' => 'SF-SCR-REM01', 'name' => '리모컨', 'unit' => 'EA', 'price' => 85000],
['code' => 'SF-SCR-SW01', 'name' => '스위치 BOX', 'unit' => 'EA', 'price' => 45000, 'bom' => [
['code' => 'RM-S001', 'qty' => 2, 'note' => ''],
['code' => 'SM-E001', 'qty' => 3, 'note' => ''],
['code' => 'SM-L001', 'qty' => 2, 'note' => ''],
]],
];
foreach ($products as $prod) {
$bom = isset($prod['bom']) ? $this->buildBomJson($tenantId, $prod['bom']) : null;
$this->insertItem($tenantId, 'SF', $prod, '스크린용 반제품', 'SCREEN', $bom);
}
}
private function seedSteelSemiProducts(int $tenantId): void
{
$products = [
['code' => 'SF-STL-D01', 'name' => '철재 도어', 'unit' => 'EA', 'price' => 320000, 'bom' => [
['code' => 'RM-S003', 'qty' => 45, 'note' => '도어 본체'],
['code' => 'RM-I002', 'qty' => 2, 'note' => '충진재'],
['code' => 'RM-P001', 'qty' => 1.5, 'note' => '표면처리'],
['code' => 'SM-WD001', 'qty' => 1, 'note' => '용접'],
]],
['code' => 'SF-STL-F01', 'name' => '철재 프레임', 'unit' => 'M', 'price' => 58000, 'bom' => [
['code' => 'RM-S002', 'qty' => 8, 'note' => '프레임'],
['code' => 'SM-WD001', 'qty' => 0.3, 'note' => '용접'],
['code' => 'RM-P002', 'qty' => 0.5, 'note' => '표면처리'],
]],
['code' => 'SF-STL-P01', 'name' => '철재 패널', 'unit' => 'M2', 'price' => 68000, 'bom' => [
['code' => 'RM-S002', 'qty' => 15, 'note' => '패널'],
['code' => 'RM-I001', 'qty' => 1, 'note' => '단열'],
['code' => 'RM-P003', 'qty' => 0.8, 'note' => '표면처리'],
]],
['code' => 'SF-STL-H01', 'name' => '경첩 세트 (표준)', 'unit' => 'SET', 'price' => 42000],
['code' => 'SF-STL-H02', 'name' => '경첩 세트 (중형)', 'unit' => 'SET', 'price' => 58000],
['code' => 'SF-STL-L01', 'name' => '도어락 (기계식)', 'unit' => 'EA', 'price' => 95000],
['code' => 'SF-STL-L02', 'name' => '도어락 (전자식)', 'unit' => 'EA', 'price' => 380000],
['code' => 'SF-STL-C01', 'name' => '도어클로저', 'unit' => 'EA', 'price' => 115000],
['code' => 'SF-STL-S01', 'name' => '실링재', 'unit' => 'M', 'price' => 9500],
['code' => 'SF-STL-G01', 'name' => '유리 (방화)', 'unit' => 'M2', 'price' => 220000],
['code' => 'SF-STL-T01', 'name' => '문턱', 'unit' => 'EA', 'price' => 58000, 'bom' => [
['code' => 'RM-A002', 'qty' => 3, 'note' => ''],
['code' => 'RM-R001', 'qty' => 0.5, 'note' => '실링'],
]],
['code' => 'SF-STL-V01', 'name' => '환기구', 'unit' => 'EA', 'price' => 75000],
['code' => 'SF-STL-K01', 'name' => '킥플레이트', 'unit' => 'EA', 'price' => 45000, 'bom' => [
['code' => 'RM-ST001', 'qty' => 2, 'note' => '스테인리스'],
['code' => 'SM-R001', 'qty' => 12, 'note' => '고정용'],
]],
['code' => 'SF-STL-W01', 'name' => '창틀', 'unit' => 'M', 'price' => 35000, 'bom' => [
['code' => 'RM-A001', 'qty' => 1.05, 'note' => 'LOSS 5%'],
['code' => 'RM-R001', 'qty' => 1, 'note' => '실링'],
]],
['code' => 'SF-STL-B01', 'name' => '볼트/너트 세트', 'unit' => 'SET', 'price' => 18000],
['code' => 'SF-STL-P02', 'name' => '파우더 도장', 'unit' => 'M2', 'price' => 32000, 'bom' => [
['code' => 'RM-P001', 'qty' => 0.5, 'note' => '도장'],
]],
['code' => 'SF-BND-L01', 'name' => '절곡 L형 브라켓', 'unit' => 'EA', 'price' => 28000, 'spec' => '절곡가공 L형 (90도 절곡)', 'bom' => [
['code' => 'RM-S002', 'qty' => 2.5, 'note' => '절곡가공'],
['code' => 'RM-P002', 'qty' => 0.2, 'note' => '표면처리'],
['code' => 'SM-B002', 'qty' => 4, 'note' => '고정용'],
]],
['code' => 'SF-BND-U01', 'name' => '절곡 U형 채널', 'unit' => 'M', 'price' => 42000, 'spec' => '절곡가공 U형 (2회 절곡)', 'bom' => [
['code' => 'RM-S003', 'qty' => 4, 'note' => '절곡가공'],
['code' => 'RM-Z001', 'qty' => 0.5, 'note' => '보강'],
['code' => 'SM-WD001', 'qty' => 0.1, 'note' => '용접'],
]],
['code' => 'SF-BND-Z01', 'name' => '절곡 Z형 앵글', 'unit' => 'M', 'price' => 38000, 'spec' => '절곡가공 Z형 (2회 절곡, S자 형태)', 'bom' => [
['code' => 'RM-S002', 'qty' => 3.2, 'note' => '절곡가공'],
['code' => 'RM-P003', 'qty' => 0.25, 'note' => '표면처리'],
]],
['code' => 'SF-BND-C01', 'name' => '절곡 ㄷ형 보강재', 'unit' => 'M', 'price' => 35000, 'spec' => '절곡가공 ㄷ형 (2회 절곡, 보강용)', 'bom' => [
['code' => 'RM-S004', 'qty' => 3.8, 'note' => '절곡가공'],
['code' => 'RM-P001', 'qty' => 0.3, 'note' => '표면처리'],
['code' => 'SM-B003', 'qty' => 6, 'note' => '고정용'],
]],
];
foreach ($products as $prod) {
$bom = isset($prod['bom']) ? $this->buildBomJson($tenantId, $prod['bom']) : null;
$spec = $prod['spec'] ?? (str_contains($prod['code'], 'BND') ? '절곡 반제품' : '철재용 반제품');
$category = str_contains($prod['code'], 'BND') ? 'BENDING' : 'STEEL';
$this->insertItem($tenantId, 'SF', $prod, $spec, $category, $bom);
}
}
private function seedFinishedGoods(int $tenantId): void
{
// 스크린 5종 - 반제품 BOM 포함
$screenProducts = [
['code' => 'FG-SCR-001', 'name' => '방화 스크린 셔터 (소형)', 'spec' => '1000W x 2000H', 'price' => 1000000, 'bom' => [
['code' => 'SF-SCR-S01', 'qty' => 1, 'note' => '스크린 원단 (소형)'],
['code' => 'SF-SCR-M01', 'qty' => 1, 'note' => '모터 1KW'],
['code' => 'SF-SCR-C01', 'qty' => 1, 'note' => '제어반'],
['code' => 'SF-SCR-W01', 'qty' => 1, 'note' => '권취축'],
['code' => 'SF-SCR-B01', 'qty' => 1, 'note' => '브라켓'],
['code' => 'SF-SCR-S01', 'qty' => 1, 'note' => '감지기'],
]],
['code' => 'FG-SCR-002', 'name' => '방화 스크린 셔터 (중형)', 'spec' => '2000W x 3000H', 'price' => 1500000, 'bom' => [
['code' => 'SF-SCR-S02', 'qty' => 1, 'note' => '스크린 원단 (중형)'],
['code' => 'SF-SCR-M02', 'qty' => 1, 'note' => '모터 1.5KW'],
['code' => 'SF-SCR-C01', 'qty' => 1, 'note' => '제어반'],
['code' => 'SF-SCR-W01', 'qty' => 1.5, 'note' => '권취축'],
['code' => 'SF-SCR-B01', 'qty' => 2, 'note' => '브라켓'],
['code' => 'SF-SCR-S01', 'qty' => 1, 'note' => '감지기'],
['code' => 'SF-SCR-E01', 'qty' => 3, 'note' => '엣지윙 좌'],
['code' => 'SF-SCR-E02', 'qty' => 3, 'note' => '엣지윙 우'],
]],
['code' => 'FG-SCR-003', 'name' => '방화 스크린 셔터 (대형)', 'spec' => '3000W x 4000H', 'price' => 2200000, 'bom' => [
['code' => 'SF-SCR-S03', 'qty' => 1, 'note' => '스크린 원단 (대형)'],
['code' => 'SF-SCR-M03', 'qty' => 1, 'note' => '모터 2.2KW'],
['code' => 'SF-SCR-C02', 'qty' => 1, 'note' => '제어반 고급'],
['code' => 'SF-SCR-W01', 'qty' => 2, 'note' => '권취축'],
['code' => 'SF-SCR-B01', 'qty' => 3, 'note' => '브라켓'],
['code' => 'SF-SCR-S01', 'qty' => 2, 'note' => '감지기'],
['code' => 'SF-SCR-E01', 'qty' => 4, 'note' => '엣지윙 좌'],
['code' => 'SF-SCR-E02', 'qty' => 4, 'note' => '엣지윙 우'],
['code' => 'SF-SCR-SP01', 'qty' => 1, 'note' => '스프링'],
]],
['code' => 'FG-SCR-004', 'name' => '방화 스크린 셔터 (특대)', 'spec' => '4000W x 5000H', 'price' => 3500000, 'bom' => [
['code' => 'SF-SCR-S04', 'qty' => 1, 'note' => '스크린 원단 (특대)'],
['code' => 'SF-SCR-M04', 'qty' => 1, 'note' => '모터 3.7KW'],
['code' => 'SF-SCR-C02', 'qty' => 1, 'note' => '제어반 고급'],
['code' => 'SF-SCR-W01', 'qty' => 3, 'note' => '권취축'],
['code' => 'SF-SCR-B01', 'qty' => 4, 'note' => '브라켓'],
['code' => 'SF-SCR-S01', 'qty' => 3, 'note' => '감지기'],
['code' => 'SF-SCR-E01', 'qty' => 5, 'note' => '엣지윙 좌'],
['code' => 'SF-SCR-E02', 'qty' => 5, 'note' => '엣지윙 우'],
['code' => 'SF-SCR-SP01', 'qty' => 2, 'note' => '스프링'],
['code' => 'SF-SCR-CH01', 'qty' => 1, 'note' => '체인'],
]],
['code' => 'FG-SCR-005', 'name' => '방화 스크린 셔터 (맞춤형)', 'spec' => '2500W x 3500H', 'price' => 2000000, 'bom' => [
['code' => 'SF-SCR-S03', 'qty' => 1, 'note' => '스크린 원단'],
['code' => 'SF-SCR-M03', 'qty' => 1, 'note' => '모터'],
['code' => 'SF-SCR-C02', 'qty' => 1, 'note' => '제어반'],
['code' => 'SF-SCR-W01', 'qty' => 2, 'note' => '권취축'],
['code' => 'SF-SCR-B01', 'qty' => 2, 'note' => '브라켓'],
['code' => 'SF-SCR-S01', 'qty' => 2, 'note' => '감지기'],
['code' => 'SF-SCR-REM01', 'qty' => 1, 'note' => '리모컨'],
['code' => 'SF-SCR-SW01', 'qty' => 1, 'note' => '스위치'],
]],
];
foreach ($screenProducts as $prod) {
$bom = isset($prod['bom']) ? $this->buildBomJson($tenantId, $prod['bom']) : null;
$this->insertItem($tenantId, 'FG', [
'code' => $prod['code'],
'name' => $prod['name'],
'unit' => 'EA',
'price' => $prod['price'],
], $prod['spec'], 'SCREEN', $bom);
}
// 철재 5종 - 반제품 BOM 포함
$steelProducts = [
['code' => 'FG-STL-001', 'name' => '철재 방화문 (소형)', 'spec' => '900W x 2100H', 'price' => 900000, 'bom' => [
['code' => 'SF-STL-D01', 'qty' => 1, 'note' => '철재 도어'],
['code' => 'SF-STL-F01', 'qty' => 5.4, 'note' => '프레임 (둘레)'],
['code' => 'SF-STL-H01', 'qty' => 1, 'note' => '경첩'],
['code' => 'SF-STL-L01', 'qty' => 1, 'note' => '도어락'],
['code' => 'SF-STL-S01', 'qty' => 5.4, 'note' => '실링재'],
]],
['code' => 'FG-STL-002', 'name' => '철재 방화문 (중형)', 'spec' => '1800W x 2400H', 'price' => 1400000, 'bom' => [
['code' => 'SF-STL-D01', 'qty' => 2, 'note' => '철재 도어 (양쪽)'],
['code' => 'SF-STL-F01', 'qty' => 8.4, 'note' => '프레임 (둘레)'],
['code' => 'SF-STL-P01', 'qty' => 4.32, 'note' => '패널'],
['code' => 'SF-STL-H02', 'qty' => 2, 'note' => '경첩 (중형)'],
['code' => 'SF-STL-L02', 'qty' => 1, 'note' => '전자 도어락'],
['code' => 'SF-STL-C01', 'qty' => 1, 'note' => '도어클로저'],
['code' => 'SF-STL-S01', 'qty' => 8.4, 'note' => '실링재'],
]],
['code' => 'FG-STL-003', 'name' => '철재 방화문 (대형)', 'spec' => '2400W x 3000H', 'price' => 2200000, 'bom' => [
['code' => 'SF-STL-D01', 'qty' => 2, 'note' => '철재 도어'],
['code' => 'SF-STL-F01', 'qty' => 10.8, 'note' => '프레임'],
['code' => 'SF-STL-P01', 'qty' => 7.2, 'note' => '패널'],
['code' => 'SF-STL-H02', 'qty' => 3, 'note' => '경첩'],
['code' => 'SF-STL-L02', 'qty' => 1, 'note' => '도어락'],
['code' => 'SF-STL-C01', 'qty' => 2, 'note' => '도어클로저'],
['code' => 'SF-STL-S01', 'qty' => 10.8, 'note' => '실링재'],
['code' => 'SF-STL-G01', 'qty' => 0.5, 'note' => '방화유리'],
]],
['code' => 'FG-STL-004', 'name' => '철재 방화문 (양개)', 'spec' => '1800W x 2400H', 'price' => 1600000, 'bom' => [
['code' => 'SF-STL-D01', 'qty' => 2, 'note' => '철재 도어 (양개)'],
['code' => 'SF-STL-F01', 'qty' => 8.4, 'note' => '프레임'],
['code' => 'SF-STL-H02', 'qty' => 4, 'note' => '경첩'],
['code' => 'SF-STL-L02', 'qty' => 2, 'note' => '도어락'],
['code' => 'SF-STL-C01', 'qty' => 2, 'note' => '도어클로저'],
['code' => 'SF-STL-S01', 'qty' => 8.4, 'note' => '실링재'],
['code' => 'SF-STL-T01', 'qty' => 1, 'note' => '문턱'],
]],
['code' => 'FG-STL-005', 'name' => '철재 방화문 (특수)', 'spec' => '2000W x 2600H', 'price' => 1800000, 'bom' => [
['code' => 'SF-STL-D01', 'qty' => 1, 'note' => '철재 도어'],
['code' => 'SF-STL-F01', 'qty' => 9.2, 'note' => '프레임'],
['code' => 'SF-STL-P01', 'qty' => 5.2, 'note' => '패널'],
['code' => 'SF-STL-H02', 'qty' => 2, 'note' => '경첩'],
['code' => 'SF-STL-L02', 'qty' => 1, 'note' => '도어락'],
['code' => 'SF-STL-C01', 'qty' => 1, 'note' => '도어클로저'],
['code' => 'SF-STL-G01', 'qty' => 1, 'note' => '방화유리'],
['code' => 'SF-STL-V01', 'qty' => 1, 'note' => '환기구'],
['code' => 'SF-STL-K01', 'qty' => 1, 'note' => '킥플레이트'],
]],
];
foreach ($steelProducts as $prod) {
$bom = isset($prod['bom']) ? $this->buildBomJson($tenantId, $prod['bom']) : null;
$this->insertItem($tenantId, 'FG', [
'code' => $prod['code'],
'name' => $prod['name'],
'unit' => 'EA',
'price' => $prod['price'],
], $prod['spec'], 'STEEL', $bom);
}
// 절곡 4종 - 반제품 BOM 포함
$bendingProducts = [
['code' => 'FG-BND-001', 'name' => '절곡 철재 프레임 (L형)', 'spec' => '1200W x 2400H (절곡가공)', 'price' => 500000, 'bom' => [
['code' => 'SF-BND-L01', 'qty' => 8, 'note' => 'L형 브라켓'],
['code' => 'SF-STL-F01', 'qty' => 7.2, 'note' => '프레임'],
['code' => 'SF-STL-P02', 'qty' => 2.88, 'note' => '도장'],
['code' => 'SF-STL-B01', 'qty' => 2, 'note' => '볼트/너트'],
]],
['code' => 'FG-BND-002', 'name' => '절곡 철재 패널 (U형)', 'spec' => '1500W x 2000H (절곡가공)', 'price' => 650000, 'bom' => [
['code' => 'SF-BND-U01', 'qty' => 7, 'note' => 'U형 채널'],
['code' => 'SF-STL-P01', 'qty' => 3, 'note' => '패널'],
['code' => 'SF-STL-P02', 'qty' => 3, 'note' => '도장'],
['code' => 'SF-STL-B01', 'qty' => 3, 'note' => '볼트/너트'],
]],
['code' => 'FG-BND-003', 'name' => '절곡 철재 커버 (Z형)', 'spec' => '1000W x 1500H (절곡가공)', 'price' => 400000, 'bom' => [
['code' => 'SF-BND-Z01', 'qty' => 5, 'note' => 'Z형 앵글'],
['code' => 'SF-STL-P01', 'qty' => 1.5, 'note' => '패널'],
['code' => 'SF-STL-P02', 'qty' => 1.5, 'note' => '도장'],
]],
['code' => 'FG-BND-004', 'name' => '절곡 철재 보강재 (ㄷ형)', 'spec' => '800W x 1200H (절곡가공)', 'price' => 350000, 'bom' => [
['code' => 'SF-BND-C01', 'qty' => 4, 'note' => 'ㄷ형 보강재'],
['code' => 'SF-STL-F01', 'qty' => 4, 'note' => '프레임'],
['code' => 'SF-STL-B01', 'qty' => 2, 'note' => '볼트/너트'],
]],
];
foreach ($bendingProducts as $prod) {
$bom = isset($prod['bom']) ? $this->buildBomJson($tenantId, $prod['bom']) : null;
$this->insertItem($tenantId, 'FG', [
'code' => $prod['code'],
'name' => $prod['name'],
'unit' => 'EA',
'price' => $prod['price'],
], $prod['spec'], 'BENDING', $bom);
}
}
private function insertItem(
int $tenantId,
string $itemType,
array $data,
string $description = '',
?string $category = null,
?string $bomJson = null
): void {
$now = now();
DB::table('items')->insert([
'tenant_id' => $tenantId,
'item_type' => $itemType,
'code' => $data['code'],
'name' => $data['name'],
'unit' => $data['unit'] ?? 'EA',
'description' => $description,
'bom' => $bomJson,
'attributes' => json_encode([
'sales_price' => $data['price'] ?? 0,
'purchase_price' => round(($data['price'] ?? 0) * 0.7),
'item_category' => $category,
]),
'is_active' => true,
'created_at' => $now,
'updated_at' => $now,
]);
}
private function buildBomJson(int $tenantId, array $bomItems): string
{
$result = [];
foreach ($bomItems as $item) {
// 자식 품목 ID 조회
$childItem = DB::table('items')
->where('tenant_id', $tenantId)
->where('code', $item['code'])
->first();
if ($childItem) {
$result[] = [
'child_item_id' => $childItem->id,
'child_item_code' => $item['code'],
'quantity' => $item['qty'],
'note' => $item['note'] ?? '',
];
}
}
return json_encode($result);
}
}