diff --git a/app/Services/AttendanceService.php b/app/Services/AttendanceService.php index f4b444d..4c26c6a 100644 --- a/app/Services/AttendanceService.php +++ b/app/Services/AttendanceService.php @@ -88,7 +88,9 @@ public function show(int $id): Attendance } /** - * 근태 등록 + * 근태 등록 (Upsert) + * - 같은 날 같은 사용자의 기록이 있으면 업데이트 + * - 없으면 새로 생성 */ public function store(array $data): Attendance { @@ -103,16 +105,25 @@ public function store(array $data): Attendance ->whereDate('base_date', $data['base_date']) ->first(); - if ($existing) { - throw new \Exception(__('error.attendance.already_exists')); - } - // json_details 구성 - // json_details 객체가 직접 전달된 경우 그대로 사용, 아니면 개별 필드에서 구성 $jsonDetails = isset($data['json_details']) && is_array($data['json_details']) ? $data['json_details'] : $this->buildJsonDetails($data); + if ($existing) { + // 기존 기록 업데이트 (Upsert) + $existing->status = $data['status'] ?? $existing->status; + $existing->json_details = array_merge($existing->json_details ?? [], $jsonDetails); + if (array_key_exists('remarks', $data)) { + $existing->remarks = $data['remarks']; + } + $existing->updated_by = $userId; + $existing->save(); + + return $existing->fresh(['user:id,name,email']); + } + + // 새 기록 생성 $attendance = Attendance::create([ 'tenant_id' => $tenantId, 'user_id' => $data['user_id'], diff --git a/app/Swagger/v1/AttendanceApi.php b/app/Swagger/v1/AttendanceApi.php index 17ec740..77a53b5 100644 --- a/app/Swagger/v1/AttendanceApi.php +++ b/app/Swagger/v1/AttendanceApi.php @@ -283,8 +283,8 @@ public function show() {} * @OA\Post( * path="/api/v1/attendances", * tags={"Attendances"}, - * summary="근태 등록", - * description="새 근태 기록을 등록합니다.", + * summary="근태 등록 (Upsert)", + * description="근태 기록을 등록합니다. 같은 날 같은 사용자의 기록이 있으면 업데이트, 없으면 새로 생성합니다.", * security={{"ApiKeyAuth":{}},{"BearerAuth":{}}}, * * @OA\RequestBody( @@ -294,8 +294,8 @@ public function show() {} * ), * * @OA\Response( - * response=201, - * description="등록 성공", + * response=200, + * description="등록/수정 성공", * * @OA\JsonContent( * allOf={ @@ -308,7 +308,6 @@ public function show() {} * * @OA\Response(response=400, description="잘못된 요청", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), * @OA\Response(response=401, description="인증 실패", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), - * @OA\Response(response=409, description="같은 날 기록이 이미 존재함", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")), * @OA\Response(response=500, description="서버 에러", @OA\JsonContent(ref="#/components/schemas/ErrorResponse")) * ) */