'array', 'occurred_at' => 'date', 'confirmed_at' => 'date', 'action_completed_at' => 'date', 'material_cost' => 'integer', 'shipping_cost' => 'integer', 'construction_cost' => 'integer', 'other_cost' => 'integer', 'total_cost' => 'integer', 'defect_quantity' => 'decimal:2', ]; // 상태 상수 public const STATUS_RECEIVED = 'RECEIVED'; public const STATUS_ANALYZING = 'ANALYZING'; public const STATUS_RESOLVED = 'RESOLVED'; public const STATUS_CLOSED = 'CLOSED'; // 부적합 유형 상수 public const TYPE_MATERIAL = 'material'; public const TYPE_PROCESS = 'process'; public const TYPE_CONSTRUCTION = 'construction'; public const TYPE_OTHER = 'other'; public const NC_TYPES = [ self::TYPE_MATERIAL => '자재불량', self::TYPE_PROCESS => '공정불량', self::TYPE_CONSTRUCTION => '시공불량', self::TYPE_OTHER => '기타', ]; public const STATUSES = [ self::STATUS_RECEIVED => '접수', self::STATUS_ANALYZING => '분석중', self::STATUS_RESOLVED => '조치완료', self::STATUS_CLOSED => '종결', ]; // ── 관계 ── public function items(): HasMany { return $this->hasMany(NonconformingReportItem::class)->orderBy('sort_order'); } public function approval(): BelongsTo { return $this->belongsTo(Approval::class); } public function order(): BelongsTo { return $this->belongsTo(Order::class); } public function item(): BelongsTo { return $this->belongsTo(Item::class); } public function department(): BelongsTo { return $this->belongsTo(Department::class); } public function creator(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } public function actionManager(): BelongsTo { return $this->belongsTo(User::class, 'action_manager_id'); } public function relatedEmployee(): BelongsTo { return $this->belongsTo(User::class, 'related_employee_id'); } public function files(): MorphMany { return $this->morphMany(File::class, 'fileable'); } // ── 스코프 ── public function scopeStatus($query, string $status) { return $query->where('status', $status); } public function scopeNcType($query, string $type) { return $query->where('nc_type', $type); } // ── 헬퍼 ── public function recalculateTotalCost(): void { $this->total_cost = $this->material_cost + $this->shipping_cost + $this->construction_cost + $this->other_cost; } public function recalculateMaterialCost(): void { $this->material_cost = (int) $this->items()->sum('amount'); $this->recalculateTotalCost(); } public function isClosed(): bool { return $this->status === self::STATUS_CLOSED; } }