feat: [material] 부적합관리 API Phase 1-A 구현
- Migration: nonconforming_reports, nonconforming_report_items 테이블 - Model: NonconformingReport, NonconformingReportItem (관계, cast, scope) - FormRequest: Store/Update 검증 (items 배열 포함) - Service: CRUD + 채번(NC-YYYYMMDD-NNN) + 비용 자동 계산 + 상태 전이 - Controller: REST 7개 엔드포인트 (목록/통계/상세/등록/수정/삭제/상태변경) - Route: /api/v1/material/nonconforming-reports - i18n: 부적합관리 에러 메시지 (ko)
This commit is contained in:
@@ -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
|
||||
{
|
||||
Schema::create('nonconforming_reports', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
|
||||
$table->string('nc_number', 30)->comment('부적합번호 NC-YYYYMMDD-NNN');
|
||||
$table->string('status', 20)->default('RECEIVED')->comment('상태: RECEIVED/ANALYZING/RESOLVED/CLOSED');
|
||||
$table->string('nc_type', 20)->comment('부적합유형: material/process/construction/other');
|
||||
$table->date('occurred_at')->comment('발생일');
|
||||
$table->date('confirmed_at')->nullable()->comment('불량확인일');
|
||||
$table->string('site_name', 100)->nullable()->comment('현장명');
|
||||
$table->unsignedBigInteger('department_id')->nullable()->comment('부서');
|
||||
$table->unsignedBigInteger('order_id')->nullable()->comment('관련 수주');
|
||||
$table->unsignedBigInteger('item_id')->nullable()->comment('관련 품목');
|
||||
$table->decimal('defect_quantity', 10, 2)->nullable()->comment('불량 수량');
|
||||
$table->string('unit', 20)->nullable()->comment('단위');
|
||||
$table->text('defect_description')->nullable()->comment('불량 상세 설명');
|
||||
$table->text('cause_analysis')->nullable()->comment('원인 분석');
|
||||
$table->text('corrective_action')->nullable()->comment('처리 방안 및 개선 사항');
|
||||
$table->date('action_completed_at')->nullable()->comment('조치 완료일');
|
||||
$table->unsignedBigInteger('action_manager_id')->nullable()->comment('조치 담당자');
|
||||
$table->unsignedBigInteger('related_employee_id')->nullable()->comment('관련 직원');
|
||||
$table->decimal('material_cost', 12, 0)->default(0)->comment('자재 비용');
|
||||
$table->decimal('shipping_cost', 12, 0)->default(0)->comment('운송 비용');
|
||||
$table->decimal('construction_cost', 12, 0)->default(0)->comment('시공 비용');
|
||||
$table->decimal('other_cost', 12, 0)->default(0)->comment('기타 비용');
|
||||
$table->decimal('total_cost', 12, 0)->default(0)->comment('비용 합계');
|
||||
$table->text('remarks')->nullable()->comment('비고');
|
||||
$table->string('drawing_location', 255)->nullable()->comment('도면 저장 위치');
|
||||
$table->json('options')->nullable()->comment('확장 속성');
|
||||
$table->unsignedBigInteger('created_by')->default(0)->comment('등록자');
|
||||
$table->unsignedBigInteger('updated_by')->nullable()->comment('수정자');
|
||||
$table->unsignedBigInteger('deleted_by')->nullable()->comment('삭제자');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->index(['tenant_id', 'status']);
|
||||
$table->index(['tenant_id', 'nc_type']);
|
||||
$table->index(['tenant_id', 'occurred_at']);
|
||||
$table->unique(['tenant_id', 'nc_number']);
|
||||
});
|
||||
|
||||
Schema::create('nonconforming_report_items', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
|
||||
$table->unsignedBigInteger('nonconforming_report_id')->comment('부적합 보고서 ID');
|
||||
$table->unsignedBigInteger('item_id')->nullable()->comment('품목 마스터 연결');
|
||||
$table->string('item_name', 100)->comment('품목명');
|
||||
$table->string('specification', 100)->nullable()->comment('규격/사양');
|
||||
$table->decimal('quantity', 10, 2)->default(0)->comment('수량');
|
||||
$table->decimal('unit_price', 12, 0)->default(0)->comment('단가');
|
||||
$table->decimal('amount', 12, 0)->default(0)->comment('금액');
|
||||
$table->integer('sort_order')->default(0)->comment('정렬 순서');
|
||||
$table->string('remarks', 255)->nullable()->comment('비고');
|
||||
$table->json('options')->nullable()->comment('확장 속성');
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('nonconforming_report_id');
|
||||
$table->foreign('nonconforming_report_id')
|
||||
->references('id')
|
||||
->on('nonconforming_reports')
|
||||
->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('nonconforming_report_items');
|
||||
Schema::dropIfExists('nonconforming_reports');
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user