chore(API): 마이그레이션 파일 정리 및 추가
- 기존 마이그레이션 파일 정리 - handover_reports 테이블 마이그레이션 추가 - site_briefings 테이블 마이그레이션 추가 - work_orders process_id 마이그레이션 추가 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,193 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 작업지시 공정유형 변경 마이그레이션
|
||||||
|
*
|
||||||
|
* 변경 사항:
|
||||||
|
* - process_type (varchar: screen/slat/bending) 제거
|
||||||
|
* - process_id (FK → processes.id) 추가
|
||||||
|
*
|
||||||
|
* 데이터 마이그레이션:
|
||||||
|
* - screen → processes.process_name = '스크린' (P-002)
|
||||||
|
* - slat → processes.process_name = '슬랫' (P-001)
|
||||||
|
* - bending → processes.process_name = '절곡' (신규 생성)
|
||||||
|
*/
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
// 1. 절곡 공정이 없으면 각 테넌트별로 생성
|
||||||
|
$this->ensureBendingProcessExists();
|
||||||
|
|
||||||
|
// 2. process_id 컬럼 추가 (nullable로 먼저 생성)
|
||||||
|
Schema::table('work_orders', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('process_id')
|
||||||
|
->nullable()
|
||||||
|
->after('sales_order_id')
|
||||||
|
->comment('공정 ID (FK → processes.id)');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. 기존 process_type 데이터를 process_id로 마이그레이션
|
||||||
|
$this->migrateProcessTypeToProcessId();
|
||||||
|
|
||||||
|
// 4. process_id에 FK 제약 추가 및 NOT NULL로 변경
|
||||||
|
Schema::table('work_orders', function (Blueprint $table) {
|
||||||
|
$table->foreign('process_id')
|
||||||
|
->references('id')
|
||||||
|
->on('processes')
|
||||||
|
->onDelete('restrict');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 5. 기존 process_type 컬럼 제거
|
||||||
|
Schema::table('work_orders', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('process_type');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
// 1. process_type 컬럼 복원
|
||||||
|
Schema::table('work_orders', function (Blueprint $table) {
|
||||||
|
$table->string('process_type', 30)
|
||||||
|
->default('screen')
|
||||||
|
->after('sales_order_id')
|
||||||
|
->comment('공정유형: screen/slat/bending');
|
||||||
|
});
|
||||||
|
|
||||||
|
// 2. process_id에서 process_type으로 데이터 복원
|
||||||
|
$this->migrateProcessIdToProcessType();
|
||||||
|
|
||||||
|
// 3. FK 및 process_id 컬럼 제거
|
||||||
|
Schema::table('work_orders', function (Blueprint $table) {
|
||||||
|
$table->dropForeign(['process_id']);
|
||||||
|
$table->dropColumn('process_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 절곡 공정이 없는 테넌트에 절곡 공정 생성
|
||||||
|
*/
|
||||||
|
private function ensureBendingProcessExists(): void
|
||||||
|
{
|
||||||
|
// 작업지시에서 bending을 사용하는 테넌트 조회
|
||||||
|
$tenantIds = DB::table('work_orders')
|
||||||
|
->where('process_type', 'bending')
|
||||||
|
->distinct()
|
||||||
|
->pluck('tenant_id');
|
||||||
|
|
||||||
|
foreach ($tenantIds as $tenantId) {
|
||||||
|
// 해당 테넌트에 절곡 공정이 있는지 확인
|
||||||
|
$exists = DB::table('processes')
|
||||||
|
->where('tenant_id', $tenantId)
|
||||||
|
->where('process_name', '절곡')
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if (! $exists) {
|
||||||
|
// 마지막 공정코드 조회
|
||||||
|
$lastCode = DB::table('processes')
|
||||||
|
->where('tenant_id', $tenantId)
|
||||||
|
->orderByDesc('process_code')
|
||||||
|
->value('process_code');
|
||||||
|
|
||||||
|
// 새 공정코드 생성 (P-003 형식)
|
||||||
|
$newCodeNum = 1;
|
||||||
|
if ($lastCode && preg_match('/P-(\d+)/', $lastCode, $matches)) {
|
||||||
|
$newCodeNum = (int) $matches[1] + 1;
|
||||||
|
}
|
||||||
|
$newCode = sprintf('P-%03d', $newCodeNum);
|
||||||
|
|
||||||
|
// 절곡 공정 생성
|
||||||
|
DB::table('processes')->insert([
|
||||||
|
'tenant_id' => $tenantId,
|
||||||
|
'process_code' => $newCode,
|
||||||
|
'process_name' => '절곡',
|
||||||
|
'process_type' => '생산',
|
||||||
|
'description' => '절곡 공정 (마이그레이션에 의해 자동 생성)',
|
||||||
|
'is_active' => true,
|
||||||
|
'created_at' => now(),
|
||||||
|
'updated_at' => now(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process_type → process_id 데이터 마이그레이션
|
||||||
|
*/
|
||||||
|
private function migrateProcessTypeToProcessId(): void
|
||||||
|
{
|
||||||
|
// 공정명 매핑 (process_type → process_name)
|
||||||
|
$mappings = [
|
||||||
|
'screen' => '스크린',
|
||||||
|
'slat' => '슬랫',
|
||||||
|
'bending' => '절곡',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($mappings as $processType => $processName) {
|
||||||
|
// 각 테넌트별로 해당 공정 ID 조회 후 업데이트
|
||||||
|
$workOrders = DB::table('work_orders')
|
||||||
|
->where('process_type', $processType)
|
||||||
|
->whereNull('process_id')
|
||||||
|
->get(['id', 'tenant_id']);
|
||||||
|
|
||||||
|
foreach ($workOrders as $workOrder) {
|
||||||
|
$processId = DB::table('processes')
|
||||||
|
->where('tenant_id', $workOrder->tenant_id)
|
||||||
|
->where('process_name', $processName)
|
||||||
|
->value('id');
|
||||||
|
|
||||||
|
if ($processId) {
|
||||||
|
DB::table('work_orders')
|
||||||
|
->where('id', $workOrder->id)
|
||||||
|
->update(['process_id' => $processId]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// process_id가 설정되지 않은 레코드 확인 (데이터 무결성)
|
||||||
|
$orphanCount = DB::table('work_orders')
|
||||||
|
->whereNull('process_id')
|
||||||
|
->count();
|
||||||
|
|
||||||
|
if ($orphanCount > 0) {
|
||||||
|
throw new \RuntimeException(
|
||||||
|
"마이그레이션 실패: {$orphanCount}개의 작업지시에 대응하는 공정을 찾을 수 없습니다. ".
|
||||||
|
'processes 테이블에 스크린, 슬랫, 절곡 공정이 등록되어 있는지 확인하세요.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* process_id → process_type 데이터 복원 (롤백용)
|
||||||
|
*/
|
||||||
|
private function migrateProcessIdToProcessType(): void
|
||||||
|
{
|
||||||
|
// 공정명 → process_type 역매핑
|
||||||
|
$mappings = [
|
||||||
|
'스크린' => 'screen',
|
||||||
|
'슬랫' => 'slat',
|
||||||
|
'절곡' => 'bending',
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($mappings as $processName => $processType) {
|
||||||
|
DB::table('work_orders')
|
||||||
|
->whereIn('process_id', function ($query) use ($processName) {
|
||||||
|
$query->select('id')
|
||||||
|
->from('processes')
|
||||||
|
->where('process_name', $processName);
|
||||||
|
})
|
||||||
|
->update(['process_type' => $processType]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 매핑되지 않은 공정은 기본값 screen으로 설정
|
||||||
|
DB::table('work_orders')
|
||||||
|
->where('process_type', '')
|
||||||
|
->orWhereNull('process_type')
|
||||||
|
->update(['process_type' => 'screen']);
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('handover_reports', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
|
||||||
|
|
||||||
|
// 보고서 기본 정보
|
||||||
|
$table->string('report_number', 50)->comment('보고서번호');
|
||||||
|
$table->unsignedBigInteger('contract_id')->nullable()->comment('연결 계약 ID');
|
||||||
|
$table->string('site_name')->comment('현장명');
|
||||||
|
|
||||||
|
// 거래처 정보
|
||||||
|
$table->unsignedBigInteger('partner_id')->nullable()->comment('거래처 ID');
|
||||||
|
$table->string('partner_name')->nullable()->comment('거래처명');
|
||||||
|
|
||||||
|
// 담당자 정보
|
||||||
|
$table->unsignedBigInteger('contract_manager_id')->nullable()->comment('계약담당자 ID');
|
||||||
|
$table->string('contract_manager_name')->nullable()->comment('계약담당자명');
|
||||||
|
$table->unsignedBigInteger('construction_pm_id')->nullable()->comment('공사PM ID');
|
||||||
|
$table->string('construction_pm_name')->nullable()->comment('공사PM명');
|
||||||
|
|
||||||
|
// 계약 상세
|
||||||
|
$table->integer('total_sites')->default(0)->comment('총 개소');
|
||||||
|
$table->decimal('contract_amount', 15, 2)->default(0)->comment('계약금액');
|
||||||
|
$table->date('contract_date')->nullable()->comment('계약일자');
|
||||||
|
$table->date('contract_start_date')->nullable()->comment('계약시작일');
|
||||||
|
$table->date('contract_end_date')->nullable()->comment('계약종료일');
|
||||||
|
$table->date('completion_date')->nullable()->comment('준공일');
|
||||||
|
|
||||||
|
// 상태 정보
|
||||||
|
$table->string('status', 20)->default('pending')->comment('인수인계상태: pending, completed');
|
||||||
|
|
||||||
|
// 2차 배관
|
||||||
|
$table->boolean('has_secondary_piping')->default(false)->comment('2차 배관 유무');
|
||||||
|
$table->decimal('secondary_piping_amount', 15, 2)->default(0)->comment('2차 배관 금액');
|
||||||
|
$table->text('secondary_piping_note')->nullable()->comment('2차 배관 비고');
|
||||||
|
|
||||||
|
// 도장 & 코킹
|
||||||
|
$table->boolean('has_coating')->default(false)->comment('도장 & 코킹 유무');
|
||||||
|
$table->decimal('coating_amount', 15, 2)->default(0)->comment('도장 & 코킹 금액');
|
||||||
|
$table->text('coating_note')->nullable()->comment('도장 & 코킹 비고');
|
||||||
|
|
||||||
|
// 장비 외 실행금액 (JSON)
|
||||||
|
$table->json('external_equipment_cost')->nullable()->comment('장비 외 실행금액: shipping_cost, high_altitude_work, public_expense');
|
||||||
|
|
||||||
|
// 특이사항
|
||||||
|
$table->text('special_notes')->nullable()->comment('특이사항');
|
||||||
|
|
||||||
|
// 활성화 상태
|
||||||
|
$table->boolean('is_active')->default(true)->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');
|
||||||
|
$table->index('contract_id');
|
||||||
|
$table->index('partner_id');
|
||||||
|
$table->index('status');
|
||||||
|
$table->unique(['tenant_id', 'report_number']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('handover_reports');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('handover_report_managers', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
|
||||||
|
$table->unsignedBigInteger('handover_report_id')->comment('인수인계보고서 ID');
|
||||||
|
|
||||||
|
// 담당자 정보
|
||||||
|
$table->string('name')->comment('담당자명');
|
||||||
|
$table->text('non_performance_reason')->nullable()->comment('미이행 사유');
|
||||||
|
$table->text('signature')->nullable()->comment('서명 (Base64 또는 URL)');
|
||||||
|
|
||||||
|
// 순서
|
||||||
|
$table->integer('sort_order')->default(0)->comment('정렬 순서');
|
||||||
|
|
||||||
|
// 감사 컬럼
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable()->comment('생성자 ID');
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable()->comment('수정자 ID');
|
||||||
|
|
||||||
|
// 타임스탬프
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// 인덱스
|
||||||
|
$table->index('tenant_id');
|
||||||
|
$table->index('handover_report_id');
|
||||||
|
|
||||||
|
// 외래키
|
||||||
|
$table->foreign('handover_report_id')
|
||||||
|
->references('id')
|
||||||
|
->on('handover_reports')
|
||||||
|
->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('handover_report_managers');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('handover_report_items', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
|
||||||
|
$table->unsignedBigInteger('handover_report_id')->comment('인수인계보고서 ID');
|
||||||
|
|
||||||
|
// ITEM 정보
|
||||||
|
$table->integer('item_no')->default(0)->comment('순번');
|
||||||
|
$table->string('name')->comment('명칭');
|
||||||
|
$table->string('product')->nullable()->comment('제품');
|
||||||
|
$table->integer('quantity')->default(0)->comment('수량');
|
||||||
|
$table->text('remark')->nullable()->comment('비고');
|
||||||
|
|
||||||
|
// 감사 컬럼
|
||||||
|
$table->unsignedBigInteger('created_by')->nullable()->comment('생성자 ID');
|
||||||
|
$table->unsignedBigInteger('updated_by')->nullable()->comment('수정자 ID');
|
||||||
|
|
||||||
|
// 타임스탬프
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// 인덱스
|
||||||
|
$table->index('tenant_id');
|
||||||
|
$table->index('handover_report_id');
|
||||||
|
$table->index(['handover_report_id', 'item_no']);
|
||||||
|
|
||||||
|
// 외래키
|
||||||
|
$table->foreign('handover_report_id')
|
||||||
|
->references('id')
|
||||||
|
->on('handover_reports')
|
||||||
|
->onDelete('cascade');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('handover_report_items');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::create('site_briefings', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->foreignId('tenant_id')->comment('테넌트 ID');
|
||||||
|
|
||||||
|
// 기본 정보
|
||||||
|
$table->string('briefing_code', 50)->nullable()->comment('현설번호 (자동생성)');
|
||||||
|
$table->string('title', 200)->comment('현장설명회명/현장명');
|
||||||
|
$table->text('description')->nullable()->comment('설명/업무보고');
|
||||||
|
|
||||||
|
// 거래처/현장 연결
|
||||||
|
$table->foreignId('partner_id')->nullable()->comment('거래처 ID');
|
||||||
|
$table->foreignId('site_id')->nullable()->comment('현장 ID');
|
||||||
|
|
||||||
|
// 일정 정보
|
||||||
|
$table->date('briefing_date')->comment('현장설명회 일자');
|
||||||
|
$table->string('briefing_time', 10)->nullable()->comment('현장설명회 시간 (HH:MM)');
|
||||||
|
$table->enum('briefing_type', ['online', 'offline'])->default('offline')->comment('구분: online|offline');
|
||||||
|
$table->string('location', 200)->nullable()->comment('현장설명회 장소');
|
||||||
|
$table->string('address', 255)->nullable()->comment('주소');
|
||||||
|
|
||||||
|
// 상태 정보
|
||||||
|
$table->enum('status', ['scheduled', 'ongoing', 'completed', 'cancelled', 'postponed'])
|
||||||
|
->default('scheduled')->comment('상태: scheduled|ongoing|completed|cancelled|postponed');
|
||||||
|
$table->enum('bid_status', ['pending', 'bidding', 'closed', 'failed', 'awarded'])
|
||||||
|
->default('pending')->comment('입찰상태: pending|bidding|closed|failed|awarded');
|
||||||
|
$table->date('bid_date')->nullable()->comment('입찰일자');
|
||||||
|
|
||||||
|
// 참석자 정보
|
||||||
|
$table->string('attendee', 100)->nullable()->comment('담당 참석자');
|
||||||
|
$table->enum('attendance_status', ['scheduled', 'attended', 'absent'])
|
||||||
|
->default('scheduled')->comment('참석상태: scheduled|attended|absent');
|
||||||
|
$table->integer('attendee_count')->default(0)->comment('총 참석자 수');
|
||||||
|
|
||||||
|
// 공사 정보
|
||||||
|
$table->integer('site_count')->default(0)->comment('개소 수');
|
||||||
|
$table->date('construction_start_date')->nullable()->comment('공사기간 시작');
|
||||||
|
$table->date('construction_end_date')->nullable()->comment('공사기간 종료');
|
||||||
|
$table->enum('vat_type', ['excluded', 'included'])->default('excluded')->comment('부가세: excluded|included');
|
||||||
|
|
||||||
|
// 감사 필드
|
||||||
|
$table->foreignId('created_by')->nullable()->comment('생성자');
|
||||||
|
$table->foreignId('updated_by')->nullable()->comment('수정자');
|
||||||
|
$table->foreignId('deleted_by')->nullable()->comment('삭제자');
|
||||||
|
$table->softDeletes();
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
// 인덱스
|
||||||
|
$table->index('tenant_id');
|
||||||
|
$table->index('partner_id');
|
||||||
|
$table->index('site_id');
|
||||||
|
$table->index('briefing_date');
|
||||||
|
$table->index('status');
|
||||||
|
$table->index('bid_status');
|
||||||
|
$table->unique(['tenant_id', 'briefing_code']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('site_briefings');
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?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
|
||||||
|
{
|
||||||
|
Schema::table('site_briefings', function (Blueprint $table) {
|
||||||
|
// attendee 컬럼 삭제 후 attendees JSON 컬럼 추가
|
||||||
|
$table->dropColumn('attendee');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('site_briefings', function (Blueprint $table) {
|
||||||
|
// JSON 컬럼으로 참석자 목록 저장
|
||||||
|
// 구조: [{"user_id": 1, "name": "홍길동", "type": "internal"}, {"name": "외부인", "company": "업체명", "phone": "010-1234-5678", "type": "external"}]
|
||||||
|
$table->json('attendees')->nullable()->after('bid_date')->comment('참석자 목록 (JSON)');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('site_briefings', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('attendees');
|
||||||
|
});
|
||||||
|
|
||||||
|
Schema::table('site_briefings', function (Blueprint $table) {
|
||||||
|
$table->string('attendee', 100)->nullable()->after('bid_date')->comment('참석자 (단일)');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* 현장설명회 참석완료 시 견적 자동등록 기능을 위한 스키마 변경
|
||||||
|
* - quotes에 site_briefing_id FK 추가
|
||||||
|
* - product_category nullable로 변경
|
||||||
|
* - status에 'pending' (견적대기) 추가
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('quotes', function (Blueprint $table) {
|
||||||
|
// 현장설명회 연결
|
||||||
|
$table->foreignId('site_briefing_id')
|
||||||
|
->nullable()
|
||||||
|
->after('order_id')
|
||||||
|
->comment('현장설명회 ID (자동생성 시)');
|
||||||
|
|
||||||
|
// 인덱스 추가
|
||||||
|
$table->index('site_briefing_id', 'idx_quotes_site_briefing_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
// product_category를 nullable enum으로 변경
|
||||||
|
// MySQL에서 enum 변경은 raw SQL 필요
|
||||||
|
DB::statement("ALTER TABLE quotes MODIFY product_category ENUM('SCREEN', 'STEEL') NULL COMMENT '제품 카테고리'");
|
||||||
|
|
||||||
|
// status에 'pending' 추가
|
||||||
|
DB::statement("ALTER TABLE quotes MODIFY status ENUM('pending', 'draft', 'sent', 'approved', 'rejected', 'finalized', 'converted') DEFAULT 'draft' COMMENT '상태'");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('quotes', function (Blueprint $table) {
|
||||||
|
$table->dropIndex('idx_quotes_site_briefing_id');
|
||||||
|
$table->dropColumn('site_briefing_id');
|
||||||
|
});
|
||||||
|
|
||||||
|
// product_category를 NOT NULL로 복원
|
||||||
|
DB::statement("ALTER TABLE quotes MODIFY product_category ENUM('SCREEN', 'STEEL') NOT NULL COMMENT '제품 카테고리'");
|
||||||
|
|
||||||
|
// status에서 'pending' 제거
|
||||||
|
DB::statement("ALTER TABLE quotes MODIFY status ENUM('draft', 'sent', 'approved', 'rejected', 'finalized', 'converted') DEFAULT 'draft' COMMENT '상태'");
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user