feat: [HR/기타] 캘린더/배차/설비/재고 + DB 마이그레이션
- 캘린더 CRUD API, 배차차량 관리 API (CRUD + options) - 배차정보 다중 행 시스템 (shipment_vehicle_dispatches) - 설비 다중점검주기 + 부 담당자 스키마 추가 - TodayIssue 날짜 기반 조회, Stock/Client 날짜 필터 - i18n 메시지 추가 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?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('equipments', function (Blueprint $table) {
|
||||
$table->foreignId('sub_manager_id')->nullable()->after('manager_id')
|
||||
->comment('부 담당자 ID (users.id)');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('equipments', function (Blueprint $table) {
|
||||
$table->dropColumn('sub_manager_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
<?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
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
// 컬럼 추가 (이미 존재하면 건너뜀)
|
||||
if (! Schema::hasColumn('equipment_inspection_templates', 'inspection_cycle')) {
|
||||
Schema::table('equipment_inspection_templates', function (Blueprint $table) {
|
||||
$table->string('inspection_cycle', 20)->default('daily')->after('equipment_id')
|
||||
->comment('점검주기: daily/weekly/monthly/bimonthly/quarterly/semiannual');
|
||||
});
|
||||
}
|
||||
|
||||
// FK 삭제 → 유니크 변경 → FK 재생성 (개별 statement)
|
||||
$this->dropFkIfExists('equipment_inspection_templates', 'equipment_inspection_templates_equipment_id_foreign');
|
||||
$this->dropUniqueIfExists('equipment_inspection_templates', 'uq_equipment_item_no');
|
||||
|
||||
Schema::table('equipment_inspection_templates', function (Blueprint $table) {
|
||||
$table->unique(['equipment_id', 'inspection_cycle', 'item_no'], 'uq_equipment_cycle_item_no');
|
||||
$table->index('inspection_cycle', 'idx_insp_tmpl_cycle');
|
||||
|
||||
$table->foreign('equipment_id')
|
||||
->references('id')
|
||||
->on('equipments')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
$this->dropFkIfExists('equipment_inspection_templates', 'equipment_inspection_templates_equipment_id_foreign');
|
||||
|
||||
Schema::table('equipment_inspection_templates', function (Blueprint $table) {
|
||||
$table->dropIndex('idx_insp_tmpl_cycle');
|
||||
$table->dropUnique('uq_equipment_cycle_item_no');
|
||||
$table->unique(['equipment_id', 'item_no'], 'uq_equipment_item_no');
|
||||
$table->dropColumn('inspection_cycle');
|
||||
|
||||
$table->foreign('equipment_id')
|
||||
->references('id')
|
||||
->on('equipments')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
private function dropFkIfExists(string $table, string $fkName): void
|
||||
{
|
||||
$fks = DB::select("SELECT CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND CONSTRAINT_NAME = ?", [$table, $fkName]);
|
||||
if (count($fks) > 0) {
|
||||
DB::statement("ALTER TABLE `{$table}` DROP FOREIGN KEY `{$fkName}`");
|
||||
}
|
||||
}
|
||||
|
||||
private function dropUniqueIfExists(string $table, string $indexName): void
|
||||
{
|
||||
$indexes = DB::select("SHOW INDEX FROM `{$table}` WHERE Key_name = ?", [$indexName]);
|
||||
if (count($indexes) > 0) {
|
||||
DB::statement("ALTER TABLE `{$table}` DROP INDEX `{$indexName}`");
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('equipment_inspections', function (Blueprint $table) {
|
||||
$table->string('inspection_cycle', 20)->default('daily')->after('equipment_id')
|
||||
->comment('점검주기: daily/weekly/monthly/bimonthly/quarterly/semiannual');
|
||||
});
|
||||
|
||||
// 기존 레코드를 daily로 설정
|
||||
DB::statement("UPDATE equipment_inspections SET inspection_cycle = 'daily' WHERE inspection_cycle = '' OR inspection_cycle IS NULL");
|
||||
|
||||
Schema::table('equipment_inspections', function (Blueprint $table) {
|
||||
// 기존 유니크/인덱스 삭제
|
||||
$table->dropUnique('uq_inspection_month');
|
||||
$table->dropIndex('idx_inspection_ym');
|
||||
|
||||
// cycle 포함 유니크/인덱스 추가
|
||||
$table->unique(['tenant_id', 'equipment_id', 'inspection_cycle', 'year_month'], 'uq_inspection_cycle_period');
|
||||
$table->index(['tenant_id', 'inspection_cycle', 'year_month'], 'idx_inspection_cycle_period');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('equipment_inspections', function (Blueprint $table) {
|
||||
$table->dropIndex('idx_inspection_cycle_period');
|
||||
$table->dropUnique('uq_inspection_cycle_period');
|
||||
|
||||
$table->unique(['tenant_id', 'equipment_id', 'year_month'], 'uq_inspection_month');
|
||||
$table->index(['tenant_id', 'year_month'], 'idx_inspection_ym');
|
||||
|
||||
$table->dropColumn('inspection_cycle');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
<?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('shipment_vehicle_dispatches', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('tenant_id')->comment('테넌트 ID');
|
||||
$table->foreignId('shipment_id')->comment('출하 ID');
|
||||
$table->integer('seq')->default(1)->comment('순번');
|
||||
$table->string('logistics_company', 100)->nullable()->comment('물류사');
|
||||
$table->datetime('arrival_datetime')->nullable()->comment('도착일시');
|
||||
$table->string('tonnage', 20)->nullable()->comment('톤수');
|
||||
$table->string('vehicle_no', 20)->nullable()->comment('차량번호');
|
||||
$table->string('driver_contact', 50)->nullable()->comment('운전자 연락처');
|
||||
$table->text('remarks')->nullable()->comment('비고');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
// 인덱스
|
||||
$table->index(['shipment_id', 'seq']);
|
||||
|
||||
// 외래키
|
||||
$table->foreign('shipment_id')->references('id')->on('shipments')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('shipment_vehicle_dispatches');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<?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('shipment_vehicle_dispatches', function (Blueprint $table) {
|
||||
$table->json('options')->nullable()->after('remarks')
|
||||
->comment('추가 속성 (dispatch_no, status, freight_cost_type, supply_amount, vat, total_amount, writer)');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('shipment_vehicle_dispatches', function (Blueprint $table) {
|
||||
$table->dropColumn('options');
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user