Files
sam-docs/changes/20260319_attendance_leave_sync_fix.md

2.7 KiB

근태현황 승인된 휴가 누락 버그 수정

날짜: 2026-03-19 작업자: Claude Code

변경 개요

휴가관리에서 3명의 휴가가 승인 상태인데, 근태현황에는 2명만 표시되는 버그 수정.

근본 원인

Attendance 모델의 $fillabledeleted_at이 포함되지 않아서, updateOrCreate()에서 'deleted_at' => null 설정이 mass assignment 보호에 의해 무시됨.

재현 시나리오

  1. 전진선이 03-18 연차를 신청 → attendance 레코드(id:380) 자동 생성
  2. 03-05에 해당 휴가가 취소됨 → attendance 레코드 soft-delete (deleted_at = 2026-03-05)
  3. 03-16에 동일 날짜로 다시 연차 신청 → 결재 승인 → createAttendanceRecords() 호출
  4. Attendance::withTrashed()->updateOrCreate(...) 실행 — soft-deleted 레코드를 찾아 deleted_at => null 설정 시도
  5. deleted_at$fillable에 없어서 무시됨 → 레코드는 여전히 soft-deleted 상태
  6. 근태현황 조회 시 SoftDeletes 스코프에 의해 해당 레코드 미표시

핵심 코드

// LeaveService::createAttendanceRecords() — 기존 코드 (버그)
Attendance::withTrashed()->updateOrCreate(
    ['tenant_id' => ..., 'user_id' => ..., 'base_date' => ...],
    ['status' => 'vacation', 'deleted_at' => null]  // ← $fillable에 없어서 무시됨
);

수정된 파일

파일 변경 내용
app/Services/HR/LeaveService.php createAttendanceRecords()restore() 메서드로 soft-delete 복원 (근본 원인 수정)
app/Services/HR/AttendanceService.php syncApprovedLeaveAttendances() 추가 — 조회 시 누락 레코드 자동 보정 (방어 로직)

상세 변경 사항

1. 근본 원인 수정 (LeaveService)

updateOrCreate()trashed() 확인 → restore()로 복원:

$attendance = Attendance::withTrashed()->updateOrCreate(...);

if ($attendance->trashed()) {
    $attendance->restore();
    $attendance->update(['deleted_by' => null]);
}

2. 방어 로직 추가 (AttendanceService)

syncApprovedLeaveAttendances() 메서드 — 근태 목록/통계/엑셀 조회 전 실행:

  • 조회 기간 내 승인된 휴가 중 attendance 레코드가 없는 건을 자동 생성
  • getAttendances(), getExportData(), getMonthlyStats()에서 호출

테스트 체크리스트

  • 승인된 휴가 3건 모두 근태현황에 표시 확인 (운영서버)
  • 기존 attendance 레코드가 있는 경우 중복 생성 안 됨
  • soft-deleted 레코드가 정상 복원됨 (id:380 전진선)
  • 운영서버 배포 후 실데이터 확인 완료

관련 문서

  • rules/attendance-api.md — 근태 API 규칙
  • features/hr/ — 인사관리 기능