2026-04-08 07:22:13 +00:00
|
|
|
|
<?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'));
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
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), "/");
|
2026-04-18 06:17:01 +00:00
|
|
|
|
}elseif ($user->is_admin == 2){
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
|
|
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} ثبت کرد.";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-18 06:17:01 +00:00
|
|
|
|
$admins = User::whereIn('is_admin', [1,2])->whereNotNull('chatid')->select('chatid', 'bale', 'user_name')->get();
|
2026-04-08 07:22:13 +00:00
|
|
|
|
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;
|
|
|
|
|
|
}
|