id(); $table->unsignedBigInteger('tenant_id')->comment('테넌트 ID'); $table->unsignedBigInteger('model_set_id')->comment('모델셋(카테고리) ID'); $table->string('estimate_no', 50)->comment('견적번호 (자동생성)'); $table->string('estimate_name')->comment('견적명'); $table->string('customer_name')->nullable()->comment('고객명'); $table->string('project_name')->nullable()->comment('프로젝트명'); // 견적 파라미터 (사용자 입력값들) $table->json('parameters')->comment('견적 파라미터 (W0, H0, 수량 등)'); // 계산 결과 (W1, H1, 중량, 면적 등) $table->json('calculated_results')->nullable()->comment('계산 결과값들'); // BOM 데이터 (계산된 BOM 정보) $table->json('bom_data')->nullable()->comment('BOM 계산 결과'); $table->decimal('total_amount', 15, 2)->nullable()->comment('총 견적금액'); $table->enum('status', ['DRAFT', 'SENT', 'APPROVED', 'REJECTED', 'EXPIRED']) ->default('DRAFT')->comment('견적 상태'); $table->text('notes')->nullable()->comment('비고'); $table->date('valid_until')->nullable()->comment('견적 유효기간'); // 공통 감사 필드 $table->unsignedBigInteger('created_by')->nullable()->comment('생성자 ID'); $table->unsignedBigInteger('updated_by')->nullable()->comment('수정자 ID'); $table->unsignedBigInteger('deleted_by')->nullable()->comment('삭제자 ID'); $table->timestamps(); $table->softDeletes(); // 인덱스 $table->index(['tenant_id', 'status']); $table->index(['tenant_id', 'created_at']); $table->index(['tenant_id', 'model_set_id']); $table->unique(['tenant_id', 'estimate_no']); // 외래키 $table->foreign('tenant_id')->references('id')->on('tenants')->onDelete('cascade'); $table->foreign('model_set_id')->references('id')->on('categories')->onDelete('restrict'); }); Schema::create('estimate_items', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('tenant_id')->comment('테넌트 ID'); $table->unsignedBigInteger('estimate_id')->comment('견적 ID'); $table->integer('sequence')->default(1)->comment('항목 순번'); $table->string('item_name')->comment('항목명'); $table->text('item_description')->nullable()->comment('항목 설명'); // 항목별 파라미터 (개별 제품 파라미터) $table->json('parameters')->comment('항목별 파라미터'); // 항목별 계산 결과 $table->json('calculated_values')->nullable()->comment('항목별 계산값'); $table->decimal('unit_price', 12, 2)->default(0)->comment('단가'); $table->decimal('quantity', 8, 2)->default(1)->comment('수량'); $table->decimal('total_price', 15, 2)->default(0)->comment('총 가격 (단가 × 수량)'); // BOM 구성품 정보 $table->json('bom_components')->nullable()->comment('BOM 구성품 목록'); $table->text('notes')->nullable()->comment('항목별 비고'); // 공통 감사 필드 $table->unsignedBigInteger('created_by')->nullable()->comment('생성자 ID'); $table->unsignedBigInteger('updated_by')->nullable()->comment('수정자 ID'); $table->unsignedBigInteger('deleted_by')->nullable()->comment('삭제자 ID'); $table->timestamps(); $table->softDeletes(); // 인덱스 $table->index(['tenant_id', 'estimate_id']); $table->index(['estimate_id', 'sequence']); // 외래키 $table->foreign('tenant_id')->references('id')->on('tenants')->onDelete('cascade'); $table->foreign('estimate_id')->references('id')->on('estimates')->onDelete('cascade'); }); } public function down(): void { Schema::dropIfExists('estimate_items'); Schema::dropIfExists('estimates'); } };