'array', ]; protected $appends = [ 'position_label', 'job_title_label', 'rank', 'hire_date', ]; protected $fillable = [ 'tenant_id', 'user_id', 'department_id', 'position_key', 'job_title_key', 'work_location_key', 'employment_type_key', 'employee_status', 'manager_user_id', 'json_extra', 'profile_photo_path', 'display_name', ]; // ========================================================================= // 관계 정의 // ========================================================================= public function user(): BelongsTo { return $this->belongsTo(User::class, 'user_id'); } public function department(): BelongsTo { return $this->belongsTo(Department::class, 'department_id'); } public function manager(): BelongsTo { return $this->belongsTo(User::class, 'manager_user_id'); } // ========================================================================= // json_extra 헬퍼 메서드 // ========================================================================= /** * json_extra에서 특정 키 값 가져오기 */ public function getJsonExtraValue(string $key, mixed $default = null): mixed { return $this->json_extra[$key] ?? $default; } /** * json_extra에 특정 키 값 설정 */ public function setJsonExtraValue(string $key, mixed $value): void { $extra = $this->json_extra ?? []; if ($value === null) { unset($extra[$key]); } else { $extra[$key] = $value; } $this->json_extra = $extra; } /** * 사원 정보 일괄 업데이트 (json_extra) */ public function updateEmployeeInfo(array $data): void { $allowedKeys = [ 'employee_code', 'resident_number', 'gender', 'address', 'salary', 'hire_date', 'rank', 'bank_account', 'work_type', 'contract_info', 'emergency_contact', 'education', 'certifications', ]; $extra = $this->json_extra ?? []; foreach ($allowedKeys as $key) { if (array_key_exists($key, $data)) { if ($data[$key] === null) { unset($extra[$key]); } else { $extra[$key] = $data[$key]; } } } $this->json_extra = $extra; $this->save(); } // ========================================================================= // json_extra Accessor (자주 사용하는 필드) // ========================================================================= public function getEmployeeCodeAttribute(): ?string { return $this->json_extra['employee_code'] ?? null; } public function getHireDateAttribute(): ?string { return $this->json_extra['hire_date'] ?? null; } public function getAddressAttribute(): ?string { return $this->json_extra['address'] ?? null; } public function getEmergencyContactAttribute(): ?string { return $this->json_extra['emergency_contact'] ?? null; } /** * 직책 레이블 (position_key → 한글) */ public function getPositionLabelAttribute(): ?string { $labels = [ 'EXECUTIVE' => '임원', 'DIRECTOR' => '부장', 'MANAGER' => '과장', 'SENIOR' => '대리', 'STAFF' => '사원', 'INTERN' => '인턴', ]; return $labels[$this->position_key] ?? $this->position_key; } /** * 직급 레이블 (job_title_key → 한글) */ public function getJobTitleLabelAttribute(): ?string { $labels = [ 'CEO' => '대표이사', 'CTO' => '기술이사', 'CFO' => '재무이사', 'TEAM_LEAD' => '팀장', 'TEAM_MEMBER' => '팀원', ]; return $labels[$this->job_title_key] ?? $this->job_title_key; } /** * json_extra 내 직급 정보 (rank) */ public function getRankAttribute(): ?string { return $this->json_extra['rank'] ?? null; } // ========================================================================= // 스코프 // ========================================================================= public function scopeActive($query) { return $query->where('employee_status', 'active'); } public function scopeOnLeave($query) { return $query->where('employee_status', 'leave'); } public function scopeResigned($query) { return $query->where('employee_status', 'resigned'); } }