Files
sam-api/database/seeders/Dummy/DummyItemSeeder.php
kent be90c351fa chore(API): Seeder 파일 정리
- Dummy Seeder 파일들 정리 및 개선
- ApprovalTestDataSeeder 수정
- PositionSeeder, StockReceivingSeeder 수정

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-13 19:49:28 +09:00

160 lines
5.7 KiB
PHP

<?php
namespace Database\Seeders\Dummy;
use App\Models\Items\Item;
use Database\Seeders\DummyDataSeeder;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class DummyItemSeeder extends Seeder
{
/**
* 타입별 생성 수량
*/
private const TYPE_COUNTS = [
'FG' => 2000, // 완제품
'PT' => 3000, // 부품
'SM' => 2000, // 부자재
'RM' => 2000, // 원자재
'CS' => 1000, // 소모품
];
/**
* 타입별 코드 접두사
*/
private const TYPE_PREFIXES = [
'FG' => 'FG',
'PT' => 'PT',
'SM' => 'SM',
'RM' => 'RM',
'CS' => 'CS',
];
/**
* 타입별 품목명 패턴
*/
private const TYPE_NAMES = [
'FG' => ['스크린', '블라인드', '커튼', '차양막', '롤스크린', '버티칼', '우드블라인드', '허니콤', '듀오롤', '콤비블라인드'],
'PT' => ['모터', '브라켓', '가이드레일', '샤프트', '베어링', '기어박스', '풀리', '벨트', '스프링', '힌지'],
'SM' => ['나사', '볼트', '너트', '와셔', '리벳', '클립', '고정핀', '스토퍼', '캡', '부싱'],
'RM' => ['알루미늄', '스틸', 'PVC', '폴리에스터', '면', '폴리카보네이트', 'ABS', '나일론', '실리콘', '고무'],
'CS' => ['포장재', '라벨', '테이프', '박스', '비닐', '완충재', '스티커', '인쇄물', '매뉴얼', '보증서'],
];
/**
* 단위 목록
*/
private const UNITS = ['EA', 'SET', 'M', 'MM', 'KG', 'G', 'L', 'ML', 'BOX', 'ROLL'];
/**
* 색상 목록
*/
private const COLORS = ['화이트', '아이보리', '베이지', '그레이', '블랙', '브라운', '네이비', '카키', '버건디', '실버'];
/**
* 규격 목록
*/
private const SPECS = ['소형', '중형', '대형', '특대형', 'A타입', 'B타입', 'C타입', '표준', '고급', '프리미엄'];
public function run(): void
{
$tenantId = DummyDataSeeder::TENANT_ID;
$userId = DummyDataSeeder::USER_ID;
// 기존 데이터 확인
$existing = Item::where('tenant_id', $tenantId)->count();
if ($existing >= 10000) {
$this->command->info(' ⚠ items: 이미 '.$existing.'개 존재 (스킵)');
return;
}
$this->command->info(' 🔄 items: 10,000개 생성 중...');
$totalCount = 0;
$now = now();
foreach (self::TYPE_COUNTS as $type => $count) {
$prefix = self::TYPE_PREFIXES[$type];
$names = self::TYPE_NAMES[$type];
$items = [];
for ($i = 1; $i <= $count; $i++) {
$code = sprintf('%s-%06d', $prefix, $i);
$baseName = $names[array_rand($names)];
$color = self::COLORS[array_rand(self::COLORS)];
$spec = self::SPECS[array_rand(self::SPECS)];
$name = "{$baseName} {$color} {$spec}";
$items[] = [
'tenant_id' => $tenantId,
'item_type' => $type,
'code' => $code,
'name' => $name,
'unit' => self::UNITS[array_rand(self::UNITS)],
'category_id' => null,
'bom' => null,
'attributes' => json_encode($this->generateAttributes($type)),
'attributes_archive' => null,
'options' => json_encode(['color' => $color, 'spec' => $spec]),
'description' => "{$type} 타입 품목 - {$name}",
'is_active' => rand(1, 100) <= 95, // 95% 활성
'created_by' => $userId,
'updated_by' => $userId,
'created_at' => $now,
'updated_at' => $now,
];
// 1000개씩 배치 삽입
if (count($items) >= 1000) {
DB::table('items')->insert($items);
$totalCount += count($items);
$items = [];
$this->command->info("{$totalCount}개 완료...");
}
}
// 남은 데이터 삽입
if (! empty($items)) {
DB::table('items')->insert($items);
$totalCount += count($items);
}
}
$this->command->info(' ✓ items: '.$totalCount.'건 생성 완료');
}
/**
* 타입별 속성 생성
*/
private function generateAttributes(string $type): array
{
$base = [
'weight' => rand(10, 10000) / 100, // 0.1 ~ 100 kg
'width' => rand(10, 3000), // 10 ~ 3000 mm
'height' => rand(10, 3000), // 10 ~ 3000 mm
];
return match ($type) {
'FG' => array_merge($base, [
'warranty_months' => rand(6, 36),
'lead_time_days' => rand(3, 30),
]),
'PT' => array_merge($base, [
'material' => ['알루미늄', '스틸', 'ABS', 'PVC'][array_rand(['알루미늄', '스틸', 'ABS', 'PVC'])],
'tolerance' => '±'.rand(1, 10) / 10 .'mm',
]),
'SM', 'RM' => array_merge($base, [
'min_order_qty' => rand(1, 100) * 10,
'supplier' => ['국내', '중국', '베트남', '일본'][array_rand(['국내', '중국', '베트남', '일본'])],
]),
'CS' => [
'expiry_months' => rand(6, 24),
'storage' => ['상온', '냉장', '냉동'][array_rand(['상온', '냉장', '냉동'])],
],
default => $base,
};
}
}