Files
a.montask/app/Http/Controllers/AttendanceController.php
T
2026-04-08 07:22:13 +00:00

721 lines
26 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers;
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\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;
class AttendanceController extends Controller
{
public function index()
{
if (isset($_COOKIE['user_identity'])) {
$Attendance = isset($_COOKIE['user_identity'])
? ($_COOKIE['user_identity'] == 1370
? Attendance::all()
: Attendance::where('user_identity', $_COOKIE['user_identity'])->get())
: collect();
$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();
$ids = array_merge($ids, [$s->id]);
Cookie::queue('seen_angizeh_ids', json_encode($ids), 14400);
//total time
$now = Jalalian::fromCarbon(Carbon::now());
$tsec = 0;
//dd(->user_profile);
if (isset($_COOKIE['token01'])) {
$a = json_decode($_COOKIE['token01']);
$user = User::where('user_name', $a->user_profile)->with('attendances')->first();
} else {
$user = isset($_COOKIE['user_identity']) ? User::where('user_name', $_COOKIE['user_identity'])->with('attendances')->first() : null;
}
//dd($user);
if (!empty($user->attendances)) {
foreach ($user->attendances as $att) {
$date = $att->entered_at != null ? Jalalian::fromCarbon(Carbon::parse($att->entered_at)) : null;
$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/';
$now = Carbon::now()->format('Y-m-d 00:00:00');
$existed = $Attendance->whereNull('exited_at')->where('entered_at', '>=', $now)->first();
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
$until_now = null;
if ($user->break == 1) {
$att = Attendance::whereNull('exited_at')->latest('entered_at')->first();
$break = AttendanceBreak::where('attendance_id', $att->id)
->whereNull('break_end')
->latest('break_start')
->first();
if ($break)
$until_now = (int)Carbon::parse($break->break_start)->diffInSeconds(now(), false);
// $until_now = Carbon::now()->diffInSeconds(Carbon::parse($break->break_start));
}
// dd($until_now);
return view('attendance.index', compact('user'))->with([
's' => $s,
'existed' => $existed,
'formaction' => $formaction,
'breakDu' => $until_now ?? null,
]);
} 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'));
// }
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), "/");
$admin = $user->is_admin == 1 ? true : false;
if ($admin) {
setcookie('ad', '1', time() + (60 * 60 * 24 * 365 * 5), "/");
}
return redirect(url(''))->with([
'message' => [
'color' => '#00c300ff',
'text' => 'ورود موفق'
],
'admin' => $admin,
]);
}
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();
if ($attendance) {
// خروج
//end task
if (!empty($user->active_task)) {
$task = Tasks::where('name', $user->active_task)->first();
if ($p_task = Pivot_Tasks::where('user_id', $user->plain_id)->where('task_id', $task->task_id)->whereNull('ended_at')->latest('started_at')->first()) {
$p_task->duration = $attendance->duration(Carbon::parse($p_task->started_at)->format('H:i:s'), Carbon::now()->format('H:i:s'));
$p_task->ended_at = Carbon::now();
$p_task->save();
}
$user->active_task = null;
$user->save();
}
//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');
$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;
$duration = gmdate("H:i:s", $durationSec);
}
$attendance->exited_at = Carbon::now()->format('Y-m-d H:i:s');
$attendance->exit_location = ['lat' => $userLat, 'lng' => $userLng];
$attendance->ip_exit = $userLng;
$attendance->distance_exit = $request->input('distance');
$attendance->duration = $duration;
$attendance->save();
send_tel($user->name, $attendance, 'attendance');
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();
send_tel($user->name, $attendance, 'attendance');
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')
->latest('entered_at')
->first();
$today = Carbon::now()->format('Y-m-d');
$day = Carbon::parse($attendance->entered_at)->format('Y-m-d');
if ($today !== $day || !$attendance) {
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
]);
dd(send_tel($user->name, $break, 'break'));
return response()->json([
"break_status" => 'ended',
'duration' => $durationSeconds
]);
} else {
// شروع استراحت
$break = AttendanceBreak::create([
'attendance_id' => $attendance->id,
'break_start' => $now,
]);
dd(send_tel($user->name, $break, 'break'));
$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 = "ایجاد روز کاری";
send_tel($user->name, $d, $status);
$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 = "تغییر ساعت کاری";
send_tel($user->name, $d, $status);
$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 = "حذف روز کاری";
send_tel($user->name, $d, $status);
$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]);
}
}
public function profile(Request $request)
{
$username = $request->query('username') ?: $_COOKIE['user_identity'];
$user = User::where('user_name', $username)->first();
return view('attendance.profile', ['user' => $user]);
}
public function updateProfile(Request $request)
{
// dd($request->all());
$user = User::where('user_name', $_COOKIE['user_identity'])->first();
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;
// اگر کاربر ادمین باشه، می‌تونه نقش رو تغییر بده
if (!empty($_COOKIE['ad'])) {
$user->is_admin = $request->role == 1 ? 1 : null;
}
$user->save();
return redirect()->back()->with('message', [
'color' => '#00c300ff',
'text' => 'اطلاعات با موفقیت ویرایش شد.'
]);
}
private function fa2en_numbers($input)
{
if (is_string($input)) {
$fa_numbers = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
$en_numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
return str_replace($fa_numbers, $en_numbers, $input);
} elseif (is_array($input)) {
return array_map([$this, __FUNCTION__], $input);
} else {
return $input;
}
}
}
function send_tel($user, $data, $status)
{
if ($status == 'attendance') {
// dd('hi');
$enter = Carbon::parse($data->entered_at)->format('H:i');
$date = Jalalian::fromCarbon(Carbon::parse($data->entered_at))->format('Y/m/d');
$exit = $data->exited_at ? Carbon::parse($data->exited_at)->format('H:i') : null;
// $user = json_decode($user);
$message = "تاریخ: {$date}\n {$user} در ساعت ";
if (!$exit) {
$message .= "{$enter} وارد شد.";
} else {
$message .= "{$exit} خارج شد.";
}
}
if ($status == 'break') {
$date = Jalalian::fromCarbon(Carbon::parse($data->break_start))->format('Y/m/d');
$start = Carbon::parse($data->break_start)->format('H:i');
$end = Carbon::parse($data->break_end)->format('H:i');
if (!$data->break_end)
$message = "تاریخ: {$date}\n {$user} در ساعت {$start} شروع به استراحت کرد.";
else
$message = "تاریخ: {$date}\n {$user} در ساعت {$end} به استراحت پایان داد.";
}
if ($status == 'request') {
$message = "{$user} درخواست {$data} ثبت کرد.";
}
$admins = User::where('is_admin', '1')->whereNotNull('chatid')->select('chatid', 'bale', 'user_name')->get();
if ($_COOKIE['user_identity'] !== 'test') {
foreach ($admins as $admin) {
if (!$admin->bale) {continue;}
// dd($admin->chatid);
// Http::get("https://api.wwwapp.ir/telegran_send.php", [
// 'botToken' => "7467099619:AAF2V6yYcbAb8oSIRSCyH5i2GKfdWVO3a7k",
// 'chatId' => $admin->chatid,
// 'message' => $message,
// ]);
if ($admin->bale) {
try {
$response = Http::post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
"chat_id" => $admin->bale,
'text' => $message,
]);
}catch (\Exception $e){}
}
Log::create([
'error' => $response->body(),
'user' => "کاربر: $user
ادمین: {$admin->user_name}",
]);
}
}else{
try {
$response = Http::post('https://tapi.bale.ai/1482838710:sYbLzby0tuLRzHvP4d3LsbcNwg2sjSDLTAU/sendMessage', [
"chat_id" => '985309723',
'text' => $message,
]);
}catch (\Exception $e){}
}
// return $message;
}
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;
}