subDay(); $start = $date->copy()->startOfDay(); $end = $date->copy()->endOfDay(); $list = EmployeeSignLog::whereBetween('time', [$start, $end])->get(); // 休息的员工 $restEmployeeIds = EmployeeRest::whereBetWeen('date', [$start, $end])->pluck('employee_id'); // 需要打卡的员工 $employees = Employee::where('store_id', '>', 0)->whereNotIn('id', $restEmployeeIds)->get(); foreach ($employees as $employee) { $logs = $list->where('employee_id', $employee->id); // 状态: 两个打卡=正常, 一次打卡 = 缺卡, 两次未打=旷工 $status = 0; // 外勤打卡-事由 $remarks = null; // 上班时间: 12:00 前打卡的都算 $firstTime = null; if ($item = $logs->where('time', '<=', $date->format('Y-m-d 12:00'))->sortBy('time')->first()) { $firstTime = $item->time; $status ++; if ($item->sign_type == SignType::Outside) { $remarks = $item->remarks; } } // 下班时间: 24:00 前打卡的都算 $lastTime = null; if ($item = $logs->where('time', '<=', $date->format('Y-m-d 24:00'))->sortByDesc('time')->first()) { $lastTime = $item->time; $status ++; if ($item->sign_type == SignType::Outside) { $remarks = $item->remarks; } } // 打卡类型 $type = SignType::Absent; if ($status > 0) { $type = $logs->where('sign_type', SignType::Outside)->count() > 0 ? SignType::Outside : SignType::Normal; } $attributes = [ 'date' => $date, 'store_id' => $employee->store_id, 'sign_type' => $type, 'first_time' => $firstTime, 'last_time' => $lastTime, 'sign_status' => match($status) { 0 => SignStatus::Absent, 1 => SignStatus::Lose, 2 => SignStatus::Normal, }, 'remarks' => $remarks, ]; $employee->signs()->create($attributes); } } }