Files

810 lines
30 KiB
PHP
Raw Permalink Normal View History

2026-04-08 07:22:13 +00:00
<?php
namespace App\Http\Controllers;
use Carbon\CarbonInterval;
2026-04-08 07:22:13 +00:00
use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
use function PHPUnit\Framework\throwException;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Http;
use App\Models\AttendanceBreak;
use Morilog\Jalali\Jalalian;
use Illuminate\Http\Request;
use App\Models\TaskDuration;
2026-04-08 07:22:13 +00:00
use App\Models\Pivot_Tasks;
use App\Models\Attendance;
use App\Models\Tasks;
use App\Models\User;
use App\Models\Log;
use Carbon\Carbon;
use App\Models\ai;
2026-07-22 14:10:05 +03:30
use App\Services\LatePenaltyService;
2026-04-08 07:22:13 +00:00
class AttendanceController extends Controller
{
public function index()
{
if (isset($_COOKIE['user_identity'])) {
$username = $_COOKIE['user_identity'];
$attendanceSince = Carbon::now()->subMonths(12)->startOfMonth()->format('Y-m-d 00:00:00');
2026-04-08 07:22:13 +00:00
$Attendance = $username == 1370
? Attendance::where('entered_at', '>=', $attendanceSince)->get()
: Attendance::where('user_identity', $username)
->where('entered_at', '>=', $attendanceSince)
->get();
2026-04-08 07:22:13 +00:00
$jalalian_object = Jalalian::now();
$first_day_of_month = $jalalian_object->subDays($jalalian_object->getDay() - 1);
$carbon_gregorian = $first_day_of_month->toCarbon();
$thismonth = $carbon_gregorian->format('Y-m-d 00:00:00');
$ids = json_decode(request()->cookie('seen_angizeh_ids', '[]'), true) ?: [];
$s = ai::where('key', 'angizeh')
->when($ids, fn($q) => $q->whereNotIn('id', $ids))
->orderByDesc('id')
->first()
?? ai::where('key', 'angizeh')->orderByDesc('id')->first();
if ($s) {
$ids = array_merge($ids, [$s->id]);
Cookie::queue('seen_angizeh_ids', json_encode($ids), 14400);
}
2026-04-08 07:22:13 +00:00
//total time
$now = Jalalian::fromCarbon(Carbon::now());
$tsec = 0;
if (isset($_COOKIE['token01'])) {
$a = json_decode($_COOKIE['token01']);
$user = User::where('user_name', $a->user_profile)
->with(['attendances' => fn($q) => $q->where('entered_at', '>=', $attendanceSince)])
->first();
2026-04-08 07:22:13 +00:00
} else {
$user = User::where('user_name', $username)
->with(['attendances' => fn($q) => $q->where('entered_at', '>=', $attendanceSince)])
->first();
2026-04-08 07:22:13 +00:00
}
if ($user && !empty($user->attendances)) {
2026-04-08 07:22:13 +00:00
foreach ($user->attendances as $att) {
2026-07-22 17:38:35 +03:30
$date = $att->entered_at != null
? \App\Support\JalaliHelper::fromDateTime($att->entered_at)
: null;
2026-04-08 07:22:13 +00:00
$att->date = $date != null ? $date->format('Y/m/d') : null;
if ($att->duration != null && $date != null && $now->getMonth() == $date->getMonth()) {
[$h, $m, $sec] = explode(':', $att->duration);
$tsec += $h * 3600 + $m * 60 + $sec;
}
}
}
$hours = floor($tsec / 3600);
$minutes = floor(($tsec % 3600) / 60);
$totalTime = sprintf('%02d:%02d', $hours, $minutes);
$formaction = (isset($_COOKIE['ad']) && $_COOKIE['ad'] == 1)
? 'admin/'
: 'attendance/';
2026-04-23 14:00:39 +03:30
$existed = $Attendance->whereNull('exited_at')->where('entered_at', '>=', now()->format('Y-m-d 00:00:00'))->where('entered_at', '<=', now()->format('Y-m-d 23:59:59'))->first();
2026-04-08 07:22:13 +00:00
$until_now = null;
$duration = null;
if ($user && $user->break == 1) {
$att = Attendance::where('user_identity', $user->user_name)
->whereNull('exited_at')
->latest('entered_at')
2026-04-08 07:22:13 +00:00
->first();
$break = $att
? AttendanceBreak::where('attendance_id', $att->id)
->whereNull('break_end')
->latest('break_start')
->first()
: null;
if ($break) {
2026-04-08 07:22:13 +00:00
$until_now = (int)Carbon::parse($break->break_start)->diffInSeconds(now(), false);
$duration = $att->duration($break->break_start, now()->format('Y-m-d H:i:s'));
}
2026-04-08 07:22:13 +00:00
}
if ($user) {
$user->tasks = Tasks::where('created_by', $user->id)
->orWhereJsonContains('assignees', (string)$user->id)
->orderBy('target_date', 'desc')
->limit(50)
->get();
}
2026-04-08 07:22:13 +00:00
return view('attendance.index', compact('user'))->with([
's' => $s,
'existed' => $existed,
'formaction' => $formaction,
'breakDu' => $until_now ?? null,
'duration' => $duration,
2026-04-08 07:22:13 +00:00
]);
} else {
foreach (request()->cookies as $name => $value) {
Cookie::queue(Cookie::forget($name));
}
}
return view('attendance.login');
}
// public function back()
// {
// if (isset($_COOKIE['token-0'])) {
// setcookie("user_identity", $_COOKIE['token-0'], time() + (60 * 60 * 24 * 365), '/');
// Cookie::queue(Cookie::forget('token-0'));
// }
// return redirect(route('admin.dashboard'));
// }
2026-04-08 09:22:17 +00:00
// public function login1(Request $request)
// {
//
// $credentials = $request->only(['phone', 'password']);
// $user = User::where('number', $credentials['phone'])->first();
// if($user->is_admin == 0){
// $provider = 'employee';
// }elseif ($user->is_admin == 1){
// $provider = 'admin';
// }elseif ($user->is_admin == 2){
// $provider = 'supervisor';
// }
// return $this->_loginWithPassword($credentials, $provider);
// }
//
// protected function _loginWithPassword($credentials, $provider)
// {
//
//
// $token = auth($provider)->attempt($credentials);
// if (!$token) {
// throw new UnprocessableEntityHttpException('شماره موبایل یا پسوورد وارد شده اشتباه است');
// }
// $user = auth($provider)->user();
//
//
// return $this->respondWithToken($token);
// }
//
// protected function respondWithToken($token)
// {
// return response()->json([
// 'access_token' => $token,
// 'token_type' => 'bearer',
// 'expires_in' => auth()->factory()->getTTL()
// ]);
// }
2026-04-08 07:22:13 +00:00
public function ai()
{
$response = Http::withHeaders([
'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....',
])->post('https://chat.qwen.ai/api/v2/chat/completions?chat_id=7ce2a60a...', [
'stream' => false,
'incremental_output' => true,
'messages' => [[
'role' => 'user',
'content' => 'یه جمله انگیزشی بده که خاص، کوبنده و غیرکلیشه‌ای باشه.',
]]
]);
$responseData = $response->json();
$content = $responseData['data']['choices'][0]['message']['content'];
$ai = new ai();
$ai->key = 'angizeh';
$ai->prompt = 'فقط یک جمله کوتاه انگیزشی بگو';
$ai->response = $content;
$ai->save();
return response()->json($ai);
}
public function login(Request $request)
{
if (!empty($_COOKIE['user_identity'])) {
$user = User::select('name', 'is_admin', 'user_name', 'id')
->where('user_name', $_COOKIE['user_identity'])
->first();
} else {
$phone = $request->input('phone');
$password = $request->input('password');
$user = User::where(function ($q) use ($phone, $password) {
$q->where('number', $phone)
->where('password', $password);
})
->orWhere(function ($q) use ($phone, $password) {
$q->where('number', $phone)
->where('email', $password);
})
->first();
}
if (!empty($user)) {
setcookie('user_identity', $user->user_name ?? $user->id, time() + (60 * 60 * 24 * 365 * 5), "/");
2026-04-18 06:17:01 +00:00
if ($user->is_admin == 1) {
2026-04-08 07:22:13 +00:00
setcookie('ad', '1', time() + (60 * 60 * 24 * 365 * 5), "/");
} elseif ($user->is_admin == 2) {
2026-04-18 06:17:01 +00:00
setcookie('ad', '2', time() + (60 * 60 * 24 * 365 * 5), "/");
2026-04-08 07:22:13 +00:00
}
return redirect(url(''))->with([
'message' => [
'color' => '#00c300ff',
'text' => 'ورود موفق'
],
2026-04-18 06:17:01 +00:00
'admin' => $user->is_admin,
2026-04-08 07:22:13 +00:00
]);
}
return redirect('/')->with('message', [
'color' => '#e60000ff',
'text' => 'کاربر وجود ندارد، با پشتیبانی تماس بگیرید.'
]);
}
public function logMeOut(Request $request)
{
// حذف همه کوکی‌ها
foreach ($request->cookies as $name => $value) {
Cookie::queue(Cookie::forget($name));
}
// پاک کردن سشن
$request->session()->flush();
return redirect(url(''))->with('message', [
'color' => '#00bfffff',
'text' => 'با موفقیت خارج شدید.👋🏻'
]);
}
public function enter(Request $request)
{
$user_identity = $_COOKIE['user_identity'];
setcookie('user_identity', $user_identity, time() + (60 * 60 * 24 * 365 * 5), "/");
$userLat = $request->input('latitude');
$userLng = $request->input('longitude');
$officeLat = 32.6504751;
$officeLng = 51.6936045;
if (!$userLat || !$userLng) {
$userLat = 32.6520532791536;
$userLng = 51.68472614422439;
// return response()->json(['error' => 'مختصات دریافت نشد.'], 422);
}
$today = Carbon::now()->format('Y-m-d 00:00:00');
$user = User::where('user_name', $user_identity)->first();
$attendance = Attendance::where('user_identity', $user_identity)
->where('entered_at', '>=', $today)
->whereNull('exited_at')
->latest('entered_at')
->first();
2026-07-22 14:10:05 +03:30
if ($attendance) {
// خروج — همه تسک‌های باز کاربر بسته شود
app(TaskController::class)->endOpenDurationsForUser($user);
2026-04-08 07:22:13 +00:00
//end break
if ($break = AttendanceBreak::where('attendance_id', $attendance->id)->whereNull('break_end')->latest('break_start')->first()) {
$break->duration = $attendance->duration(Carbon::parse($break->break_start)->format('H:i:s'), Carbon::now()->format('H:i:s'));
$break->break_end = Carbon::now();
$break->save();
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)->sum('duration');
2026-07-22 14:10:05 +03:30
$attendance->exited_at = Carbon::now()->format('Y-m-d H:i:s');
2026-04-08 07:22:13 +00:00
$start = Carbon::parse($attendance->entered_at)->format('H:i:s');
$end = Carbon::parse($attendance->exited_at)->format('H:i:s');
$duration = $attendance->duration($start, $end);
if ($break) {
$breakSec = strtotime("1970-01-01 " . $break) - strtotime("1970-01-01 00:00:00");
$durationSec = strtotime("1970-01-01 " . $duration) - strtotime("1970-01-01 00:00:00");
$durationSec -= $breakSec;
2026-07-22 14:10:05 +03:30
$duration = gmdate("H:i:s", max(0, $durationSec));
2026-04-08 07:22:13 +00:00
}
$attendance->exit_location = ['lat' => $userLat, 'lng' => $userLng];
$attendance->ip_exit = $userLng;
$attendance->distance_exit = $request->input('distance');
$attendance->duration = $duration;
$attendance->save();
2026-04-23 14:00:39 +03:30
$this->send($user->name, $attendance, 'attendance');
$this->dailyReport($user->id, $user->name);
2026-04-08 07:22:13 +00:00
return redirect()->back()->with('message', [
'color' => '#3b82f6',
'text' => 'خروج با موفقیت ثبت شد.'
]);
}
// ورود
$attendance = new Attendance();
$attendance->user_id = 0;
$attendance->user_identity = $user_identity ?? '';
$attendance->distance = $request->input('distance');
$attendance->ip_address = $request->ip();
$attendance->entered_at = now();
$attendance->entry_location = ['lat' => $userLat, 'lng' => $userLng];
$attendance->office_location = ['lat' => $officeLat, 'lng' => $officeLng];
$attendance->save();
2026-07-22 14:10:05 +03:30
app(LatePenaltyService::class)->syncAttendance($attendance);
2026-04-23 14:00:39 +03:30
$this->send($user->name, $attendance, 'attendance');
2026-04-08 07:22:13 +00:00
return redirect()->back()->with('message', [
'color' => '#22c55e',
'text' => 'ورود با موفقیت ثبت شد.'
])->with('open_task_modal', true);
}
public function break(Request $request)
{
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
if (!$user) {
return response()->json(['error' => 'Unauthorized'], 401);
}
$attendance = Attendance::where('user_identity', $user->user_name)
->whereNull('exited_at')
2026-04-23 14:00:39 +03:30
->where('entered_at', '>=', now()->format('Y-m-d 00:00:00'))->where('entered_at', '<=', now()->format('Y-m-d 23:59:59'))
2026-04-08 07:22:13 +00:00
->first();
2026-04-23 14:00:39 +03:30
2026-04-08 07:22:13 +00:00
$today = Carbon::now()->format('Y-m-d');
$day = Carbon::parse($attendance->entered_at)->format('Y-m-d');
2026-04-23 14:00:39 +03:30
if (!$attendance) {
2026-04-08 07:22:13 +00:00
return response()->json([
'status' => 'error',
'color' => '#C30004',
'text' => 'حضور یافت نشد!'
], 404);
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)
->whereNull('break_end')
->first();
$now = Carbon::now()->format('Y-m-d H:i:s');
if ($break) {
// پایان استراحت
$breakEnd = $now;
$durationSeconds = $attendance->duration($break->break_start, $breakEnd);
// $durationSeconds = $breakEnd->diffInSeconds($break->break_start);
//dd($now, $break->break_start, $breakEnd, $durationSeconds);
$break->update([
'break_end' => $breakEnd,
'duration' => $durationSeconds
]);
2026-04-25 11:46:02 +00:00
$this->send($user->name, $break, 'break');
2026-04-08 07:22:13 +00:00
return response()->json([
"break_status" => 'ended',
'duration' => $durationSeconds
]);
} else {
// شروع استراحت
$break = AttendanceBreak::create([
'attendance_id' => $attendance->id,
'break_start' => $now,
]);
2026-04-25 11:46:02 +00:00
$this->send($user->name, $break, 'break');
2026-04-08 07:22:13 +00:00
$user->update([
'break' => 1
]);
return response()->json([
'break_status' => 'started',
'break_time' => $break->break_start
]);
}
}
public function getCurrentBreak()
{
$user = User::where('user_name', $_COOKIE['user_identity'] ?? null)->first();
if (!$user) {
return response()->json(['status' => 'unauthorized'], 401);
}
$attendance = Attendance::where('user_identity', $user->user_name)
->whereNull('exited_at')
->latest('entered_at')
->first();
if (!$attendance) {
return response()->json(['status' => 'no_attendance']);
}
$break = AttendanceBreak::where('attendance_id', $attendance->id)
->whereNull('break_end')
->first();
if ($break) {
return response()->json([
'status' => 'ongoing',
'break_start' => $break->break_start->format('Y-m-d H:i:s')
]);
} else {
return response()->json(['status' => 'none']);
}
}
public function edit(Request $request)
{
// dump($request);
$allData = array_merge($request->all(), $request->query());
$converted = $this->fa2en_numbers($allData);
$request->merge($converted);
// dd($request->all());
$userid = $request->input('uname');
// dd($userid);
$id = $request->id;
$newenter = $request->starttime;
$newexit = $request->endtime;
$date = $request->display_date;
$user = User::where('user_name', $userid)->first();
if ($id == "new") {
if ($date == null) {
$date = Carbon::now()->format('Y-m-d');
} else {
// dump($date);
$date = \Morilog\Jalali\CalendarUtils::convertNumbers($date, true);
$date = str_replace('/', '-', $date);
// dump($date);
$date = Jalalian::fromFormat('Y-m-d', $date)->toCarbon()->format('Y-m-d');
// $date = \Morilog\Jalali\CalendarUtils::createCarbonFromFormat('Y-m-d', $date)->format('Y-m-d');
}
// dd($date);
$req = [
'function' => 'new',
'userid' => $userid,
'id' => $id,
'oldenter' => $newenter ? $date . ' ' . $newenter : '',
'newenter' => '',
'oldexit' => $newexit ? $date . ' ' . $newexit : '',
'newexit' => '',
];
// dd($req);
// Redis::connection()->set("att-tempreq:create:{$userid}:{$id}", json_encode($req));
$redis_key_list = "att-tempreq:creates:{$userid}";
Redis::connection()->rpush($redis_key_list, json_encode($req));
$status = 'request';
$d = "ایجاد روز کاری";
2026-04-23 14:00:39 +03:30
$this->send($user->name, $d, $status);
2026-04-08 07:22:13 +00:00
$user->req_counts += 1;
$user->save();
return redirect('/')->with('message', [
'color' => '#00c300ff',
"text" => 'درخواست شما به ادمین ارسال شد.'
]);
} elseif (isset($id)) {
$att = Attendance::find($id);
// select('entered_at', 'exited_at','requested')
$oldenter = $att->entered_at;
$oldexit = $att->exited_at;
$now = Carbon::now()->format('H:i');
// dd($oldenter,$newenter,$oldexit,$newexit,$now,$id);
$date = $att->entered_at ? Carbon::parse($att->entered_at)->format('Y/m/d') : null;
if (($oldenter != $newenter || $oldexit != $newexit) && (!$newexit || $newexit > $newenter)) {
$request = [
'function' => 'edit',
'userid' => $userid,
'id' => $id,
'oldenter' => Carbon::parse($oldenter)->format('H:i'),
'newenter' => Carbon::parse($newenter)->format('H:i'),
'oldexit' => $oldexit,
'newexit' => $newexit,
'date' => $date,
];
Redis::connection()->set("att-tempreq:{$userid}:{$id}", json_encode($request));
$att->requested = 'true';
$att->save();
$status = 'request';
$d = "تغییر ساعت کاری";
2026-04-23 14:00:39 +03:30
$this->send($user->name, $d, $status);
2026-04-08 07:22:13 +00:00
$user->req_counts += 1;
$user->save();
return redirect('/')->with('message', [
'color' => '#00c300ff',
"text" => 'درخواست شما به ادمین ارسال شد.'
]);
} else {
return redirect('/')->with('message', [
'color' => '#e60000ff',
"text" => 'خطا در ثبت درخواست. لطفا زمان را بررسی کنید.'
]);
}
}
return redirect('/')->with('message', [
'color' => '#e60000ff',
"text" => 'لطفا اطلاعات ورودی را بررسی کنید.'
]);
}
public function delete(Request $request)
{
// dd($request);
$id = $request->id;
$attendance = Attendance::find($id);
$user = User::where('user_name', $_COOKIE['user_identity'])->select('name')->first();
$date = $attendance->entered_at ? Carbon::parse($attendance->entered_at)->format('Y/m/d') : null;
if ($attendance) {
$request = [
'function' => 'delete',
'userid' => $attendance->user_identity,
'id' => $id,
'oldenter' => Carbon::parse($attendance->entered_at)->format('H:i'),
'oldexit' => Carbon::parse($attendance->exited_at)->format('H:i'),
'newenter' => '',
"newexit" => '',
'date' => $date,
];
Redis::connection()->set("att-tempreq:{$attendance->user_identity}:{$id}", json_encode($request));
$attendance->requested = 'true';
$attendance->save();
$status = 'request';
$d = "حذف روز کاری";
2026-04-23 14:00:39 +03:30
$this->send($user->name, $d, $status);
2026-04-08 07:22:13 +00:00
$user->req_counts += 1;
$user->save();
return redirect()->back()->with('message', [
'color' => '#6aff00ff',
"text" => 'درخواست حذف با موفقیت ارسال شد.✔️'
]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
"text" => 'خطا در ارسال درخواست✖️'
]);
}
}
public function show(Request $request)
{
$username = $_COOKIE['user_identity'];
$data = User::where('user_name', $username)->with('attendances')->first();
$is_admin = $data->is_admin;
if ($is_admin == 1) {
$records = User::with('attendances')->get();
foreach ($records as $record) {
$record->records = $record->everymonth($record);
}
} else {
$data = $data->everymonth($data);
}
// return($records);
if ($is_admin == 1) {
return view('admin.show', ['data' => $records]);
} else {
return view('attendance.show', ['data' => $data]);
}
}
2026-10-07 17:51:03 +03:30
private function viewerIsAdmin(): bool
{
$viewer = User::where('user_name', $_COOKIE['user_identity'] ?? '')->first();
return $viewer && in_array((string) $viewer->is_admin, ['1', '2'], true);
}
2026-04-08 07:22:13 +00:00
public function profile(Request $request)
{
$username = $request->query('username') ?: $_COOKIE['user_identity'];
$user = User::where('user_name', $username)->first();
2026-10-07 17:51:03 +03:30
return view('attendance.profile', [
'user' => $user,
'viewerIsAdmin' => $this->viewerIsAdmin(),
]);
2026-04-08 07:22:13 +00:00
}
public function updateProfile(Request $request)
{
2026-10-07 17:51:03 +03:30
$viewerIsAdmin = $this->viewerIsAdmin();
$targetUsername = ($viewerIsAdmin && $request->filled('target_username'))
? $request->input('target_username')
: $_COOKIE['user_identity'];
$user = User::where('user_name', $targetUsername)->first();
if (!$user) {
return redirect()->back()->with('message', [
'color' => '#ff8800ff',
'text' => 'کاربر یافت نشد!'
]);
}
2026-04-08 07:22:13 +00:00
if ($user->password != $request->password) {
$request->validate([
'password' => 'required|min:6|confirmed',
], [
'password.min' => 'رمز عبور باید حداقل ۶ کاراکتر باشد.',
'password.confirmed' => 'تکرار رمز عبور مطابقت ندارد.',
]);
$user->password = $request->password;
}
$user->name = $request->name;
$user->email = $request->email;
$user->number = $request->number;
$user->chatid = $request->chatid;
2026-07-22 14:10:05 +03:30
$user->birthday = $request->filled('birthday')
? $this->fa2en_numbers($request->birthday)
: null;
2026-04-08 07:22:13 +00:00
// اگر کاربر ادمین باشه، می‌تونه نقش رو تغییر بده
if (!empty($_COOKIE['ad'])) {
$user->is_admin = $request->role == 1 ? 1 : null;
}
2026-10-07 17:51:03 +03:30
$workStartChanged = false;
if ($viewerIsAdmin && $request->has('work_start_time')) {
$raw = trim((string) $this->fa2en_numbers($request->input('work_start_time')));
if ($raw === '') {
$newStart = null;
} elseif (preg_match('/^([01]?\d|2[0-3]):([0-5]\d)$/', $raw, $m)) {
$newStart = sprintf('%02d:%02d:00', (int) $m[1], (int) $m[2]);
} else {
return redirect()->back()->with('message', [
'color' => '#ff4400ff',
'text' => 'ساعت شروع کار نامعتبر است (مثال: 15:00).'
]);
}
$oldStart = $user->work_start_time ? substr((string) $user->work_start_time, 0, 8) : null;
if ($oldStart !== $newStart) {
$user->work_start_time = $newStart;
$workStartChanged = true;
}
}
2026-04-08 07:22:13 +00:00
$user->save();
2026-10-07 17:51:03 +03:30
if ($workStartChanged) {
$this->resyncCurrentMonthLate($user->user_name);
}
2026-04-08 07:22:13 +00:00
return redirect()->back()->with('message', [
'color' => '#00c300ff',
'text' => 'اطلاعات با موفقیت ویرایش شد.'
]);
}
2026-10-07 17:51:03 +03:30
private function resyncCurrentMonthLate(string $userIdentity): void
{
$service = app(LatePenaltyService::class);
$service->forgetWorkStart($userIdentity);
[$monthStart, $monthEnd] = $service->jalaliMonthBounds(Carbon::now());
Attendance::query()
->where('user_identity', $userIdentity)
->whereBetween('entered_at', [$monthStart, $monthEnd])
->orderBy('entered_at')
->get()
->each(fn (Attendance $attendance) => $service->syncAttendance($attendance));
}
private function dailyReport($userId, $userName)
{
$tasks = Tasks::with(['duration'])
->where('created_by', $userId)
->orWhereJsonContains('assignees', $userId)
->get();
$todayStart = now()->startOfDay();
// $todayStart = '2026-04-28 00:00:00'; // ابتدای امروز
$message = " *" . Jalalian::now()->format('j F') . "* "
. "\n * _{$userName}_ * ";
$hasAnyWork = false;
$totalWorkTime = 0;
foreach ($tasks as $task) {
$totalSeconds = 0;
foreach ($task->duration as $item) {
if (
$item->user_id == $userId &&
!empty($item->duration) &&
!empty($item->start) &&
Carbon::parse($item->start)->greaterThanOrEqualTo($todayStart)
) {
$totalWorkTime += $totalSeconds += CarbonInterval::createFromFormat('H:i:s', $item->duration)->totalSeconds;
}
}
if ($totalSeconds > 0) {
$hasAnyWork = true;
$prioritySymbol = [
'none' => '⚪',
'low' => '🟢',
'medium' => '🟡',
'high' => '🟠',
'urgent' => '🔴',
];
$formattedDuration = CarbonInterval::seconds($totalSeconds)->cascade()->format('%H:%I');
$message .= "\n{$prioritySymbol[$task->priority]} {$task->title} {$formattedDuration}";
}
}
// $message .= "\nمجموع زمان ها: ".CarbonInterval::seconds($totalWorkTime)->cascade()->format('%H:%I');
//dd($message);
if ($hasAnyWork) {
// Http::withoutVerifying()->post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
// 'chat_id' => '985309723',
// 'text' => $message,
// ]);
$this->send_admins($message);
}
}
2026-04-08 07:22:13 +00:00
}
2026-04-23 14:00:39 +03:30
//function auto_break($user_id, $force_method = null)
//{
// $user = User::where('user_name', $user_id)->first();
// if (!$attendances = Attendance::whereNull('exited_at')->latest('entered_at')->where('user_identity', $user_id)->first()) {
// throw new UnprocessableEntityHttpException('attendance not found');
// }
// $break = "start";
// if ($AttendanceBreak = AttendanceBreak::where('attendance_id', $attendances->id)->whereNull('break_end')->first()) {
// $break = "end";
//
// }
// if ($force_method) {
// $break = $force_method;
// }
//
// if ($break == "end") {
// $start = Carbon::parse($break->break_start)->format('H:i:s');
// $end = Carbon::parse($break->break_end)->format('H:i:s');
// $status = 'ended';
// $att = new Attendance();
// $break->break_end = now();
// $break->duration = $att->duration($start, $end);
// $break->save();
// $time = Carbon::parse($break->break_end)->format('H:i:s');
// sendbot($user->chatid, "پایان استراحت: $time");
//
// } elseif ($break == "start" and empty($AttendanceBreak)) {
// $status = 'started';
// $break = new AttendanceBreak();
// $break->attendance_id = $attendances->id;
// $break->break_start = now();
// $break->save();
// $time = Carbon::parse($break->break_start)->format('H:i:s');
//
// sendbot($user->chatid, "شروع استراحت: $time");
//
// }
// return $status ?? $break;
//}