'array', 'items' => 'array', 'attachments' => 'array', 'extra' => 'array', 'request_date' => 'date', 'inspection_date' => 'date', ]; /** * 검사 유형 상수 */ public const TYPE_IQC = 'IQC'; // 수입검사 (Incoming Quality Control) public const TYPE_PQC = 'PQC'; // 공정검사 (Process Quality Control) public const TYPE_FQC = 'FQC'; // 최종검사 (Final Quality Control) /** * 상태 상수 */ public const STATUS_WAITING = 'waiting'; public const STATUS_IN_PROGRESS = 'in_progress'; public const STATUS_COMPLETED = 'completed'; /** * 판정결과 상수 */ public const RESULT_PASS = 'pass'; public const RESULT_FAIL = 'fail'; // ===== Relationships ===== /** * 작업지시 (PQC/FQC용) */ public function workOrder() { return $this->belongsTo(WorkOrder::class); } /** * 품목 */ public function item() { return $this->belongsTo(Item::class, 'item_id'); } /** * 검사자 */ public function inspector() { return $this->belongsTo(User::class, 'inspector_id'); } /** * 생성자 */ public function creator() { return $this->belongsTo(User::class, 'created_by'); } // ===== Accessors (meta JSON 필드) ===== protected function processName(): Attribute { return Attribute::make( get: fn () => $this->meta['process_name'] ?? null, set: fn ($value) => $this->setMetaValue('process_name', $value), ); } protected function quantity(): Attribute { return Attribute::make( get: fn () => $this->meta['quantity'] ?? null, set: fn ($value) => $this->setMetaValue('quantity', $value), ); } protected function unit(): Attribute { return Attribute::make( get: fn () => $this->meta['unit'] ?? null, set: fn ($value) => $this->setMetaValue('unit', $value), ); } // ===== Accessors (extra JSON 필드) ===== protected function remarks(): Attribute { return Attribute::make( get: fn () => $this->extra['remarks'] ?? null, set: fn ($value) => $this->setExtraValue('remarks', $value), ); } protected function opinion(): Attribute { return Attribute::make( get: fn () => $this->extra['opinion'] ?? null, set: fn ($value) => $this->setExtraValue('opinion', $value), ); } // ===== Helper Methods ===== /** * meta JSON 필드에 값 설정 */ protected function setMetaValue(string $key, $value): array { $meta = $this->meta ?? []; $meta[$key] = $value; $this->attributes['meta'] = json_encode($meta); return $meta; } /** * extra JSON 필드에 값 설정 */ protected function setExtraValue(string $key, $value): array { $extra = $this->extra ?? []; $extra[$key] = $value; $this->attributes['extra'] = json_encode($extra); return $extra; } /** * 검사번호 자동 생성 */ public static function generateInspectionNo(int $tenantId, string $type): string { $prefix = match ($type) { self::TYPE_IQC => 'IQC', self::TYPE_PQC => 'PQC', self::TYPE_FQC => 'FQC', default => 'INS', }; $date = now()->format('Ymd'); $lastNo = static::withoutGlobalScopes() ->where('tenant_id', $tenantId) ->where('inspection_no', 'like', "{$prefix}-{$date}-%") ->orderByDesc('inspection_no') ->value('inspection_no'); if ($lastNo) { $seq = (int) substr($lastNo, -4) + 1; } else { $seq = 1; } return sprintf('%s-%s-%04d', $prefix, $date, $seq); } }