month; $currentYear = $currentDate->year; $data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first(); if ($currentMonth == (int)$request->month && $currentYear == (int)$request->year) { $cacheData = CurrentMonthTimekeeping::getCacheCurrentMonthTimekeeping(); if ($cacheData) { $cacheData->data = json_decode($cacheData->data, true); return response()->json(['status' => true, 'data' => $this->appendUsersInformation($cacheData->data), 'working_days' => $cacheData->working_days, 'message' => 'Get from cache']); } else { $result = $this->analyzeCurrentMonthTimeKeepingData($currentMonth, $currentYear); if ($data) { $data->update(['data' => json_encode($result)]); return response()->json(['status' => true, 'data' => $this->appendUsersInformation($result), 'message' => 'Get from analyzeCurrentMonthTimeKeepingData + update record']); } MonthlyTimekeeping::create(['month' => $currentMonth, 'year' => $currentYear, 'working_days' => $currentDate->daysInMonth, 'data' => json_encode($result)]); return response()->json(['status' => true, 'data' => $this->appendUsersInformation($result), 'message' => 'Get from analyzeCurrentMonthTimeKeepingData + create record']); } } else { if ($data) { $data['data'] = json_decode($data['data']); return response()->json(['status' => true, 'data' => $this->appendUsersInformation($data['data']), 'working_days' => $data['working_days'], 'message' => 'Get from DB']); } else { $result = $this->analyzeCurrentMonthTimeKeepingData($request->month, $request->year); MonthlyTimekeeping::create(['month' => $request->month, 'year' => $request->year, 'working_days' => Carbon::create((int)$request->year, (int)$request->month)->daysInMonth, 'data' => json_encode($result)]); return response()->json(['status' => true, 'data' => $this->appendUsersInformation($result), 'message' => 'Get from analyzeCurrentMonthTimeKeepingData']); } } return response()->json(['status' => false, 'mewssage' => 'Get data failed!']); } public function addWorkingTimeForMultipleUser(Request $request) { $user_ids = $request->users; $year = $request->year; $month = $request->month; $day = $request->day; $type = $request->type; foreach ($user_ids as $id) { $user = Admin::find($id); $date = Carbon::create($year, $month, $day)->setTimezone(env('TIME_ZONE')); $start = $date->copy()->setTime(7, 31, 11); $end = $type == 'half' ? $date->copy()->setTime(11, 31, 11) : $date->copy()->setTime(17, 1, 11); Tracking::insert([ [ 'name' => $user->name, 'user_id' => $user->id, 'status' => 'check in', 'time_string' => $start->format('Y-m-d H:i:s'), 'created_at' => $start->setTimezone('UTC') ], [ 'name' => $user->name, 'user_id' => $user->id, 'status' => 'check out', 'time_string' => $end->format('Y-m-d H:i:s'), 'created_at' => $end->setTimezone('UTC') ] ]); } $this->createOrUpdateRecordForCurrentMonth($month, $year); return response()->json(['status' => true, 'message' => 'Add successfully']); } public function saveWorkingDays(Request $request) { $data = MonthlyTimekeeping::where('month', '=', $request->month)->where('year', '=', $request->year)->first(); if ($data) { $data->update(['working_days' => $request->working_days]); $this->createOrUpdateRecordForCurrentMonth($request->month, $request->year); return response()->json(['status' => true, 'message' => 'Update successful']); } return response()->json(['status' => false, 'message' => 'Update failed']); } public function addNoteForUser(Request $request) { $user_id = $request->users["id"] ?? ""; $month = $request->month; $year = $request->year; $day = $request->day; $time_type = $request->type; $reason = $request->reason; $note = $request->note; if ($user_id == "") { return response()->json(['status' => false, 'message' => 'User not found!']); } $existingNote = Notes::where('n_user_id', $user_id) ->where('n_day', $day) ->where('n_month', $month) ->where('n_year', $year) ->where('n_reason', $reason) ->first(); if ($existingNote) { // Cập nhật bản ghi nếu đã tồn tại $existingNote->update([ 'n_day' => $day, 'n_month' => $month, 'n_year' => $year, 'n_time_type' => $time_type, 'n_reason' => $reason, 'n_note' => $note ]); } else { // Chèn bản ghi mới nếu không tồn tại Notes::create([ 'n_user_id' => $user_id, 'n_day' => $day, 'n_month' => $month, 'n_year' => $year, 'n_time_type' => $time_type, 'n_reason' => $reason, 'n_note' => $note ]); } $this->createOrUpdateRecordForCurrentMonth($month, $year); return response()->json(['status' => true, 'message' => 'Add successfully']); } public function updateCacheMonth(Request $request) { $month = $request->month; $year = $request->year; $this->createOrUpdateRecordForCurrentMonth($month, $year); return response()->json(['status' => true, 'message' => 'Update successfully']); } public function deleteNote(Request $request) { $rules = [ 'id' => 'required' ]; // Validate the request $request->validate($rules); $id = $request->input('id'); $month = $request->month; $year = $request->year; $note = Notes::find($id); if ($note) { $n_month = $note->n_month; $n_year = $note->n_year; if ($note->n_reason == "ONLEAVE") { // Get note reason ONLEAVE by $n_month, $n_year not include $note->id & include $note->n_user_id // $onleave = Notes::getNotesByMonthAndYearAndUserId($n_month, $n_year, $note->n_user_id, $note->id); // Get note reason LEAVE_WITHOUT_PAY by $n_month, $n_year & include $note->n_user_id $leaveWithoutPay = Notes::getNotesByMonthAndYearAndUserIdAndReason($n_month, $n_year, $note->n_user_id, 'LEAVE_WITHOUT_PAY'); if (count($leaveWithoutPay) > 0) { $deletedValue = ($note->n_time_type === 'ALL') ? 1.0 : 0.5; $needUpdate = $deletedValue; // dd($needUpdate, $leaveWithoutPay); foreach ($leaveWithoutPay as $lwNote) { if ($needUpdate <= 0) break; if ($lwNote->n_time_type === 'ALL') { if ($needUpdate == 1.0) { // Chuyển cả note ALL thành phép $lwNote->update(['n_reason' => 'ONLEAVE']); $needUpdate = 0; break; } else { // $needUpdate == 0.5 // Tách ALL thành 2 note S và C, chuyển S thành phép, C giữ không phép Notes::create([ 'n_user_id' => $lwNote->n_user_id, 'n_day' => $lwNote->n_day, 'n_month' => $lwNote->n_month, 'n_year' => $lwNote->n_year, 'n_time_type' => 'S', 'n_reason' => 'ONLEAVE', 'n_note' => $lwNote->n_note ]); Notes::create([ 'n_user_id' => $lwNote->n_user_id, 'n_day' => $lwNote->n_day, 'n_month' => $lwNote->n_month, 'n_year' => $lwNote->n_year, 'n_time_type' => 'C', 'n_reason' => 'LEAVE_WITHOUT_PAY', 'n_note' => $lwNote->n_note ]); $lwNote->delete(); $needUpdate = 0; break; } } else { // Nếu $lwNote->n_time_type == 'S' hoặc 'C' => 0.5 if ($needUpdate == 1.0) { // Chuyển cả note ALL thành phép $lwNote->update(['n_reason' => 'ONLEAVE']); $needUpdate -= 0.5; } else { // $needUpdate == 0.5 // S hoặc C, chỉ cần chuyển đúng 0.5 ngày $lwNote->update(['n_reason' => 'ONLEAVE']); $needUpdate = 0; break; } } } } else { // Khi note phép và k tồn tại nghỉ không phép => phép + dồn cho tháng sau } } $note->delete(); $this->createOrUpdateRecordForCurrentMonth($month, $year); return response()->json(['message' => 'Delete success', 'status' => true]); } return response()->json(['message' => 'Delete fail', 'status' => false]); } public function export(Request $request) { // Validate request $request->validate([ 'month' => 'required|numeric|between:1,12', 'year' => 'required|numeric|min:2000', 'working_days' => 'required|numeric|between:1,31' ]); // Reuse get() function to fetch data $response = $this->get($request); $responseData = json_decode($response->getContent(), true); if (!$responseData['status']) { return response()->json(['status' => false, 'message' => 'No data found']); } // Lọc chỉ lấy user có permission bao gồm staff $staffData = array_filter($responseData['data'], function ($user) { return isset($user['user']['permission']) && strpos($user['user']['permission'], 'staff') !== false; }); $currentDate = date('d_His'); return Excel::download( new TimekeepingExport( array_values($staffData), // Convert to indexed array after filtering $request->month, $request->year, $request->working_days ), "Timekeeping_{$request->month}_{$request->year}_{$currentDate}.xlsx" ); } }