[fix] 미정의 변수 사용 수식 12개 비활성화
- QuoteFormulaSeeder: is_active 플래그 추가 (기본 true) - 미정의 변수 사용 수식 비활성화: - GR_QTY_WALL, GR_QTY_SIDE, GR_QTY_MIXED (BASE_QTY 미정의) - EDGE_QTY (EDGE_WING_SIZE 미정의) - PRICE_GR, PRICE_CASE, PRICE_MOTOR, PRICE_CTRL, PRICE_EDGE (QTY, UNIT_PRICE 미정의) - PRICE_INSP (INSPECTION_FEE 미정의) - PRICE_AREA_SCREEN, PRICE_AREA_STEEL (AREA, UNIT_PRICE_PER_M2 미정의)
This commit is contained in:
108
database/seeders/QuoteFormulaCategorySeeder.php
Normal file
108
database/seeders/QuoteFormulaCategorySeeder.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class QuoteFormulaCategorySeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* 견적수식 카테고리 시드 데이터
|
||||
* 출처: design/src/components/utils/formulaSampleData.ts
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$tenantId = 1; // 기본 테넌트
|
||||
|
||||
$categories = [
|
||||
[
|
||||
'code' => 'OPEN_SIZE',
|
||||
'name' => '오픈사이즈',
|
||||
'description' => '제품의 설치 오픈 사이즈 (W0, H0)',
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'code' => 'MAKE_SIZE',
|
||||
'name' => '제작사이즈',
|
||||
'description' => '실제 제작 사이즈 (W1, H1)',
|
||||
'sort_order' => 2,
|
||||
],
|
||||
[
|
||||
'code' => 'AREA',
|
||||
'name' => '면적',
|
||||
'description' => '제품 면적 계산 (㎡)',
|
||||
'sort_order' => 3,
|
||||
],
|
||||
[
|
||||
'code' => 'WEIGHT',
|
||||
'name' => '중량',
|
||||
'description' => '제품 중량 계산 (kg)',
|
||||
'sort_order' => 4,
|
||||
],
|
||||
[
|
||||
'code' => 'GUIDE_RAIL',
|
||||
'name' => '가이드레일',
|
||||
'description' => '가이드레일 자동 선택 및 수량 계산',
|
||||
'sort_order' => 5,
|
||||
],
|
||||
[
|
||||
'code' => 'CASE',
|
||||
'name' => '케이스',
|
||||
'description' => '케이스(셔터박스) 자동 선택',
|
||||
'sort_order' => 6,
|
||||
],
|
||||
[
|
||||
'code' => 'MOTOR',
|
||||
'name' => '모터',
|
||||
'description' => '개폐전동기 자동 선택',
|
||||
'sort_order' => 7,
|
||||
],
|
||||
[
|
||||
'code' => 'CONTROLLER',
|
||||
'name' => '제어기',
|
||||
'description' => '연동제어기 자동 선택',
|
||||
'sort_order' => 8,
|
||||
],
|
||||
[
|
||||
'code' => 'EDGE_WING',
|
||||
'name' => '마구리',
|
||||
'description' => '마구리 날개 수량 계산',
|
||||
'sort_order' => 9,
|
||||
],
|
||||
[
|
||||
'code' => 'INSPECTION',
|
||||
'name' => '검사',
|
||||
'description' => '제품 검사비',
|
||||
'sort_order' => 10,
|
||||
],
|
||||
[
|
||||
'code' => 'PRICE_FORMULA',
|
||||
'name' => '단가수식',
|
||||
'description' => '품목별 단가 계산 수식',
|
||||
'sort_order' => 11,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
DB::table('quote_formula_categories')->updateOrInsert(
|
||||
[
|
||||
'tenant_id' => $tenantId,
|
||||
'code' => $category['code'],
|
||||
],
|
||||
[
|
||||
'tenant_id' => $tenantId,
|
||||
'code' => $category['code'],
|
||||
'name' => $category['name'],
|
||||
'description' => $category['description'],
|
||||
'sort_order' => $category['sort_order'],
|
||||
'is_active' => true,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->command->info('QuoteFormulaCategorySeeder: 11개 카테고리 생성 완료');
|
||||
}
|
||||
}
|
||||
474
database/seeders/QuoteFormulaSeeder.php
Normal file
474
database/seeders/QuoteFormulaSeeder.php
Normal file
@@ -0,0 +1,474 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class QuoteFormulaSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* 견적수식 시드 데이터
|
||||
* 출처: design/src/components/utils/formulaSampleData.ts
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$tenantId = 1; // 기본 테넌트
|
||||
|
||||
// 카테고리 코드 → ID 매핑
|
||||
$categoryMap = DB::table('quote_formula_categories')
|
||||
->where('tenant_id', $tenantId)
|
||||
->pluck('id', 'code')
|
||||
->toArray();
|
||||
|
||||
if (empty($categoryMap)) {
|
||||
$this->command->error('QuoteFormulaSeeder: 카테고리가 없습니다. QuoteFormulaCategorySeeder를 먼저 실행하세요.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$formulas = [
|
||||
// ==============================
|
||||
// 1. 오픈사이즈 (OPEN_SIZE) - 2개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'OPEN_SIZE',
|
||||
'variable' => 'W0',
|
||||
'name' => '오픈사이즈 W0 (가로)',
|
||||
'type' => 'input',
|
||||
'formula' => null,
|
||||
'description' => '자동 견적 산출 섹션의 오픈사이즈 W0 입력값',
|
||||
'metadata' => ['unit' => 'mm'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'category_code' => 'OPEN_SIZE',
|
||||
'variable' => 'H0',
|
||||
'name' => '오픈사이즈 H0 (세로)',
|
||||
'type' => 'input',
|
||||
'formula' => null,
|
||||
'description' => '자동 견적 산출 섹션의 오픈사이즈 H0 입력값',
|
||||
'metadata' => ['unit' => 'mm'],
|
||||
'sort_order' => 2,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 2. 제작사이즈 (MAKE_SIZE) - 4개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'MAKE_SIZE',
|
||||
'variable' => 'W1_SCREEN',
|
||||
'name' => '제작사이즈 W1 (스크린)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'W0 + 140',
|
||||
'description' => '스크린 제작 가로 = 오픈 가로 + 140',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'screen'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'category_code' => 'MAKE_SIZE',
|
||||
'variable' => 'H1_SCREEN',
|
||||
'name' => '제작사이즈 H1 (스크린)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'H0 + 350',
|
||||
'description' => '스크린 제작 세로 = 오픈 세로 + 350',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'screen'],
|
||||
'sort_order' => 2,
|
||||
],
|
||||
[
|
||||
'category_code' => 'MAKE_SIZE',
|
||||
'variable' => 'W1_STEEL',
|
||||
'name' => '제작사이즈 W1 (철재)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'W0 + 110',
|
||||
'description' => '철재 제작 가로 = 오픈 가로 + 110',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'steel'],
|
||||
'sort_order' => 3,
|
||||
],
|
||||
[
|
||||
'category_code' => 'MAKE_SIZE',
|
||||
'variable' => 'H1_STEEL',
|
||||
'name' => '제작사이즈 H1 (철재)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'H0 + 350',
|
||||
'description' => '철재 제작 세로 = 오픈 세로 + 350',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'steel'],
|
||||
'sort_order' => 4,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 3. 면적 (AREA) - 1개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'AREA',
|
||||
'variable' => 'M',
|
||||
'name' => '면적 계산',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'W1 * H1 / 1000000',
|
||||
'description' => '면적(㎡) = 제작가로(W1) × 제작세로(H1) ÷ 1,000,000',
|
||||
'metadata' => ['unit' => '㎡'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 4. 중량 (WEIGHT) - 2개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'WEIGHT',
|
||||
'variable' => 'K_SCREEN',
|
||||
'name' => '중량 계산 (스크린)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'M * 2 + W0 / 1000 * 14.17',
|
||||
'description' => '스크린 중량(kg) = 면적 × 2 + (오픈가로 ÷ 1000 × 14.17)',
|
||||
'metadata' => ['unit' => 'kg', 'product_type' => 'screen'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'category_code' => 'WEIGHT',
|
||||
'variable' => 'K_STEEL',
|
||||
'name' => '중량 계산 (철재)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'M * 25',
|
||||
'description' => '철재 중량(kg) = 면적 × 25',
|
||||
'metadata' => ['unit' => 'kg', 'product_type' => 'steel'],
|
||||
'sort_order' => 2,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 5. 가이드레일 (GUIDE_RAIL) - 5개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'GUIDE_RAIL',
|
||||
'variable' => 'G',
|
||||
'name' => '가이드레일 제작길이',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'H0 + 250',
|
||||
'description' => '가이드레일 제작길이(G) = 오픈세로(H0) + 250',
|
||||
'metadata' => ['unit' => 'mm'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'category_code' => 'GUIDE_RAIL',
|
||||
'variable' => 'GR_AUTO_SELECT',
|
||||
'name' => '가이드레일 자재 자동 선택',
|
||||
'type' => 'range',
|
||||
'formula' => null,
|
||||
'description' => '가이드레일 길이 및 수량 자동 산출 (기본 2개)',
|
||||
'metadata' => ['unit' => 'EA', 'input_variable' => 'G'],
|
||||
'sort_order' => 2,
|
||||
'ranges' => [
|
||||
['min' => 1219, 'max' => 2438, 'result' => '2438 2개', 'quantity' => 2, 'description' => '1219 < G ≤ 2438'],
|
||||
['min' => 2438, 'max' => 3000, 'result' => '3000 2개', 'quantity' => 2, 'description' => '2438 < G ≤ 3000'],
|
||||
],
|
||||
],
|
||||
[
|
||||
'category_code' => 'GUIDE_RAIL',
|
||||
'variable' => 'GR_QTY_WALL',
|
||||
'name' => '가이드레일 수량 (벽면형)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'BASE_QTY',
|
||||
'description' => '벽면형: 기본 수량 그대로 (좌우 2개)',
|
||||
'metadata' => ['unit' => 'EA', 'install_type' => 'wall'],
|
||||
'sort_order' => 3,
|
||||
'is_active' => false, // 미정의 변수(BASE_QTY) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'GUIDE_RAIL',
|
||||
'variable' => 'GR_QTY_SIDE',
|
||||
'name' => '가이드레일 수량 (측면형)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'BASE_QTY / 2',
|
||||
'description' => '측면형: 기본 수량의 절반 (한쪽만)',
|
||||
'metadata' => ['unit' => 'EA', 'install_type' => 'side'],
|
||||
'sort_order' => 4,
|
||||
'is_active' => false, // 미정의 변수(BASE_QTY) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'GUIDE_RAIL',
|
||||
'variable' => 'GR_QTY_MIXED',
|
||||
'name' => '가이드레일 수량 (혼합형)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'BASE_QTY * 1.5',
|
||||
'description' => '혼합형: 기본 수량 × 1.5',
|
||||
'metadata' => ['unit' => 'EA', 'install_type' => 'mixed'],
|
||||
'sort_order' => 5,
|
||||
'is_active' => false, // 미정의 변수(BASE_QTY) 사용
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 6. 케이스 (CASE) - 3개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'CASE',
|
||||
'variable' => 'S_SCREEN',
|
||||
'name' => '케이스 사이즈 (스크린)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'W0 + 220',
|
||||
'description' => '스크린 케이스 사이즈(S) = 오픈가로(W0) + 220',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'screen'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
[
|
||||
'category_code' => 'CASE',
|
||||
'variable' => 'S_STEEL',
|
||||
'name' => '케이스 사이즈 (철재)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'W0 + 240',
|
||||
'description' => '철재 케이스 사이즈(S) = 오픈가로(W0) + 240',
|
||||
'metadata' => ['unit' => 'mm', 'product_type' => 'steel'],
|
||||
'sort_order' => 2,
|
||||
],
|
||||
[
|
||||
'category_code' => 'CASE',
|
||||
'variable' => 'CASE_AUTO_SELECT',
|
||||
'name' => '케이스 자재 자동 선택',
|
||||
'type' => 'range',
|
||||
'formula' => null,
|
||||
'description' => '케이스 자재 길이 및 수량 자동 산출',
|
||||
'metadata' => ['unit' => 'EA', 'input_variable' => 'S'],
|
||||
'sort_order' => 3,
|
||||
'ranges' => [
|
||||
['min' => 0, 'max' => 1219, 'result' => '1219 1개', 'item_code' => 'PT-CASE-1219', 'quantity' => 1, 'description' => '0 < S ≤ 1219'],
|
||||
['min' => 1219, 'max' => 2438, 'result' => '2438 1개', 'item_code' => 'PT-CASE-2438', 'quantity' => 1, 'description' => '1219 < S ≤ 2438'],
|
||||
['min' => 2438, 'max' => 3000, 'result' => '3000 1개', 'item_code' => 'PT-CASE-3000', 'quantity' => 1, 'description' => '2438 < S ≤ 3000'],
|
||||
],
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 7. 모터 (MOTOR) - 1개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'MOTOR',
|
||||
'variable' => 'MOTOR_AUTO_SELECT',
|
||||
'name' => '모터 자동 선택',
|
||||
'type' => 'range',
|
||||
'formula' => null,
|
||||
'description' => '모터 중량 기반 자동 선택 (전원 유형 반영)',
|
||||
'metadata' => ['unit' => 'EA', 'input_variable' => 'K'],
|
||||
'sort_order' => 1,
|
||||
'ranges' => [
|
||||
['min' => 0, 'max' => 150, 'result' => '150k', 'quantity' => 1, 'description' => '0 < K ≤ 150kg'],
|
||||
['min' => 150, 'max' => 300, 'result' => '300k', 'quantity' => 1, 'description' => '150 < K ≤ 300kg'],
|
||||
['min' => 300, 'max' => 400, 'result' => '400k', 'quantity' => 1, 'description' => '300 < K ≤ 400kg'],
|
||||
],
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 8. 제어기 (CONTROLLER) - 1개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'CONTROLLER',
|
||||
'variable' => 'CTRL_AUTO_SELECT',
|
||||
'name' => '제어기 자동 선택',
|
||||
'type' => 'mapping',
|
||||
'formula' => null,
|
||||
'description' => '연동제어기 설치 유형(매립/노출)에 따라 자동 선택',
|
||||
'metadata' => ['unit' => 'EA', 'input_variable' => 'CONTROLLER_TYPE'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 9. 마구리 (EDGE_WING) - 1개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'EDGE_WING',
|
||||
'variable' => 'EDGE_QTY',
|
||||
'name' => '마구리 날개 수량 계산',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'EDGE_WING_SIZE / 50',
|
||||
'description' => '마구리 날개치수 ÷ 50 = 수량',
|
||||
'metadata' => ['unit' => 'EA'],
|
||||
'sort_order' => 1,
|
||||
'is_active' => false, // 미정의 변수(EDGE_WING_SIZE) 사용
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 10. 검사 (INSPECTION) - 1개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'INSPECTION',
|
||||
'variable' => 'INSP_FEE',
|
||||
'name' => '검사비',
|
||||
'type' => 'calculation',
|
||||
'formula' => '1',
|
||||
'description' => '검사비 고정 1EA (단가는 검사비 설정값 적용)',
|
||||
'metadata' => ['unit' => 'EA'],
|
||||
'sort_order' => 1,
|
||||
],
|
||||
|
||||
// ==============================
|
||||
// 11. 단가수식 (PRICE_FORMULA) - 8개
|
||||
// ==============================
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_GR',
|
||||
'name' => '가이드레일 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'QTY * UNIT_PRICE',
|
||||
'description' => '가이드레일 총액 = 수량 × 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'guide_rail'],
|
||||
'sort_order' => 1,
|
||||
'is_active' => false, // 미정의 변수(QTY, UNIT_PRICE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_CASE',
|
||||
'name' => '케이스 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'QTY * UNIT_PRICE',
|
||||
'description' => '케이스 총액 = 수량 × 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'case'],
|
||||
'sort_order' => 2,
|
||||
'is_active' => false, // 미정의 변수(QTY, UNIT_PRICE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_MOTOR',
|
||||
'name' => '모터 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'QTY * UNIT_PRICE',
|
||||
'description' => '모터 총액 = 수량 × 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'motor'],
|
||||
'sort_order' => 3,
|
||||
'is_active' => false, // 미정의 변수(QTY, UNIT_PRICE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_CTRL',
|
||||
'name' => '제어기 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'QTY * UNIT_PRICE',
|
||||
'description' => '제어기 총액 = 수량 × 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'controller'],
|
||||
'sort_order' => 4,
|
||||
'is_active' => false, // 미정의 변수(QTY, UNIT_PRICE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_EDGE',
|
||||
'name' => '마구리 날개 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'QTY * UNIT_PRICE',
|
||||
'description' => '마구리 날개 총액 = 수량 × 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'edge_wing'],
|
||||
'sort_order' => 5,
|
||||
'is_active' => false, // 미정의 변수(QTY, UNIT_PRICE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_INSP',
|
||||
'name' => '검사비 단가 수식',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'INSPECTION_FEE',
|
||||
'description' => '검사비 = 입력한 검사비 설정값',
|
||||
'metadata' => ['unit' => '원', 'target' => 'inspection'],
|
||||
'sort_order' => 6,
|
||||
'is_active' => false, // 미정의 변수(INSPECTION_FEE) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_AREA_SCREEN',
|
||||
'name' => '면적 기반 단가 (스크린)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'AREA * UNIT_PRICE_PER_M2',
|
||||
'description' => '스크린 면적 기반 총액 = 면적(㎡) × ㎡당 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'area', 'product_type' => 'screen'],
|
||||
'sort_order' => 7,
|
||||
'is_active' => false, // 미정의 변수(AREA, UNIT_PRICE_PER_M2) 사용
|
||||
],
|
||||
[
|
||||
'category_code' => 'PRICE_FORMULA',
|
||||
'variable' => 'PRICE_AREA_STEEL',
|
||||
'name' => '면적 기반 단가 (철재)',
|
||||
'type' => 'calculation',
|
||||
'formula' => 'AREA * UNIT_PRICE_PER_M2',
|
||||
'description' => '철재 면적 기반 총액 = 면적(㎡) × ㎡당 단가',
|
||||
'metadata' => ['unit' => '원', 'target' => 'area', 'product_type' => 'steel'],
|
||||
'sort_order' => 8,
|
||||
'is_active' => false, // 미정의 변수(AREA, UNIT_PRICE_PER_M2) 사용
|
||||
],
|
||||
];
|
||||
|
||||
$formulaCount = 0;
|
||||
$rangeCount = 0;
|
||||
|
||||
foreach ($formulas as $formula) {
|
||||
$categoryId = $categoryMap[$formula['category_code']] ?? null;
|
||||
|
||||
if (! $categoryId) {
|
||||
$this->command->warn("카테고리 '{$formula['category_code']}'를 찾을 수 없습니다: {$formula['variable']}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// 수식 생성/업데이트
|
||||
DB::table('quote_formulas')->updateOrInsert(
|
||||
[
|
||||
'tenant_id' => $tenantId,
|
||||
'variable' => $formula['variable'],
|
||||
],
|
||||
[
|
||||
'tenant_id' => $tenantId,
|
||||
'category_id' => $categoryId,
|
||||
'variable' => $formula['variable'],
|
||||
'name' => $formula['name'],
|
||||
'type' => $formula['type'],
|
||||
'formula' => $formula['formula'],
|
||||
'output_type' => 'variable',
|
||||
'description' => $formula['description'],
|
||||
'sort_order' => $formula['sort_order'] ?? 0,
|
||||
'is_active' => $formula['is_active'] ?? true,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]
|
||||
);
|
||||
$formulaCount++;
|
||||
|
||||
// Range 데이터가 있으면 처리
|
||||
if (! empty($formula['ranges'])) {
|
||||
// 먼저 수식 ID 조회
|
||||
$formulaRecord = DB::table('quote_formulas')
|
||||
->where('tenant_id', $tenantId)
|
||||
->where('variable', $formula['variable'])
|
||||
->first();
|
||||
|
||||
if ($formulaRecord) {
|
||||
// 조건 변수 추출 (metadata에서)
|
||||
$conditionVariable = $formula['metadata']['input_variable'] ?? $formula['variable'];
|
||||
|
||||
foreach ($formula['ranges'] as $rangeOrder => $range) {
|
||||
// result_value에 추가 정보를 JSON으로 포함
|
||||
$resultData = [
|
||||
'value' => $range['result'],
|
||||
'item_code' => $range['item_code'] ?? null,
|
||||
'quantity' => $range['quantity'] ?? 1,
|
||||
'note' => $range['description'] ?? null,
|
||||
];
|
||||
|
||||
DB::table('quote_formula_ranges')->updateOrInsert(
|
||||
[
|
||||
'formula_id' => $formulaRecord->id,
|
||||
'min_value' => $range['min'],
|
||||
'max_value' => $range['max'],
|
||||
],
|
||||
[
|
||||
'formula_id' => $formulaRecord->id,
|
||||
'min_value' => $range['min'],
|
||||
'max_value' => $range['max'],
|
||||
'condition_variable' => $conditionVariable,
|
||||
'result_value' => json_encode($resultData),
|
||||
'result_type' => 'fixed',
|
||||
'sort_order' => $rangeOrder + 1,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]
|
||||
);
|
||||
$rangeCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->command->info("QuoteFormulaSeeder: {$formulaCount}개 수식, {$rangeCount}개 범위 데이터 생성 완료");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user