feat: [ai-quotation] 제조 견적서 마이그레이션 추가

- ai_quotations: quote_mode, quote_number, product_category 컬럼 추가
- ai_quotation_items: specification, unit, quantity, unit_price, total_price, item_category, floor_code 컬럼 추가
- ai_quote_price_tables 테이블 신규 생성
This commit is contained in:
김보곤
2026-03-03 15:57:19 +09:00
parent 5a0deddb58
commit 2fd122feba

View File

@@ -0,0 +1,79 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
// ai_quotations 테이블: 제조 견적 필드 추가
Schema::table('ai_quotations', function (Blueprint $table) {
$table->string('quote_mode', 20)->default('module')->after('tenant_id')
->comment('견적 모드: module(모듈추천), manufacture(제조견적)');
$table->string('quote_number', 50)->nullable()->after('quote_mode')
->comment('견적번호: AQ-SC-260303-01');
$table->string('product_category', 50)->nullable()->after('quote_number')
->comment('제품 카테고리: SCREEN, STEEL');
$table->index('quote_mode');
$table->index('quote_number');
});
// ai_quotation_items 테이블: 제조 견적 품목 필드 추가
Schema::table('ai_quotation_items', function (Blueprint $table) {
$table->string('specification', 200)->nullable()->after('module_name')
->comment('규격: 3000×2500');
$table->string('unit', 20)->nullable()->after('specification')
->comment('단위: SET, EA, ㎡');
$table->decimal('quantity', 10, 2)->default(1)->after('unit')
->comment('수량');
$table->decimal('unit_price', 15, 2)->default(0)->after('quantity')
->comment('단가');
$table->decimal('total_price', 15, 2)->default(0)->after('unit_price')
->comment('금액 (수량×단가)');
$table->string('item_category', 50)->nullable()->after('total_price')
->comment('품목 분류: material, labor, install, etc.');
$table->string('floor_code', 50)->nullable()->after('item_category')
->comment('위치 코드: B1-A01, 1F-C01');
});
// ai_quote_price_tables: AI 견적용 단가표 (신규)
Schema::create('ai_quote_price_tables', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tenant_id');
$table->string('product_category', 50)->comment('SCREEN, STEEL');
$table->string('price_type', 50)->comment('area_based, weight_based, fixed');
$table->decimal('min_value', 12, 4)->default(0)->comment('면적/중량 최소');
$table->decimal('max_value', 12, 4)->default(0)->comment('면적/중량 최대');
$table->decimal('unit_price', 15, 2)->default(0)->comment('해당 구간 단가');
$table->decimal('labor_rate', 5, 2)->default(0)->comment('노무비율 (%)');
$table->decimal('install_rate', 5, 2)->default(0)->comment('설치비율 (%)');
$table->boolean('is_active')->default(true);
$table->json('options')->nullable();
$table->timestamps();
$table->index('tenant_id');
$table->index(['product_category', 'price_type']);
});
}
public function down(): void
{
Schema::dropIfExists('ai_quote_price_tables');
Schema::table('ai_quotation_items', function (Blueprint $table) {
$table->dropColumn([
'specification', 'unit', 'quantity', 'unit_price',
'total_price', 'item_category', 'floor_code',
]);
});
Schema::table('ai_quotations', function (Blueprint $table) {
$table->dropIndex(['quote_mode']);
$table->dropIndex(['quote_number']);
$table->dropColumn(['quote_mode', 'quote_number', 'product_category']);
});
}
};